Проблема здесь в том, что вы хотите проверить наличие ключа в двух (других) таблицах и не можете принудительно применить его, используя ограничения внешнего ключа для одного столбца. Postgres позволяет создавать CHECK
выражения для пользовательских проверок, но, как указано в , в руководстве сказано: :
PostgreSQL не поддерживает ограничения CHECK, которые ссылаются на данные таблицы, отличные от новых или обновленныхстрока проверяется. (...) Если возможно, используйте ограничения UNIQUE, EXCLUDE или FOREIGN KEY, чтобы выразить ограничения между строками и таблицами.
Если вам требуется однократная проверка других строк при вставке строквместо непрерывно поддерживаемой гарантии согласованности можно использовать пользовательский триггер.
См. этот очень связанный вопрос для различных решений.
Некоторые базы данных (MS SQL Server) позволяют использовать функцию в CHECK
выражениях . Это было бы оптимально, но Postgres не допускает этот синтаксис.
Для PostgreSQL вам нужно создать TRIGGER
, который будет выполняться, когда что-то будет вставлено в items_for_sale
. Что, с другой стороны, разрешает разрешать функции или проверки между таблицами.
Это будет выглядеть примерно так:
CREATE TRIGGER check_serial_present
BEFORE INSERT ON items_for_sale
FOR EACH ROW
EXECUTE FUNCTION assert_presence_of_serial(); -- implement this function
В другом связанном вопросе также упоминаетсядовольно элегантный способ достижения этого без триггеров:
Чистое решение без триггеров: добавьте лишние столбцы и включите их в ограничения FOREIGN KEY
Мне это очень нравится, так какконцептуально очень просто и легко понять. Я думаю, это будет просто включать следующие шаги:
ALTER TABLE
, чтобы добавить две строки: toy_car_serial
и toy_trains_serial
, оба NULLABLE, но с FOREIGN KEY
ограничениями наупомянутые таблицы. - Убедитесь, что любой
INSERT
вставит серийный номер в serial_no
и toy_car_serial
ИЛИ serial_no
и toy_car_serial
. - Добавить
CHECK( toy_car_serial = serial_no OR toy_trains_serial = serial_no)
.
Я думаю, что два избыточных ряда и небольшая модификация ваших вставок гораздо менее сложны, чем альтернатива.