Может ли внешний ключ быть нулевым и / или дубликатом?

пожалуйста, проясните две вещи для меня:

  1. может ли внешний ключ быть нулевым?
  2. можно ли дублировать внешний ключ?

насколько я знаю, справедливо,NULL Не следует использовать во внешних ключах, но в некоторых моих приложениях я могу вводить NULL Как в Oracle, так и в SQL Server, и я не знаю почему.

10 ответов


короткий ответ: Да, это может быть NULL или дубликат.

Я хочу объяснить, почему внешний ключ может быть null или должен быть уникальным или не уникальным. Сначала помните, что внешний ключ просто требует, чтобы значение в этом поле сначала существовало в другой таблице (родительской таблице). Это все FK по определению. Null по определению не является значением. Null означает, что мы еще не знаем, что такое значение.

позвольте мне привести вам пример реальной жизни. Предположим вам есть база данных, в которой хранятся предложения по продажам. Предположим далее, что каждому предложению назначено только одно торговое лицо и один клиент. Таким образом, ваша таблица предложений будет иметь два внешних ключа, один с идентификатором клиента и один с идентификатором торгового представителя. Однако на момент создания записи торговый представитель назначается не всегда (поскольку никто еще не может работать с ним), поэтому идентификатор клиента заполняется, но идентификатор торгового представителя может быть равен null. Другими словами, обычно вам нужна возможность иметь нулевой FK, когда вы можете не знать его значения во время ввода данных, но вы знаете другие значения в таблице, которые необходимо ввести. Чтобы разрешить нули в FK, как правило, все, что вам нужно сделать, это разрешить нули на поле с FK. Значение null отделено от идеи того, что оно является FK.

является ли он уникальным или нет, относится к тому, имеет ли таблица отношение один-один или один-много к родительской таблице. Теперь, если у вас есть отношения один-один, возможно, что вы может иметь данные все в одной таблице, но если таблица становится слишком широкой или если данные находятся на другой теме (например, пример страхования сотрудников @tbone), то вы хотите отдельные таблицы с FK. Затем вы захотите сделать этот FK также PK (который гарантирует уникальность) или поставить на него уникальное ограничение.

большинство FKs предназначены для отношения один ко многим, и это то, что вы получаете от FK без добавления дополнительного ограничения на поле. Итак, у вас есть например, таблица order и таблица order details. Если клиент заказывает десять товаров одновременно, у него есть один заказ и десять записей деталей заказа, которые содержат тот же orderID, что и FK.


1 - да, по крайней мере, с SQL Server 2000.

2 - Да, пока это не UNIQUE ограничение или связанный с уникальным индексом.


из первых уст:

внешние ключи позволяют значения ключей, которые все NULL, даже если нет соответствующие первичные или уникальные ключи

никаких ограничений на внешний ключ

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

не нулевое ограничение на внешнем ключе

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

любое количество строк в дочерней таблице может ссылаться на одного и того же родителя ключевое значение, поэтому эта модель устанавливает отношение " один ко многим между родительским и внешним ключами. Однако каждая строка в ребенка таблица должна иметь ссылку на родителя ключевое значение; отсутствие значение (a null) во внешнем ключе не допускается. Тот же пример в предыдущий раздел можно использовать для иллюстрации такой взаимосвязи. Однако в этом случае сотрудники должны иметь ссылку на конкретный отдел.

уникальное ограничение на внешний ключ

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

эта модель устанавливает взаимно однозначное отношение между родителем и внешние ключи, которые позволяют неопределенные значения (нули) в внешний ключ. Например, предположим, что таблица employee имеет столбец названо MEMBERNO, ссылаясь на номер членства сотрудника в план страховой компании. Кроме того, таблица с именем INSURANCE имеет первичный ключ с именем MEMBERNO и другие столбцы таблицы сохраняют соответствующие информация, касающаяся страховой полис работника. В MEMBERNO в таблица employee должна быть как внешним ключом, так и уникальным ключом:

  • для применения правил ссылочной целостности между EMP_TAB и Таблицы страхования (ограничение внешнего ключа)

  • чтобы гарантировать, что каждый сотрудник имеет уникальный номер участника (в Уникальное ограничение ключа)

уникальные и не нулевые ограничения на внешнем Ключ

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

Это:

Oracle 11g link


да внешний ключ может быть null, как сказано выше старших программистов... Я бы добавил другой сценарий, где внешний ключ должен быть нулевым.... предположим, у нас есть таблицы комментариев, изображений и видео в приложении, которое позволяет комментировать фотографии и видео. В таблице комментариев мы можем иметь два внешних ключа PicturesId и VideosId вместе с CommentId первичного ключа. Поэтому, когда вы комментируете видео, потребуется только VideosId, а pictureId будет нулевым... и если вы прокомментируете изображение только PictureId будет требоваться и VideosId будет нулевым...


это зависит от того, какую роль этот foreign key играет в ваших отношениях.

  1. если это foreign key тоже key attribute в вашем отношении, тогда это не может быть NULL
  2. если это foreign key является нормальным атрибутом в вашем отношении, тогда он может быть нулевым.

вот пример использования синтаксиса Oracle:
Сначала давайте создадим таблицу COUNTRY

CREATE TABLE TBL_COUNTRY ( COUNTRY_ID VARCHAR2 (50) NOT NULL ) ;
ALTER TABLE TBL_COUNTRY ADD CONSTRAINT COUNTRY_PK PRIMARY KEY ( COUNTRY_ID ) ;

создать таблицу провинция

CREATE TABLE TBL_PROVINCE(
PROVINCE_ID VARCHAR2 (50) NOT NULL ,
COUNTRY_ID  VARCHAR2 (50)
);
ALTER TABLE TBL_PROVINCE ADD CONSTRAINT PROVINCE_PK PRIMARY KEY ( PROVINCE_ID ) ;
ALTER TABLE TBL_PROVINCE ADD CONSTRAINT PROVINCE_COUNTRY_FK FOREIGN KEY ( COUNTRY_ID ) REFERENCES TBL_COUNTRY ( COUNTRY_ID ) ;

это отлично работает в Oracle. Обратите внимание, что внешний ключ COUNTRY_ID во второй таблице не имеет "NOT NULL".

теперь, чтобы вставить строку в таблицу провинций, достаточно указать только PROVINCE_ID. Однако, если вы также решили указать COUNTRY_ID, он должен существовать уже в стране таблица.


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

при создании таблицы / изменении таблицы, если вы добавите любое ограничение уникальности или not null, то только это не позволит null / дублировать значения.


проще говоря," неидентифицирующие " отношения между сущностями являются частью ER-модели и доступны в Microsoft Visio при разработке ER-диаграммы. Это необходимо для обеспечения мощности между сущностями типа "ноль или более нуля"или" ноль или один". Обратите внимание на этот "ноль" в мощности вместо "один" в "один ко многим".

теперь пример неидентифицирующих отношений, где мощность может быть " нулевой "(неидентифицирующей), когда мы говорим, что запись / объект в одном объекте - " может" или "не может" иметь значение в качестве ссылки на запись / записи в другом объекте-B.

Как, есть возможность за одну запись лица-чтобы идентифицировать себя данным другой организации-Б, поэтому там должен быть столбец в сущности-B, чтобы иметь личность-величина юридическое лицо-Б. В этом столбце может быть "null", если нет записи в лицо-идентифицирует запись/с (или, объект/с) в лицо-Б.

в объектно-ориентированной (реальной) парадигме существуют ситуации, когда объект класса-B не обязательно зависит (сильно связан) от объекта класса-A для его существования, что означает, что класс-B слабо связан с классом-a таким образом, что класс-A может "содержать" (сдерживание) объект класса-A, в отличие от понятия объекта класса-B должен иметь (состав) объект класса-A, для его (объекта класса-B) создания.

с точки зрения SQL-запроса вы можете запросить все записи в entity-B ,которые" не являются нулевыми " для внешнего ключа, зарезервированного для Entity-B. Это приведет ко всем записям, имеющим определенное соответствующее значение для строк в Entity-a в качестве альтернативы все записи с нулевым значением будут записями, которые не имеют никакой записи в Entity-A в Entity-B.


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

но ответ все зависит от бизнеса.


Я думаю, что внешний ключ одной таблицы также первичный ключ к какой-то другой таблице.Так что это не позволит nulls.Таким образом, нет вопроса о том, чтобы иметь значение null во внешнем ключе.