Может ли внешний ключ быть пустым и / или дублированным? - PullRequest
262 голосов
/ 27 сентября 2011

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

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

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

Ответы [ 11 ]

441 голосов
/ 27 сентября 2011

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

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

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

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

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

47 голосов
/ 27 сентября 2011

1 - Да, хотя бы SQL Server 2000.

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

39 голосов
/ 27 сентября 2011

Изо рта лошади:

Внешние ключи допускают значения ключей, которые имеют значение NULL, даже если их нет соответствующие ПЕРВИЧНЫЕ или УНИКАЛЬНЫЕ ключи

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

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

Ограничение NOT NULL на внешний ключ

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

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

УНИКАЛЬНОЕ ограничение на внешний ключ

Когда УНИКАЛЬНОЕ ограничение определенный по внешнему ключу, только одна строка в дочерней таблице может ссылка на данное значение родительского ключа. Эта модель допускает нулевые значения в внешний ключ.

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

  • Для обеспечения соблюдения правил ссылочной целостности между EMP_TAB и СТРАХОВЫЕ таблицы (ограничение FOREIGN KEY)

  • Чтобы гарантировать, что каждый сотрудник имеет уникальный номер участника ( УНИКАЛЬНОЕ ключевое ограничение)

УНИКАЛЬНЫЕ и НЕ НУЛЬНЫЕ ограничения на внешний ключ

Когда оба УНИКАЛЬНЫ и ограничения NOT NULL определены для внешнего ключа, только одна строка в дочерней таблице может ссылаться на заданное значение родительского ключа, и потому Значения NULL не допускаются во внешнем ключе, каждая строка в дочернем Таблица должна явно ссылаться на значение в родительском ключе.

Смотрите это:

Oracle 11g link

15 голосов
/ 08 января 2016

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

5 голосов
/ 28 июня 2018

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

  1. , если этот foreign key также является key attribute в ваших отношениях, то он не может быть NULL
  2. если этот foreign key является нормальным атрибутом в вашем отношении, то он может быть НЕДЕЙСТВИТЕЛЕН.
3 голосов
/ 19 декабря 2014

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

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

Создайте таблицу PROVINCE

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, достаточно указать только PROVINCE_ID.Однако, если вы решили указать также COUNTRY_ID, он должен уже существовать в таблице COUNTRY.

1 голос
/ 20 декабря 2017

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

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

0 голосов
/ 04 февраля 2019

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

0 голосов
/ 26 января 2018

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

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

0 голосов
/ 31 октября 2017

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

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

Так как существует возможность для одной записи объекта-A идентифицировать себя с записями другого объекта-B, поэтому в Entity-B должен быть столбец, чтобы иметь значение идентификатора записи объекта-объекта. B. Этот столбец может быть нулевым, если ни одна запись в Entity-A не идентифицирует запись (и), или объект (ы) в Entity-B.

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

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

...