Каков Ваш выбор для первичного ключа в таблицах, которые представляют человека (как Клиент, Пользователь, Клиент, Сотрудник и т.д.)? Моим предпочтительным вариантом был бы номер социального страхования (SSN). Однако использованию SSN препятствовали из-за проблем конфиденциальности и различных инструкций. SSN может измениться в течение времени жизни человека, так, чтобы была другая причина против него.
Я предполагаю, что одна из функций хорошо выбранного естественного первичного ключа должна избежать дублирования. Я не хочу, чтобы человек был зарегистрирован дважды в базе данных. Некоторый суррогат или сгенерированный первичный ключ не помогают в предотвращении дублирующихся записей. Что лучший способ состоит в том, чтобы приблизиться к этому?
Что лучший способ состоит в том, чтобы гарантировать уникальности в Вашем приложении для объекта человека, и это может быть обработано на уровне базы данных с ограничением уникальности или первичным ключом?
Как упоминалось выше, используйте в качестве первичного ключа автоинкремент. Но я не верю, что это ваш реальный вопрос.
Ваш реальный вопрос - как избежать дублирования записей. Теоретически, нет никакого способа - 2 человека могут родиться в один день, с одним и тем же именем, и жить в одном доме, и не иметь номера социального страхования, доступного для того или иного. (Одним из них может быть иностранец, посещающий страну)
Однако, чтобы избежать дублирования, обычно достаточно сочетания полного имени, даты рождения, адреса и номера телефона. Обратите внимание, что адреса могут вводиться по-разному, люди могут иметь несколько телефонных номеров, а также люди могут не указывать свое второе имя или использовать инициалы. Это зависит от того, насколько важно избежать дублирования вводимых данных, а также от того, насколько велика ваша пользовательская база (и, следовательно, вероятность столкновения).
Конечно, если вы можете получить SSN/SIN, то используйте его для определения уникальности.
.Какие атрибуты вам доступны? Какие из них важны для Вашего заявления? Например, ни один человек не может родиться в одну и ту же секунду в одном и том же месте, но у Вас, скорее всего, нет доступа к этим данным с такой степенью точности! Поэтому Вам необходимо решить, из тех атрибутов, которые Вы собираетесь использовать при моделировании, какие из них достаточны, чтобы обеспечить приемлемый уровень целостности данных. Что бы вы ни выбрали, вы правы в том, что фокусируетесь на аспектах целостности данных (предотвращение вставки нескольких строк для одного и того же человека), которые вы выбрали.
Для входов/выходов из других таблиц лучше всего использовать суррогатный ключ.
Я вырос, чтобы считать использование слова Primary Key неправильным или, в лучшем случае, запутанным. Любой ключ, независимо от того, отмечен ли он как Primary Key, Alternate Key, Unique Key или Unique Index, все равно является ключом, и требует, чтобы каждая строка в таблице содержала уникальные значения для атрибутов в ключе. В этом смысле все ключи являются равнозначными. Более того, важно, являются ли они естественными ключами (зависит от значимых атрибутов данных модели реального домена) или заменителями (зависит от атрибутов реальных данных)
Во-вторых, важно также, для чего вы используете ключ... Суррогатные ключи узкие и простые и никогда не меняются (нет причин - они ничего не значат), поэтому они являются лучшим выбором для вступления или для чужих Ключей в других зависимых таблицах.
Но для обеспечения целостности данных и предотвращения вставки нескольких строк для одной и той же сущности домена, они совершенно бесполезны... Для этого вам понадобится некий Natural Key, выбранный из имеющихся у вас данных, и который ваше приложение моделирует с той или иной целью.
Ключ не обязательно должен быть на 100% неизменяемым. Если (в качестве примера) Вы используете, например, Имя и Номер телефона и Дата рождения, даже если человек меняет свое имя или номер телефона, Вы можете просто изменить значение в таблице. До тех пор, пока ни в одной из других строк не появятся новые значения в их ключевых атрибутах, вы будете в порядке.
Даже если выбранный вами ключ работает только в 99,9% случаев (скажем, вам не повезло, что вы столкнулись с двумя людьми с одинаковыми именем и номером телефона и родились случайно в один и тот же день), ну, по крайней мере, 99,9% ваших данных будут гарантированно точными и согласованными - и вы можете, например, просто добавить время к дате их рождения, чтобы сделать их уникальными, или добавить какой-нибудь другой атрибут к ключу, чтобы отличить их. До тех пор, пока вам не придется обновлять значения данных в Иностранных ключах по всей вашей базе данных из-за изменения, (так как вы не используете этот ключ в качестве FK в других местах), вы не столкнетесь с какой-либо существенной проблемой
.Я не знаю, какой движок Базы Данных вы используете, но (по крайней мере с MySQL -- смотрите 7.4.1. Сделайте ваши данные как можно меньше ), используя как можно более короткое целое число, обычно считается наилучшим для производительности и требований к памяти.
Я бы использовал для этого первичного ключа целое число, auto_increment
.
Идея в том, что :
И, затем, установите UNIQUE
индекс на другой столбец -- тот, который определяет однозначность -- если это возможно и/или необходимо.
Правка: Вот еще пара вопросов/ответов, которые могут вас заинтересовать :
Используйте автогенерируемый целочисленный первичный ключ, а затем наложите уникальное ограничение на все, что, по вашему мнению, должно быть уникальным. Но SSN не уникальны в реальном мире, поэтому было бы плохой идеей наложить ограничение уникальности на этот столбец, если только вы не думаете, что отвергать клиентов, потому что ваша база данных не примет их - хорошая бизнес-модель.
. Я предпочитаю натуральные ключи, но таблица человек
- проигранный случай. SSN не уникальны и не у всех они есть.
Я бы порекомендовал суррогатный ключ. Добавьте все необходимые индексы для других ключей-кандидатов, но я бы не советовал держать бизнес-логику подальше от ключа
.Я предпочитаю натуральные ключи, когда им можно доверять.
Если только вы не управляете банком или чем-то подобным, у ваших клиентов и пользователей нет причин предоставлять вам действительную SSN, или даже обязательно иметь ее. Таким образом, по деловым причинам, вы вынуждены не доверять SSN в том случае, который вы наметили. Похожий аргументатор будет держать для любого заданного естественного ключа "лиц".
У вас нет другого выбора, кроме как присвоить искусственный (читайте "суррогатный") ключ. С тем же успехом это может быть целое число. Убедитесь, что это достаточно большое целое число, чтобы вам не понадобилось расширять его в ближайшее время.
Для добавления в @Mark и @Pascal (лучше всего использовать целые числа с автоинкрементом) -- SSN полезны и должны быть правильно смоделированы. Вопросы безопасности являются частью логики приложения. Вы можете нормализовать их в отдельную таблицу, а также сделать их уникальными, предоставив поле, выдающее данные.
п.с., для тех, кто не согласен с точкой `безопасности в приложении`, БД предприятия будет иметь гранулярную ACL-модель; так что это не станет камнем преткновения.
.