Использование нескольких внешних ключей в одном столбце в SQL Server
10
SQL Server позволяет мне создавать несколько внешних ключей в столбце, и каждый раз, используя только другое имя, я могу создать другой ключ, ссылающийся на один и тот же объект. В основном все ключи определяют одинаковые отношения. Я хочу знать, в чем польза наличия нескольких внешних ключей, определенных в одном столбце, и ссылки на один и тот же столбец в другой таблице. В чем преимущество того, что SQL Server позволяет нам делать такие вещи?
Нет необходимости иметь избыточные ограничения, которые различаются только по имени. Точно так же нет необходимости иметь избыточные индексы, которые отличаются только по имени. Оба добавляют накладные расходы без значения.
Ядро базы данных SQL Server не мешает вам сделать это. Хорошие соглашения об именах (например, FK_ReferencingTable_ReferencedTable) могут помочь защитить человека от таких ошибок.
Вы даже можете создать внешний ключ для столбца, ссылающегося на себя - несмотря на тот факт, что это никогда не может быть нарушено, поскольку каждая строка будет соответствовать ограничению самой себя.
Один крайний случай, когда возможность создания двух внешних ключей в одной и той же взаимосвязи была бы потенциально полезна, заключается в том, что индекс, используемый для проверки внешних ключей, определяется во время создания. Если более лучший (то есть более узкий) индекс появится позже, то это позволит создать новое ограничение внешнего ключа, связанное с лучшим индексом, а затем исходное ограничение будет удалено без пропуска без активного ограничения.
(Как в примере ниже)
CREATETABLE T1(
T1_Id INT PRIMARYKEYCLUSTEREDNOTNULL,
Filler CHAR(4000)NULL,)INSERTINTO T1 VALUES(1,'');CREATETABLE T2(
T2_Id INT IDENTITY(1,1)PRIMARYKEYNOTNULL,
T1_Id INT NOTNULLCONSTRAINT FK REFERENCES T1 (T1_Id),
Filler CHAR(4000)NULL,)ALTERTABLE T1 ADDCONSTRAINT
UQ_T1 UNIQUENONCLUSTERED(T1_Id)/*Execution Plan uses clustered index*/INSERTINTO T2 VALUES(1,1)ALTERTABLE T2 WITHCHECKADDCONSTRAINT FK2 FOREIGNKEY(T1_Id)REFERENCES T1 (T1_Id)ALTERTABLE T2 DROPCONSTRAINT FK/*Now Execution Plan now uses non clustered index*/INSERTINTO T2 VALUES(1,1)DROPTABLE T2, T1;
В дополнение к промежуточному периоду, пока существуют оба ограничения, любые вставки заканчиваются проверкой по обоим индексам.
Может ли транзакция использоваться для обеспечения того же обновления без пропусков? Возможно, этот нетранзакционный метод лучше благодаря меньшей блокировке?
Бинки
13
Не имеет смысла иметь одинаковые ограничения внешнего ключа. То есть для тех же столбцов и ссылки на одну и ту же таблицу и столбцы.
-Не согласен. Может быть шанс, что основной таблице понадобятся две отдельные проверки. Ниже приведен пример того, как отправитель и получатель абсолютно разные - stackoverflow.com/questions/40400483/…
trex
@trex, ты говоришь о чем-то другом. Вопрос здесь гласит: «Я хочу знать, в чем польза наличия нескольких внешних ключей, которые определены в одном столбце и ссылаются на один и тот же столбец в другой таблице ».
ypercubeᵀᴹ
@ ypercubeᵀᴹ - Понял. Спасибо за разъяснение
trex
6
По той же причине, по которой вы можете создать 50 индексов в одном столбце, добавить второй файл журнала, установить максимальный объем памяти сервера в 20 МБ ... большинство людей не будут делать такие вещи, но иногда могут быть законные причины делать это, так что нет выгода в создании накладных расходов в двигателе, чтобы добавить проверки против вещей, которые просто опрометчивы.
Когда вы начинаете переключаться с синего на зеленый, вам нужно временно создавать дополнительные копии вещей.
Мы хотим временно создать дополнительный внешний ключ CHECK WITH NOCHECKи ON UPDATE CASCADE ON DELETE SET NULL; то, что это делает, - это рабочий внешний ключ, но существующие строки не проверяются при создании ключа.
Позже после очистки всех строк, которые должны совпадать, мы создадим новый внешний ключ без каких-либо параметров команды (по умолчанию CHECK WITH CHECKэто то, что вы обычно хотите) и удалите временный внешний ключ.
Обратите внимание, что если вы просто сбросите и заново создадите внешний ключ, некоторые строки мусора могут проскользнуть мимо вас.
Не имеет смысла иметь одинаковые ограничения внешнего ключа. То есть для тех же столбцов и ссылки на одну и ту же таблицу и столбцы.
Это как иметь один и тот же чек 2 или более раз.
источник
По той же причине, по которой вы можете создать 50 индексов в одном столбце, добавить второй файл журнала, установить максимальный объем памяти сервера в 20 МБ ... большинство людей не будут делать такие вещи, но иногда могут быть законные причины делать это, так что нет выгода в создании накладных расходов в двигателе, чтобы добавить проверки против вещей, которые просто опрометчивы.
источник
Походит на сине-зеленую вещь.
Когда вы начинаете переключаться с синего на зеленый, вам нужно временно создавать дополнительные копии вещей.
Мы хотим временно создать дополнительный внешний ключ
CHECK WITH NOCHECK
иON UPDATE CASCADE ON DELETE SET NULL
; то, что это делает, - это рабочий внешний ключ, но существующие строки не проверяются при создании ключа.Позже после очистки всех строк, которые должны совпадать, мы создадим новый внешний ключ без каких-либо параметров команды (по умолчанию
CHECK WITH CHECK
это то, что вы обычно хотите) и удалите временный внешний ключ.Обратите внимание, что если вы просто сбросите и заново создадите внешний ключ, некоторые строки мусора могут проскользнуть мимо вас.
источник