Внешний ключ в SQL Server - PullRequest
       15

Внешний ключ в SQL Server

2 голосов
/ 07 апреля 2011

Я хочу знать, как использовать внешний ключ в SQL Server, поскольку у меня была дискуссия с одним из моих коллег.

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

Скажем, например, у меня есть две таблицы, Table1 и Table2. В Table1 есть одна запись с id = 1, а в Table2 - две записи с id = 1. Table2 является дочерней таблицей и связана с Table1 через внешний ключ. Теперь, когда я пытаюсь удалить запись id = 1 из таблицы Table1, одновременно нужно удалить id = 1 (2 записи) из таблицы Table2.

Он говорит, что это неправильно. В случае внешнего ключа я должен отдельно удалить записи из обеих таблиц.

Кто прав?

Ответы [ 6 ]

3 голосов
/ 07 апреля 2011

Оба ответа могут использоваться и могут работать.

Версия вашего коллеги повышает ответственность вашего приложения (или вашего администратора баз данных) при удалении: приложение (или администратор баз данных) сначала должно будет проверить наличие дочерних строк.и удалите их, а затем удалите родительскую строку.Это работает и не преподносит вам неожиданных сюрпризов.

Если вы добавите параметр ON DELETE CASCADE в ограничение внешнего ключа (что должно быть возможно практически в любой серьезной системе реляционных баз данных), тогда поведениебыло бы так, как вы это описываете - это может иметь смысл с точки зрения бизнеса (например, удалить все позиции заказа для заказа), но в других случаях это может вообще не иметь никакого смысла (например, если вы удаляете заказ№ 1234, вы, как правило, не хотите удалить все продукты, на которые, вероятно, будут ссылаться позиции заказа для этого заказа.

Таким образом, существует два сценария - оба имеют смысл в определенных сценариях.и не так много в других.Это совсем не простой вопрос «или - или» / «правильно или неправильно».

1 голос
/ 07 апреля 2011

Это зависит от того, есть ли у вас ON DELETE CASCADE или ON DELETE SET NULL на вашей ТАБЛИЦЕ 1. Если у вас нет ни того, ни другого, или если это INITIALLY DEFERRED, тогда вы столкнетесь с INTEGRITY CONSTRAINT, потому что будет запись ребенка (в таблице 2). Вы можете прочитать об этом в Как работает каскад в случае удаления / обновления для внешнего ключа?

1 голос
/ 07 апреля 2011

Вы можете создать таблицы для удаления в Cascade.Когда вы добавляете ограничение внешнего ключа, вам нужно указать ограничение

CONSTRAINT fk1
FOREIGN KEY(col) REFERENCES parent(col) ON DELETE CASCADE,

В противном случае, да, вы должны сначала удалить потомков.

1 голос
/ 07 апреля 2011

Вы оба правы.

Если включено каскадное удаление, то строки внешнего ключа также будут удаляться при удалении строки первичного ключа.

1 голос
/ 07 апреля 2011

Это зависит от того, как вещи определены.Вы можете либо иметь каскадное удаление , либо заблокировать его (где сначала нужно удалить одно, затем другое)

0 голосов
/ 07 апреля 2011

Я считаю, что ваш друг прав: таблицы, на которые есть ссылки, не удаляются автоматически только потому, что вы удаляете таблицу с внешним ключом. Однако вы можете настроить триггеры, которые будут это делать.

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

...