PostgreSQL: как ограничить существование внешнего ключа? - PullRequest
2 голосов
/ 19 октября 2010

В PostgreSQL, какой самый простой способ применить больше, чем просто существование внешнего ключа?

Например, с учетом следующих таблиц:

create table "bar"
    (
    bar_id serial primary key,
    status boolean not null
    )

create table "foo"
    (
    foo_id serial primary key,
    bar_id integer references "bar"
    )

Как можно ограничить foo.bar_id только строками bar, где status - это истина?

Я могу представить, как это сделать с помощью функций триггера, но мне кажется, что мне нужно несколько (insert, update на foo; update, delete на bar), поэтому я Хотелось бы узнать, есть ли более удобный метод, возможно, просто использующий ограничения.

Ответы [ 4 ]

1 голос
/ 19 октября 2010

Это одна из многих ситуаций, в которых стандартная реляционная целостность SQL не соответствует требованиям реального мира.Я хотел бы, например, чтобы можно было создать внешний ключ для index , а не для целого столбца;Postgresql предлагает частичные индексы, и это решило бы вашу проблему.

В противном случае вам придется разделить bar на две таблицы bar_true и bar_false, каждая без поля состояния.Установите свой FK против bar_true.Затем вы можете создать представление UNIONing bar_true и bar_false вместе, чтобы получить полный набор тактов (хотя вам придется позаботиться о первичных ключах).

1 голос
/ 20 октября 2010

Вы можете сделать bar.status частью первичного ключа таблицы баров.Затем вы помещаете статус в таблицу foo как часть FK для запрета.Также поместите ограничение, что foo.status должен быть равен true.Это своего рода хак, но в зависимости от контекста реального мира это может иметь смысл.

1 голос
/ 19 октября 2010

Хардкорным способом было бы иметь промежуточную таблицу / таблицу подкатегорий, расположенную между foo и bar, содержащую значения бара, статус которого равен true.Внешний ключ на foo будет указывать на промежуточную таблицу, но он потребует ведения с обеих сторон в случае добавления значений бара или изменения состояния на false ...

Альтернативой является использование триггера,потому что внешний ключ не имеет средств фильтрации.

PostgreSQL не имеет материализованных представлений;Я не уверен, что это позволит вам указать ссылку на внешний ключ для представления, но это будет означать проблему в случае, если статус бара изменится на false ...

0 голосов
/ 20 октября 2010

Похоже, что если вы использовали триггеры, вы могли контролировать только пропуск записей в foo, которые имеют статус бара true, и вы могли бы также поставить триггер на бар, который, если статус стал ложным, удалил бы запись в foo.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...