Сценарий
Представьте себе сервер чата с беседами C
и несколькими сообщениями P
в каждой беседе.Пользователь может ответить на сообщение.Эти данные должны храниться как reply := (original_post_id, replyer_post_id)
.
. Чтобы имитировать это, у меня есть таблицы P
(сообщения) и R
(ответы):
CREATE TABLE P (
id BIGINT NOT NULL,
-- more data ...
)
CREATE TABLE R (
orig_id BIGINT NOT NULL,
repl_id BIGINT NOT NULL,
FOREIGN KEY orig_id REFERENCES P(id),
FOREIGN KEY repl_id REFERENCES P(id),
)
Проблема
Если я хочу автоматически удалить все связанные R
записи при удалении внутри P
, я бы изменил две последние строки определения R
на:
...
FOREIGN KEY orig_id REFERENCES P(id) ON DELETE CASCADE,
FOREIGN KEY repl_id REFERENCES P(id) ON DELETE CASCADE,
)
Однако я получаю следующую ошибку:
Введение ограничения FOREIGN KEY
[...] в таблицу [...] может привести к циклам или нескольким каскадным путям.Укажите ON DELETE NO ACTION
или ON UPDATE NO ACTION
или измените другие ограничения FOREIGN KEY
.
Вопрос
Почему именно я получаю эту ошибку?Технически это не цикл, поскольку ни R.orig_id
, ни R.repl_id
не ссылаются ни на какую другую таблицу (таким образом, возможно, создавая цикл).Кроме того, я не могу понять, почему несколько каскадных путей должны вызывать проблемы, поскольку процедура удаления будет выглядеть следующим образом:
- Удалить запись из
P
с помощью P.id = 1234
- Удалить любая запись из
R
с R.repl_id = 1234
или R.orig_id = 1234
Должен ли я каким-либо образом ограничивать столбцы R.repl_id
и R.orig_id
, чтобы они не былиравно