Адрес электронной почты уникальный или первичный ключ?

11

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

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

aandis
источник
3
Что происходит, когда пользователь меняет свой адрес электронной почты - как он, например, меняет работу
user151019
1
Сравнение строк не просто медленнее, строки также имеют тенденцию быть больше, чем, скажем, целое число, и, следовательно, вы можете разместить меньше на странице в памяти, увеличивая количество логических операций чтения для запросов.
Безымянный Один

Ответы:

7

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

Ключ-кандидат - это то, что однозначно идентифицирует строку в таблице, в SQL один из ключей-кандидатов обычно используется в качестве первичного ключа (я так и не понял, почему один из ck считается «лучше», чем другие, но это другой рассказ), а оставшаяся копия становится уникальным ограничением.

Уникальное ограничение может использоваться так же, как и первичный ключ. Рассматривать:

create table A ( x ... not null
               , y ... not null
               , z ... not null
               ,     unique (x)
               ,     primary key (y,z) );

create table B ( x ...
               ,   ...
               ,     foreign key (x) references A (x) );

create table C ( y ...
               , z ...
               ,   ...
               ,     foreign key (y, z) references A (y, z) );  

B ссылается на ограничение уникальности, а C ссылается на ограничение первичного ключа.

NOT NULL - это еще один вид ограничений. В вашем случае вы можете применить это к электронной почте, не объявляя ее уникальной.

Следующий аспект вашего сообщения касается стабильности ключа, ключ должен быть стабильным (но это не значит, что он никогда не может измениться, он не должен быть неизменным). Некоторые СУБД реализуют ПО ОБНОВЛЕНИЮ КАСКАД, который может помочь в такой операции, но если ключ распределен по вашей модели, обновление будет затруднительно.

В вашем случае я, вероятно, выбрал бы другой кандидатный ключ в качестве первичного ключа и объявил бы, что электронная почта НЕ НЕДЕЙСТВИТЕЛЬНА и УНИКАЛЬНА.

Леннарт
источник
1
В SQL Server вы можете ссылаться на уникальный индекс как FK.
Мартин Смит,
1
У меня нет доступа к SQL, поэтому я не могу проверить сам, создает ли он неявное ограничение при создании уникального индекса?
Леннарт
1
Нет. Уникальное ограничение обрабатывается немного по-другому и имеет некоторые дополнительные метаданные и дополнительные ограничения по сравнению с уникальным индексом, но SQL Server позволяет использовать любой из них в FK.
Мартин Смит
1
Это немного странно, индексы даже не упоминаются в стандарте sql, тогда как ключи являются его центральной частью. Во всяком случае, спасибо за информацию.
Леннарт
Стоит отметить, что, если к вашей электронной почте прикреплено много записей с внешним ключом, обновление всех этих записей может занять довольно много времени при каскадном обновлении.
cimmanon
6

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

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

mrdenny
источник
1
Это не правда о SQL-сервере. Вы можете создавать индексы с whereпредложениями, которые, например, позволяют исключать NULLзначения из индекса.
Кирк Волл
1
Заявление SQL Server allows a single NULL valueвсе еще верно. Это не говорит, что нет способа получить несколько NULLзначений. Я думаю, что ответчик пытался сохранить ответ простым и не объяснять лишние детали (например, отфильтрованный индексированный).
Брэндон
1
Да, я мог бы бросить кролику целые отфильтрованные индексы, но простой вопрос обычно требует простого ответа. Без базы данных и версии я оставляю свои ответы общими.
Мрденный
2

Иметь уникальный индекс на EmailAddress - это хорошо.

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

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

vijayp
источник