Почему такие внешние ключи возможны? - PullRequest
0 голосов
/ 06 февраля 2009

Почему стандарт SQL принимает это? Какие преимущества?

Если есть эти таблицы:

create table prova_a (a number, b number);
alter table prova_a add primary key (a,b);
create table prova_b (a number, b number);
alter table prova_b add foreign key (a,b) references prova_a(a,b) ;
insert into prova_a  values (1,2);

Вы можете вставить это без ошибки:

insert into prova_b  values (123,null);
insert into prova_b  values (null,123);

Примечание 1 : Это вытекает из этого ответа .

Примечание2 : Этого можно избежать, установив ненулевое значение в обоих столбцах.

Замечания : Я не спрашиваю о том, чтобы избежать, мне интересно, какие выгоды.

Рекомендации:

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

  • Документация по SQL Server : Ограничение FOREIGN KEY может содержать нулевые значения; однако, если какой-либо столбец составного ограничения FOREIGN KEY содержит нулевые значения, проверка всех значений, составляющих ограничение FOREIGN KEY, пропускается.

Ответы [ 5 ]

4 голосов
/ 06 февраля 2009

Я знаю, что некоторые СУБД просто не обеспечивают ссылочную целостность, когда речь идет о внешних ключах с ограничениями внешнего ключа. SQLite приходит на ум. Здесь говорится о здесь .

Другие СУБД отличаются, я знаю, что MS SQL Server будет жаловаться, если вы попытаетесь что-то подобное.

SQLite имеет свои применения, но он не предназначен для использования в ситуациях с высокой степенью параллелизма. Если вы видите такое поведение в другой СУБД, проверьте их документацию, чтобы увидеть, не сделали ли они что-то подобное. Однако большинство должно обеспечивать соблюдение целостности.

2 голосов
/ 06 февраля 2009

, по крайней мере, ваша DEV работает с достаточно стандартной СУБД, даже если вы работаете в своей производственной системе с чем-то вроде SQLite (которая является отличной базой данных - она ​​работает на вашем Ipod-прикосновении!). как Линт действительно. Если вы запустите свой код с помощью SQL Server Express, который вы можете скачать бесплатно, вы получите множество ошибок, таких как ...

Msg 8111, Level 16, State 1, Line 2
Cannot define PRIMARY KEY constraint on nullable column in table 'prova_a'.
Msg 1750, Level 16, State 0, Line 2
Could not create constraint. See previous errors.
1 голос
/ 26 февраля 2009

Oracle и SQL Server допускают использование внешних ключей со значением NULL, и легко понять, почему это необходимо. Представьте, например, дерево, в котором у каждой строки есть родительский ключ, который ссылается на первичный ключ той же таблицы. В дереве должен быть корневой узел, у которого нет родителя, а родительский ключ будет нулевым. Более осязаемый пример: подумайте о сотрудниках и менеджерах. У некоторых людей в компании, и если это будет только генеральный директор, не будет менеджера. Если бы для идентификатора менеджера в таблице сотрудников было невозможно установить значение NULL, вам бы пришлось создать сотрудника без менеджера - что-то, что просто неправильно, поскольку у него нет реальной корреспонденции.

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

0 голосов
/ 06 февраля 2009

Попробуйте добавить это объявление:

изменить таблицу prova_b добавить первичный ключ (a, b);

Это запретит NULLS в prova_b. Также будут запрещены повторяющиеся записи. В Oracle и SQL-сервере он также создаст индекс. Этот индекс ускорит поиск и объединение за счет небольшого замедления вставок.

Это то, что вы хотите сделать?

Относительно того, почему стандартный SQL позволяет вам делать что-то, что вы считаете глупым, это философский вопрос. Большинство инструментов допускают некоторые глупые выборы. Инструменты, которые пытаются запретить все глупые выборы, обычно запрещают непреднамеренно некоторые действительно умные выборы.

0 голосов
/ 06 февраля 2009

Стандарт SQL не принимает это; Вы нашли СУБД, которая не обеспечивает ссылочную целостность. Удалите его сейчас , если вы умны. Как минимум, не используйте его в производственных целях.

Более ранние стандарты SQL (SQL86) не имели ссылочной целостности, и SQL89 уровня 2 исправило это.

...