В чем разница между чеком и внешним ключом? - PullRequest
9 голосов
/ 11 апреля 2010

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

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

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

Ответы [ 4 ]

7 голосов
/ 11 апреля 2010

Ограничение FOREIGN KEY гарантирует, что запись СУЩЕСТВУЕТ в

EDIT другой стол

согласно правильному комментарию Существует в другой таблице ... или той же таблице. - Марк Байерс

Ограничение CHECK гарантирует, что запись следует некоторому правилу.

ПРОВЕРЬТЕ Ограничения

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

3 голосов
/ 11 апреля 2010

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

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

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

1 голос
/ 11 апреля 2010

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

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

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

при условии, что MATCHES существует и поддерживает соответствующий язык регулярных выражений.

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

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)

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

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

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

Рассмотрим сценарий, подобный следующему:

  1. Таблица A имеет столбец ключевое слово , и значение должно быть среди тысяч предоставленных ключевых слов.
  2. Как бы вы хотели реализовать ограничение?
    жестко закодируйте условие как check (keyword in ('a', 'b', 'c' .......)) или просто импортируйте предоставленные ключевые слова в виде другой таблицы и установите ограничение внешний ключ для столбца ключевых слов таблицы A.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...