2010-04-11 2 views
8

Я довольно смущен разницей между ограничениями FOREIGN KEY и CHECK - они мне кажутся для достижения того же результата.В чем разница между чеком и внешним ключом?

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

В чем разница и когда использовать тот или иной?

ответ

6

ВНЕШНЯЯ KEY Ограничить гарантирует, что запись ДЕЙСТВИТЕЛЬНО СУЩЕСТВУЕТ в

EDIT другой таблицы

согласно правильным комментарием существует в другой таблице ... или же таблице. - Mark Byers

A CHECK constrain гарантирует, что запись будет следовать правилу.

CHECK Constraints

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

+4

Существует в другой таблице ... или той же таблице. –

+0

Ограничения CHECK определяют ..., которые не основаны на данных в другом столбце. Не совсем корректно, ограничения проверки могут включать несколько столбцов (по крайней мере, в 10g). Лучше сказать «не на основе данных в другой таблице». – Juraj

2

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

Ограничение проверки не может ссылаться на любые столбцы за пределами текущей таблицы и не может содержать подзапрос. Часто значения жестко закодированы как BETWEEN 100 and 999 или IN (1, 2, 3). Это означает, что по мере изменения вещей вам придется обновлять ограничение CHECK каждый раз. Кроме того, отношение внешнего ключа видимо на диаграмме отношений сущностей (ERD), в то время как ограничение CHECK никогда не будет. Преимущество состоит в том, что кто-то может прочитать ERD и построить запрос из него, не используя многочисленные команды таблицы DESC, чтобы знать, какие столбцы есть и что связано с тем, что нужно для создания правильных объединений.

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

+2

Внешние ключи не обязательно должны быть одним столбцом. –

1

Это зависит от вашей СУБД (которую вы не указали), но в некотором смысле вы правы: ограничение внешнего ключа является частным случаем ограничения проверки. Существуют СУБД, которые не позволят вам сформулировать ограничение внешнего ключа в качестве контрольного ограничения.

Основной целью контрольного ограничения является описание условий, которые применяются к одной строке в таблице. Например, у меня есть таблица элементов (как в Hydrogen, Helium, ...), а символы для элементов ограничены, чтобы начинаться с буквы верхнего регистра, а за ним следует ноль, одна или две строчные буквы (две строчные буквы для еще неоткрытых, но предсказанных элементов: Uus - ununseptium (117) , который только что был изолирован, но еще не назван). Это может быть предметом проверочного ограничения:

CHECK(Symbol MATCHES "[A-Z][a-z]{0,2}") 

предполагающих МАТЧИ существуют и поддерживают соответствующий язык регулярных выражений.

Вы также можете иметь проверочные ограничения, которые сравнивают значения:

CHECK(OrderDate <= ShipDate OR ShipDate IS NULL) 

Чтобы выразить ограничение внешнего ключа в качестве проверочного ограничения, вы должны быть разрешены для выполнения запроса в предложении CHECK. Гипотетически:

CHECK(EXISTS(SELECT * FROM SomeTable AS s 
       WHERE ThisTable.pk_col1 = s.pk_col1 AND 
        ThisTable.pk_col2 = s.pk_col2)) 

В этом примере показаны некоторые проблемы. У меня нет удобного псевдонима таблицы для таблицы, в которой я пишу ограничение проверки - я предположил, что это «ThisTable». Конструкция многословная. Предполагая, что первичный ключ SomeTable объявлен на колонках pk_col1 и pk_col2, то FOREIGN KEY положение является гораздо более компактным:

FOREIGN KEY (pk_col1, pk_col2) REFERENCES SomeTable 

Или, если вы ссылаетесь альтернативный ключ, а не первичный ключ:

FOREIGN KEY (pk_col1, pk_col2) REFERENCES SomeTable(ak_col1, ak_col2) 

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

Вопрос задает вопрос: когда использовать ограничение проверки и когда использовать ограничение внешнего ключа?

  • Используйте ограничение CHECK, чтобы указать критерии, которые можно проверить в одной строке.
  • Используйте ограничение FOREIGN KEY, чтобы указать, что значения в текущей строке должны соответствовать значениям строки в другом уникальном ключе (ключ-кандидат, обычно первичный ключ, а не альтернативный ключ) некоторой таблицы, что может быть той же таблицей или (чаще) другой таблицей.
Смежные вопросы