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

228

Прошу пояснить две вещи для меня:

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

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

  • 1
    @Adrian: Насколько мне известно, внешний ключ не может быть нулевым, но он принимает значение null в SQL Server и Oracle. можешь объяснить почему?
  • 0
    @Jams - прочитайте ссылку в моем ответе.
Показать ещё 2 комментария
Теги:
sql-server
foreign-keys

12 ответов

393
Лучший ответ

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

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

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

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

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

  • 12
    Так это должно быть лучше, чем иметь поддельного продавца по имени "Неназначенный"?
  • 5
    Комментарий. Нули оставляют много места для ошибок в запросе людьми, которые не знают, как SQL (неправильно) обрабатывает 3VL. Если продавец действительно не нужен для определенной таблицы, просто не включайте эту запись. Отдельная таблица может быть «ProposalAssignedTo» или чем-то подобным, с соответствующими ограничениями. Автор запросов может затем присоединиться к этой таблице и предоставить собственную логику для всего, что мы хотим сделать, когда в предложении нет продавца. NULL не просто означает «мы не знаем» - его можно использовать для многих вещей (вот почему это почти всегда плохая идея)
Показать ещё 4 комментария
47

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

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

36

Из устья лошади:

Внешние ключи позволяют использовать значения ключей, которые являются NULL, даже если их нет. сопоставление ключей PRIMARY или UNIQUE

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

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

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

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

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

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

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

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

  • Чтобы обеспечить соблюдение правил ссылочной целостности между EMP_TAB и Таблицы СТРАХОВАНИЯ (ограничение FOREIGN KEY)

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

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

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

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

ссылка Oracle 11g

13

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

  • 1
    Я думаю, что есть лучший способ решить эту проблему. Вместо создания новых столбцов у вас может быть два столбца, а именно «id» и «type», которые будут содержать id и имя таблицы внешнего ключа. Например, id = 1, type = Picture будет представлять ссылку на таблицу изображений с идентификатором 1. Преимущество использования этого решения заключается в том, что вам не нужно создавать новые столбцы, когда комментарии добавляются в дополнительные таблицы. Недостатком будет отсутствие ограничения внешнего ключа на уровне БД, скорее ограничение должно быть на уровне приложения.
  • 2
    @Agent: у нас было это «решение» в производстве. Не делай этого, это ужасно. Создание запросов превращается в беспорядок: «если это тип 1, присоединяйтесь к этой таблице, в противном случае присоединяйтесь к этой». Это был кошмар для нас. В итоге мы сделали то, что говорит этот ответ, и создали новый столбец для каждого типа объединения. Создание столбцов это дешево. В значительной степени недостатком является то, что большое количество столбцов затрудняет использование Toad, но это всего лишь недостаток Toad.
Показать ещё 3 комментария
5

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

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

Вот пример использования синтаксиса 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

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

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

0

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

0

Может ли столбец FOREIGN KEY содержать нулевое значение или повторяющиеся значения

Что такое внешний ключ? FOREIGN KEY - это ключ, который используется для связи двух таблиц. FOREIGN KEY - это столбец или набор столбцов в одной таблице, который ссылается на PRIMARY KEY в другой таблице. Таблица, содержащая PRIMARY KEY, называется дочерней таблицей, а таблица, содержащая PRIMARY KEY, называется родительской таблицей.

Может ли столбец FOREIGN KEY содержать нулевое значение

ДА, столбец FOREIGN KEY может содержать нулевые значения. Ноль по определению означает не значение. Нуль означает, что мы еще не знаем, каково значение столбца. Например, у нас есть три таблицы "Изображения", "Видео" и "Комментарии" в приложении, которое позволяет комментировать изображения, а также видео. В таблице комментариев у нас есть два внешних ключа p_id и v_id вместе с первичным ключом comment_id. Поэтому, когда вы комментируете видео, потребуется только v_id, а p_id не требуется, поэтому он будет нулевым. Кроме того, если вы прокомментируете изображение, потребуется только p_id, а v_id будет нулевым.

Может ли столбец FOREIGN KEY содержать повторяющиеся значения

ДА, столбец FOREIGN KEY может содержать повторяющиеся значения. ИНОСТРАННЫЙ КЛЮЧ можно использовать для отношений один ко многим. Например, у нас есть таблица заказов и таблица деталей заказа. Если какой-либо клиент заказывает пять товаров, у него есть один заказ и пять подробных записей заказа, которые содержат тот же идентификатор заказа, что и FK. Вы можете узнать больше об этой функции, нажав на эту ссылку: https://www.quora.com/How-can-I-do-to-automatics-reset-auto-increment-values-in-MySQL-table/answer/Shadab-Кази-17

0

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

Но ответ все зависит от Бизнеса.

0

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

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

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

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

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

-5

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню