У меня есть таблица, которая содержит данные, и одна из этих строк должна существовать в другой таблице. Итак, я хочу, чтобы внешний ключ поддерживал ссылочную целостность.
CREATE TABLE table1
(
ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
AnotherID INT NOT NULL,
SomeData VARCHAR(100) NOT NULL
)
CREATE TABLE table2
(
ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
AnotherID INT NOT NULL,
MoreData VARCHAR(30) NOT NULL,
CONSTRAINT fk_table2_table1 FOREIGN KEY (AnotherID) REFERENCES table1 (AnotherID)
)
Однако, как видите, в таблице, к которой я добавляю внешний ключ, столбец не является PK. Есть ли способ создать этот внешний ключ или, возможно, лучший способ сохранить эту ссылочную целостность?
sql
sql-server
Craig
источник
источник
table1.ID
?Ответы:
Если вы действительно хотите создать внешний ключ для не-первичного ключа, это ДОЛЖЕН быть столбец с уникальным ограничением.
Из книг онлайн :
Так что в вашем случае, если вы сделаете
AnotherID
уникальным, это будет разрешено. Если вы не можете применить уникальное ограничение, вам не повезло, но это действительно имеет смысл, если вы думаете об этом.Хотя, как уже упоминалось, если у вас есть очень хороший первичный ключ в качестве ключа-кандидата, почему бы не использовать его?
источник
Как указывали другие, в идеале внешний ключ должен создаваться как ссылка на первичный ключ (обычно столбец IDENTITY). Однако мы не живем в идеальном мире, и иногда даже «небольшие» изменения в схеме могут оказывать существенное влияние на логику приложения.
Рассмотрим случай таблицы Customer со столбцом SSN (и немым первичным ключом) и таблицы требований, которая также содержит столбец SSN (заполняемый бизнес-логикой из данных Customer, но FK не существует). Дизайн имеет недостатки, но использовался в течение нескольких лет, и три различных приложения были построены на схеме. Должно быть очевидно, что удаление Claim.SSN и установление реальных отношений между PK и FK было бы идеальным, но также и существенным капитальным ремонтом. С другой стороны, наложение уникального ограничения на Customer.SSN и добавление FK на Claim.SSN может обеспечить ссылочную целостность, практически не влияя на приложения.
Не поймите меня неправильно, я за нормализацию, но иногда прагматизм побеждает идеализм. Если посредственный дизайн можно помочь с помощью пластыря, хирургии можно избежать.
источник
Necromancing.
Я предполагаю, что когда кто-то попадает сюда, ему нужен внешний ключ для столбца в таблице, содержащей неуникальные ключи.
Проблема в том, что если у вас есть эта проблема, схема базы данных денормализуется.
Например, вы храните комнаты в таблице с первичным ключом room-uid, полем DateFrom и DateTo и другим идентификатором, здесь RM_ApertureID для отслеживания той же комнаты и поле мягкого удаления, например RM_Status, где 99 означает «удаленный», а <> 99 означает «активный».
Поэтому, когда вы создаете первую комнату, вы вставляете RM_UID и RM_ApertureID в качестве того же значения, что и RM_UID. Затем, когда вы заканчиваете комнату на определенную дату и восстанавливаете ее с новым диапазоном дат, RM_UID является newid (), и RM_ApertureID из предыдущей записи становится новым RM_ApertureID.
Так что, если это так, RM_ApertureID является неуникальным полем, и поэтому вы не можете установить внешний ключ в другой таблице.
И нет никакого способа установить внешний ключ для неуникального столбца / индекса, например, в T_ZO_REM_AP_Raum_Reinigung (WHERE RM_UID на самом деле является RM_ApertureID).
Но чтобы запретить недопустимые значения, вам нужно установить внешний ключ, иначе, мусор данных будет результатом скорее, чем позже ...
Теперь, что вы можете сделать в этом случае (если не считать переписывания всего приложения), вставить CHECK-ограничение с помощью скалярной функции, проверяющей наличие ключа:
источник
Первичные ключи всегда должны быть уникальными, внешние ключи должны разрешать неуникальные значения, если таблица является отношением «один ко многим». Совершенно нормально использовать внешний ключ в качестве первичного ключа, если таблица связана отношением один к одному, а не отношением один ко многим.
Ограничение FOREIGN KEY не обязательно должно быть связано только с ограничением PRIMARY KEY в другой таблице; он также может быть определен для ссылки на столбцы ограничения UNIQUE в другой таблице.
источник