Унікальний або первинний ключ електронної адреси?


11

Я новачок у базах даних. Я прочитав навколо, і дізнався, що, мабуть, не чудова ідея використовувати адресу електронної пошти в якості основного ключа, оскільки порівняння рядків повільніше, що впливає на ефективність у складних з'єднаннях, а якщо зміна електронної пошти, мені доведеться змінити всі зовнішні ключі, що вимагає багато зусиль.

Але якщо моя таблиця користувачів вимагає від кожного користувача електронної адреси, і кожна з цих адрес електронної пошти має бути унікальною, чи буде достатньо додати унікальний індекс у стовпці електронної пошти? Оскільки унікальні поля afaik дозволяють нульові значення, тоді як я вимагаю від кожного користувача електронної адреси, не допускаючи нульових значень. Щось тут мені не вистачає? Або я вважаю, щоб зробити стовпець електронної пошти унікальним і переконатися, що під час перевірки даних на сервері користувач вводить електронну адресу, щоб кожен користувач мав його?


3
Що станеться, коли користувач змінить свою електронну адресу - як, наприклад, змінить роботу
user151019

1
Порівняння рядків відбувається не просто повільніше, рядки також мають велике значення, ніж скажімо, ціле число, а значить, ви можете помістити менше на сторінці в пам'яті, підштовхуючи ваші логічні зчитування для запитів.
Безіменний Один

Відповіді:


7

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

Ключ-кандидат - це те, що однозначно ідентифікує рядок у таблиці, в SQL один з кандидатських ключів зазвичай використовується як первинний ключ (я ніколи не розумів, чому один з ck вважається "кращим", ніж інші, але це інший історія), а решта 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, а потім побудувавши на ньому унікальний індекс.


1
Це не вірно про SQL-сервер. Ви можете створювати індекси за допомогою whereпунктів, які, наприклад, дозволяють виключити NULLзначення з індексу.
Кірк Волл

1
Заява SQL Server allows a single NULL valueвсе-таки вірна. Це не говорить про те, що немає способу отримати кілька NULLзначень. Я думаю, що відповідь-ер намагався зробити відповідь простою і не пояснити зайві деталі (наприклад, відфільтрований індексом).
Брендон

1
Так, я міг би спустити кролика цілий відфільтрований індекс, але на просте запитання зазвичай потрібна проста відповідь. Без платформи бази даних та версії я зберігаю свої відповіді загальними.
mrdenny

2

Добре мати унікальний індекс на EmailAddress.

Оскільки ви вже заявляли, що у вашій заявці є валідація щодо наявності адреси електронної пошти як необхідного поля, я б сказав, що інша перевірка була б із бази даних, це не прийняти користувача з адресою електронної пошти та запобігти повторному введенню, а також цю перевірку буде накладено за допомогою цього Унікального індексу.

Як зазначено в іншій відповіді для SQL Server, перед створенням унікальних індексів потрібно зробити стовпець, який не допускає нульового значення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.