Необходимо ли определять для ВНЕШНЕГО КЛЮЧА те же ограничения, которые определены для ПЕРВИЧНОГО КЛЮЧА (родительской таблицы)?

#sql-server

#sql-server

Вопрос:

Допустим, я создаю таблицу Clients . Я определяю первичный ключ и набор ограничений, таких как:

  • NOT NULL
  • Длина> 5
  • ВЕРХНИЙ РЕГИСТР

и так далее..

Теперь я создаю другую таблицу с внешним ключом к Clients первичному ключу. Должен ли я создавать те же ОГРАНИЧЕНИЯ для внешнего ключа?

Если я этого не сделаю, это не будет иметь значения, поскольку значение не будет существовать в первичной таблице в первую очередь:

Пример: я не создаю ограничения для внешнего ключа, и я пытаюсь добавить значение, длина которого меньше 5 символов, и в нижнем регистре… База данных не найдет это значение в родительской таблице, следовательно, значение не будет записано, так какой смысл устанавливать тот же набор ограничений для внешней таблицы?

Комментарии:

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

2. Но даже если вы решили использовать «введенные пользователем данные» в качестве первичного ключа, смысл внешнего ключа в том, что он точно соответствует первичному ключу. Так что, если вы не примените это каким-то образом, ваша система не будет работать.

3. @DaleBurrell Я согласен с тем, что ПЕРВИЧНЫЕ КЛЮЧИ должны генерироваться системой в ЦЕЛОСТНОСТИ, но так ли это для ВНЕШНЕГО КЛЮЧА? Допустим, я создаю таблицу CLIENTS. Каждый клиент имеет свой собственный уникальный идентификатор клиента, сгенерированный системой, это нормально. Теперь предположим, что есть другая таблица, называемая Транзакциями. Каждая транзакция будет иметь свой собственный идентификатор транзакции, который будет сгенерирован системой, и это нормально. НО идентификатор клиента в транзакции не может быть автоматически сгенерирован системой, поскольку клиент уже существует в таблице CLIENT .. идентификатор клиента должен быть выбран мной или системой

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

Ответ №1:

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

Опять же, как упоминал @Dale Burrell, ПЕРВИЧНЫЙ КЛЮЧ должен быть сгенерирован системой для обеспечения уникальности. Если вы собираетесь создать кластеризованный индекс для столбца первичного ключа, он должен быть узким, увеличивающимся, а не нулевым, уникальным значением для получения хорошей производительности.

Ответ №2:

Вам не нужны ограничения длины или верхнего регистра для внешнего ключа. Они будут «неявно проверены» ограничением внешнего ключа (как вы говорите, потому что ссылочные данные не могут существовать).

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

Итак, здесь вместо этого должен возникнуть вопрос: есть ли строки в другой таблице, которые действительно не должны ссылаться на строку в Clients таблице?


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

Комментарии:

1. Спасибо. Что вы подразумеваете под «Сгенерированной системой»? Я студент. Считалось, что единственный способ сгенерировать PK — это определить столбец как PK … то есть МЫ определяем PK. Я не знаю, каким будет PK, сгенерированный системой.

2. Дэмиен, извини, я не понял, что такое обнуляемость… «Но для обнуляемости это выбор. В SQL Server, если один или несколько столбцов в таблице ссылок внешнего ключа имеют значение NULL, ограничение не применяется. Итак, здесь вместо этого должен быть вопрос: есть ли строки в другой таблице, которые не должны действительно ссылаться на строку в таблице клиентов? » Можете ли вы epxplain другими словами?

3. @user2324238 — сгенерированный системой — это означало бы использовать IDENTITY столбец an в SQL Server или a SEQUENCE . обнуляемость — представьте, что PK в клиентах есть ClientID . Если также вызывается FK для клиентов ClientID , он либо а) содержит ненулевое значение, которое должно соответствовать значению PK в клиентах, либо б) оно может быть нулевым. Во втором случае мы не ищем значение PK в клиентах, которое равно null. Ссылки нет.