Лучший выбор для первичного ключа таблицы Person - PullRequest
5 голосов
/ 24 декабря 2009

Как вы выбираете первичный ключ в таблицах, которые представляют человека (например, Клиент, Пользователь, Клиент, Сотрудник и т. Д.)? Мой первый выбор - номер социального страхования (SSN). Тем не менее, использование SSN не рекомендуется из-за проблем конфиденциальности и других правил. SSN может меняться в течение жизни человека, так что это еще одна причина против этого.

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

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

Ответы [ 8 ]

7 голосов
/ 24 декабря 2009

Я не знаю, какой движок базы данных вы используете, но (по крайней мере с MySQL - см. 7.4.1. Сделайте ваши данные как можно меньше ) , используя целое число, самое короткое из возможных, обычно считается лучшим для производительности и требований к памяти.

Я бы использовал целое число auto_increment для этого первичного ключа.
Идея такова:

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

И затем установите индекс UNIQUE для другого столбца, который определяет уникальность, если это возможно и / или необходимо.


Изменить: Вот несколько других вопросов / ответов, которые могут вас заинтересовать:

3 голосов
/ 24 декабря 2009

Какие атрибуты вам доступны? Какие из них волнует ваше приложение? Например, два человека не могут родиться в одну и ту же секунду в одном и том же месте, но вы, вероятно, не имеете доступа к этим данным с таким уровнем точности! Таким образом, из атрибутов, которые вы намереваетесь моделировать, вам нужно решить, какие из них достаточны для обеспечения приемлемого уровня целостности данных. Что бы вы ни выбрали, вы правы, сосредоточившись на аспектах целостности данных (предотвращая вставку нескольких строк для одного и того же человека) по вашему выбору.

Для соединений / внешних ключей в других таблицах лучше использовать суррогатный ключ.

Я вырос, чтобы рассмотреть использование слова Первичный ключ как неправильное или, в лучшем случае, запутанное. Любой ключ, независимо от того, помечен ли он как Первичный ключ , Альтернативный ключ , Уникальный ключ или Уникальный индекс , по-прежнему является ключом, и требует, чтобы каждая строка в таблице содержала уникальные значения для атрибутов в ключе. В этом смысле все ключи эквивалентны. Важнее всего (больше всего), являются ли они естественными ключами (в зависимости от значимых атрибутов данных модели реального домена) или суррогатами (независимыми от атрибутов реальных данных)

Во-вторых, важно также то, для чего вы используете ключ. Суррогатные ключи узки и просты и никогда не меняются (Нет причин - они ничего не значат). Поэтому они являются лучшим выбором для соединений или для внешних ключей. в других зависимых таблицах.

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

Ключ не должен быть на 100% неизменным. Если (в качестве примера) вы используете имя, номер телефона и дату рождения, например, даже если человек меняет свое имя или номер телефона, вы можете просто изменить значение в таблице. Пока ни у одной другой строки нет новых значений в их ключевых атрибутах, у вас все в порядке.

Даже если выбранный вами ключ работает только в 99,9% случаев (скажем, вам не повезло столкнуться с двумя людьми с одинаковым именем и номером телефона, которые случайно родились в один и тот же день), по крайней мере, 99,9 % ваших данных будет гарантированно точным и непротиворечивым - и вы можете, например, просто добавить время к их дате рождения, чтобы сделать их уникальными, или добавить какой-то другой атрибут к ключу, чтобы различать их. Если вам не нужно обновлять значения данных в внешних ключах по всей базе данных из-за этого изменения (поскольку вы не используете этот ключ в качестве FK в другом месте), вы не столкнетесь с какой-либо существенной проблемой.

3 голосов
/ 24 декабря 2009

Как уже упоминалось выше, используйте автоинкремент в качестве первичного ключа. Но я не верю, что это ваш настоящий вопрос.

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

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

Конечно, если вы можете получить SSN / SIN, используйте его для определения уникальности.

1 голос
/ 25 декабря 2009

Я предпочитаю натуральные ключи, когда им можно доверять.

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

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

1 голос
/ 24 декабря 2009

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

1 голос
/ 24 декабря 2009

Я предпочитаю натуральные ключи, но таблица person - проигранный случай. SSN не уникальны, и не у всех есть.

1 голос
/ 24 декабря 2009

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

0 голосов
/ 24 декабря 2009

Для добавления к @Mark и @Pascal (лучше всего ставить автоинкрементные целые числа) - SSN полезны и должны корректно моделироваться Проблемы безопасности являются частью логики приложения. Вы можете нормализовать их в отдельную таблицу и сделать их уникальными, указав поле даты выпуска.

p.s., Для тех, кто не согласен с пунктом «безопасность в приложении», корпоративная БД будет иметь детализированную модель ACL; так что это не будет камнем преткновения.

...