Практическое правило, при создании внешних ключей всегда делайте одно или обнуляемое, или опускайте одно определение внешнего ключа.
Это позволяет прерывать цикл.
Простейший случай (синтаксис SQL, но принцип sampe)применяется):
CREATE TABLE Employee (
EmployeeId INTEGER NOT NULL IDENTITY(1,1)
ManagerId INTEGER NOT NULL
--...
PRIMARY KEY EmployeeId NONCLUSTERED
FOREIGN KEY FK_Manager REFRENCES Employee(EmployeeId)
)
Может быть разорван цикл следующим образом:
CREATE TABLE Employee (
EmployeeId INTEGER NOT NULL IDENTITY(1,1)
ManagerId INTEGER NOT NULL
--...
PRIMARY KEY EmployeeId NONCLUSTERED
)
или следующим образом:
CREATE TABLE Employee (
EmployeeId INTEGER NOT NULL IDENTITY(1,1)
ManagerId INTEGER NULL
--...
PRIMARY KEY EmployeeId NONCLUSTERED
FOREIGN KEY FK_Manager REFRENCES Employee(EmployeeId)
)
Я предпочитаю, когда объявляю внешние ключи,всегда отслеживать схему и следить за тем, чтобы не было циклов.Я опущу наименее опасные ключи, пока все циклы не будут нарушены.Это гарантирует, что все таблицы могут быть массово экспортированы, а затем массово импортированы в другую базу данных.
РЕДАКТИРОВАТЬ: я обнаружил, что, когда вы задаете вопрос эксперту по книге, вы получаете ответ, например отключение внешнего ключа во время удаления.Это неправильно по двум причинам.Во-первых, обычные транзакционные операции не должны изменять определения схемы.Во-вторых, остальная часть кода ожидает присутствия внешнего ключа и поэтому не обрабатывает его в коде приложения;однако модификации схемы имеют неприятную привычку перетекать через транзакции или блокировать целые таблицы.