для одной и той же библиотеки?
Не знаю, твою стркутуру надо смотреть. Но этот триггер условно работающий, у него будут гонки при срабатывании, две идеально одновременные вставки одного и того же студента тут пройдут.
Идея такова, что есть таблица пользователь-библиотека(fk- пользователя, fk-библиотеки). Ограничение заключается в том, что пользователи с ролью учитель, могут иметь отношение с библиотекой многие ко многим, а вот пользователи с ролью студент не могут, им доступно только один ко многим(тойсть один студент может иметь несколько библиотек)
Можете создать частичный уникальный индекс, туда попадут только записи по вашему условию и для них будет требоваться уникальность
А Вы его хотя бы по шагам проверили (у нас-то DDL этих таблиц нет)? И да, в дополнение к https://t.me/pgsql/509304 — constraints не нужно проверять в before-триггерах, т.к. это в принципе ненадёжно.
А там нужный признак в другой таблице... кажется (\d нам пока не показали).
Прошу прощение, просто только учусь работать с БД. Вот таблицы: create table university_user ( id bigserial primary key, first_name varchar(64) not null, last_name varchar(64) not null, user_role varchar(64) not null ); create table library ( id bigserial primary key, title varchar(64) not null ); create table user_library ( user_id bigint, library_id bigint, foreign key (library_id) references library (id) on delete cascade on update cascade, foreign key (user_id) references university_user (id) on delete cascade on update cascade );
Т.е., у вас связь студента с библиотекой не многие-ко-многим, а 0..1 ко многим? Может тогда поменять связи?
Просто у меня одинаковые атрибуты у пользователей и это причина, почему я так создал связь. Не хочу создавать лишние таблицы. Но если Вы можете дать совет, как решить такую проблему и есть ли смысл создавать несколько одинаковых по структуре таблиц
Ну и УМВР (для некоторого значения понятия "работает" ;) ): NOTICE: Attempting to insert user_id: 2, library_id: 2 ERROR: Cannot add more than one student to a library CONTEXT: PL/pgSQL function prevent_multiple_students_in_one_library() line 9 at RAISE Кстати, почему у Вас нет PK в user_library (это грубая ошибка проектирования, если что)?
Во-первых, user_role должен быть не строкой, а нужна отдельная траблица-справочник, на которую таблица пользователей должна ссылаться. В вашем случае (я так понимаю, у вас в библиотеке может быть только один студент), можно сделать ссылку из библиотеки на студента, а связь многие-ко-многим использовать только для других ролей. Правда, появляется другая проблема - вы можете сослаться на не-студента. Решить это на уровне констрейнтов возможно, но решение несколько странное: https://stackoverflow.com/questions/68025556/postgres-how-can-i-create-an-fk-reference-on-a-partial-index
Спасибо большое!
вот зачемм ттакое в бд?)
Это "решение" — нарушение 2NF (ну и даже с т.з. здравого смысла const_neg_one int generated always as (-1) stored, — это дурь, нет?). ;( Лучше уж сразу "наследование" реализовывать (т.е. roles → students), мне кажется (тут это как раз имеет смысл). Тоже не без недостатков, но они, хотя бы, технические.
Я и пишу, очень странное решение (к тому же, в примере автора там можно было обойтись одним generated полем)
роли чем нарушают 2nf?
не роли, а странное решение со "ссылкой на частичный индекс"
Я про association из https://stackoverflow.com/a/68025696 , неужели непонятно? Или Вы ещё где-то увидели const_neg_one int generated always as (-1) stored,?
Знаете что... я вот перечитал это описание, и уже не уверен, что Вам на самом деле нужно. :( Вы можете примеры привести (того, как может быть, и того, как обязано не быть)?
Обсуждают сегодня