Каковы недостатки ограничений внешнего ключа, которые ссылаются на столбцы без первичного ключа? - PullRequest
2 голосов
/ 20 марта 2011

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

Существуют ли различия в том, как анализируются запросы в конкретных системах БД (например, Microsoft SQL Server 2005), в зависимости от того, ссылается ли внешний ключ на первичный ключ, а не на уникальный ключ?

Обратите внимание, что я не спрашиваю о различиях между использованием столбцов разных типов данных для ссылочной целостности, объединений и т. Д.

Просто в качестве примера представьте БД, в которой есть «справочная таблица» dbo.Offices:

CREATE TABLE dbo.Offices (
    ID   int NOT NULL IDENTITY(1,1) CONSTRAINT PK_Codes PRIMARY KEY,
    Code varchar(50) NOT NULL CONSTRAINT UQ_Codes_Code UNIQUE
);

Есть также таблица dbo.Patients:

CREATE TABLE dbo.Patients (
    ID         int NOT NULL IDENTITY(1,1) CONSTRAINT PK_Patients PRIMARY KEY,
    OfficeCode varchar(50) NOT NULL,
    ...
    CONSTRAINT FK_Patients_Offices FOREIGN KEY ( OfficeCode )
        REFERENCES dbo.Offices ( Code )
);

Каковы недостатки таблицы dbo.Patients и ее ограничения FK_Patients_Offices, как в приведенном выше коде T-SQL, по сравнению со следующей альтернативной версией:

CREATE TABLE dbo.Patients (
    ID       int NOT NULL IDENTITY(1,1) CONSTRAINT PK_Patients PRIMARY KEY,
    OfficeID int NOT NULL,
    ...
    CONSTRAINT FK_Patients_Offices FOREIGN KEY ( OfficeID )
        REFERENCES dbo.Offices ( ID )
);

Очевидно, что для второй версии dbo.Patients значения в столбце OfficeID обновлять не нужно, если в значения в столбце Code dbo.Offices внесены изменения.

Также (очевидно) то, что использование столбца Code dbo.Offices для ссылок на внешний ключ в значительной степени отрицательно сказывается на цели столбца суррогатного ключа ID - это чисто артефакт примера. [Есть ли лучший пример таблицы, для которой ссылки на внешний ключ могут разумно использовать не первичный ключ?]

Ответы [ 6 ]

2 голосов
/ 20 марта 2011

Недостатков нет.

Тем не менее ..

Почему у вас есть столбец ID в таблице "Офисы"? Суррогатный ключ используется для уменьшения пространства и повышения производительности, скажем, столбца varchar при использовании в других таблицах в качестве внешнего ключа.

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

Большинство преимуществ наличия IDENTITY упущены с использованием столбца Code для FK.

2 голосов
/ 20 марта 2011

Почему вы думаете, что будут какие-то недостатки?

Совсем наоборот!Приятно видеть, что вы применяете ссылочную целостность, как и все остальные!Никаких недостатков - просто хорошая практика, чтобы сделать это!

Я не вижу никаких функциональных различий или проблем / проблем со ссылкой на уникальный индекс по сравнению со ссылкой на первичный ключ.


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

Единственное незначительное, что я вижу, это то, что ваш OfficeCode является одновременно VARCHAR, и, таким образом, вы можете столкнуться с проблемами с сопоставлением и / или регистром (в верхнем / нижнем регистре, в зависимости от вашего сопоставления), а также с JOIN.Большое (до 50 байт) и поле переменной длины, вероятно, не так эффективно, как условия JOIN, основанные на небольшом столбце INT фиксированной длины.

1 голос
/ 21 марта 2011

Первичный ключ является ключом-кандидатом и принципиально не отличается от любого другого ключа-кандидата. Широко распространено соглашение о том, что один ключ-кандидат на таблицу обозначается как «первичный», и этот ключ используется для всех ссылок на внешние ключи.

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

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

Большой недостаток Мы смогли ввести некоторое значение в dbo.Patients.OfficeID , которого нет в dbo.Offices.ID Нет смысла говорить, что есть ссылка.

0 голосов
/ 20 марта 2011

Предполагая, что вы добавляете индекс к столбцу кода (что вам определенно следует сделать, как только вы на него ссылаетесь), можно ли что-то сказать против избавления от всего столбца идентификатора и использования столбца кода в качестве PK?

0 голосов
/ 20 марта 2011

Самое важное, что я могу вспомнить, это то, что, если они когда-нибудь перенумеруют офисы, вы либо потеряете целостность, либо вам придется обновить обе таблицы. Как бы вероятно это ни было.

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

Для большинства людей это не считается существенным фактором, определяющим структуру базы данных.

...