Ответ 1
Разница возникает только при определении ограничения как DEFERRABLE
с помощью режима INITIALLY DEFERRED
или INITIALLY IMMEDIATE
.
См. SET CONSTRAINTS
.
RESTRICT предотвращает удаление ссылочной строки. NO ACTION означает, что если какие-либо ссылочные строки все еще существуют, когда проверяются ограничения, возникает ошибка; это поведение по умолчанию, если вы ничего не указали. (Существенное различие между этими двумя вариантами состоит в том, что NO ACTION позволяет проверке быть отложенной до более поздней транзакции, тогда как RESTRICT не делает.)
Позволяет проверить его. Создайте родительскую и дочернюю таблицу:
CREATE TABLE parent (
id serial not null,
CONSTRAINT parent_pkey PRIMARY KEY (id)
);
CREATE TABLE child (
id serial not null,
parent_id serial not null,
CONSTRAINT child_pkey PRIMARY KEY (id),
CONSTRAINT parent_fk FOREIGN KEY (parent_id)
REFERENCES parent (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
);
Заполните некоторые данные:
insert into parent values(1);
insert into child values(5, 1);
И проверка действительно проверена:
BEGIN;
delete from parent where id = 1; -- violates foreign key constraint, execution fails
delete from child where parent_id = 1;
COMMIT;
После первого удаления целостность была нарушена, но после второго она будет восстановлена. Однако при первом удалении выполнение выполняется.
То же самое для обновления:
BEGIN;
update parent set id = 2 where id = 1; -- same as above
update child set parent_id = 2 where parent_id = 1;
COMMIT;
В случае удаления я могу сменить операторы, чтобы он работал, но в случае обновлений я просто не могу их сделать (это можно выполнить, удалив обе строки и вставив новые версии).
Многие базы данных не имеют никакого значения между RESTRICT и NO ACTION, в то время как postgres делает вид, что делает иначе. Действительно ли это (правда)?
Разница возникает только при определении ограничения как DEFERRABLE
с помощью режима INITIALLY DEFERRED
или INITIALLY IMMEDIATE
.
См. SET CONSTRAINTS
.