У якому типі даних я повинен зберігати електронну адресу в базі даних?


44

Я розумію, що адреса електронної пошти з 254 символами є дійсною, але в дослідженні, що я досліджував, як правило, використовується varchar (60) до varchar (80) або еквівалент. Наприклад: ця рекомендація SQL Server використовує varchar (80) або цей приклад Oracle

Чи є причина не використовувати повний максимум 254 символу? Чи не varchar за визначенням не використовує лише стільки місця, скільки потрібно для зберігання даних?

Чи є значні наслідки / компроміси для продуктивності, які призводять до того, що стільки впроваджень використовують менше 254 можливих символів?

Відповіді:


45

Я завжди користувався VARCHAR(320). Ось чому. Стандарт диктує такі обмеження:

  • 64 символи для "локальної частини" (ім'я користувача).
  • 1 символ для @символу.
  • 255 символів для доменного імені.

Зараз деякі люди скажуть, що вам потрібно підтримати більше. Деякі люди також скажуть, що вам потрібно підтримувати Unicode для доменних імен (тобто ви повинні перейти на NVARCHAR). Незважаючи на те, що стандарт може тим часом змінитися (пройшов час, як у мене з'явилася шкіра в грі), я впевнений, що в цей час більшість серверів у світі не прийматимуть адреси електронної пошти Unicode, і я впевнений на багатьох серверах виникнуть проблеми зі створенням та / або прийняттям адрес з> 320 символами.

З цього приводу ви можете підготуватися до найгіршого зараз, якщо вам подобається (і якщо ви використовуєте стиснення даних у SQL Server 2008 R2 або вище, ви отримаєте користь від стиснення Unicode, тобто ви сплатите лише 2-байтний штраф за символи, які насправді потрібні це). Таким чином ви можете зробити свій стовпець настільки широким, наскільки вам захочеться, і ви можете дозволити людям вносити будь-які занадто довгі сміття туди, які вони хочуть - вони не отримають електронну пошту, якщо вони дадуть вам барахло так, як вони не захочуть отримати електронну пошту, якщо вставка не вдалася. Проблема полягає в тому, якщо ви пускаєте недійсні сміття, видоведеться з цим боротися. І незалежно від того, якого розміру ви це зробите - якщо хтось спробує набити 400 символів у стовпчик на 320 символів, хтось спробує вписати 1025 символів у колонку 1024 символів. Немає причин, щоб будь-яка розумна людина мала адресу електронної пошти> 320 символів, якщо вона не використовує її для явного тестування системних меж.

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


EDIT завдяки @ypercube за пінг у чаті.

З іншого боку, можливо, ви не хочете переносити всю адресу в одну колонку. Нормалізація може припустити, що ви не хочете зберігати @hotmail.com15 мільйонів разів, коли набагато більш стрункий FK int працював би чудово і не мав додаткових накладних витрат стовпців змінної довжини. Крім того, можна нормувати ім'я користувача, так як john.smith@hotmail.comі john.smith@gmail.comподіляють спільне ім'я - вони не знають один одного , але база даних не дбає про це.

Я говорив про щось тут:

http://www.mssqltips.com/sqlservertip/2657/storing-email-addresses-more-efficient-in-sql-server/

http://www.mssqltips.com/sqlservertip/2671/storing-email-addresses-more-efficient-in-sql-server--part-2/

Однак це вводить виклики до вищевказаного обмеження на 254 символів, оскільки, здається, немає єдиної думки щодо того, що відбувається, коли дійсний домен 255 символів поєднується з дійсним локальним розділом з 1 символом. Це повинно прийняти більшість серверів у всьому світі, але, схоже, порушує цю межу з 254 символами. Отже, ви створюєте Domainsтаблицю з штучно меншим обмеженням довжини для адрес електронної пошти, коли домен можна буде повторно використовувати як дійсну URL-адресу з 255 символами?


Мені подобається такий підхід, але як щодо унікальності електронної пошти? Як це управляється?
Роберто Ріцци

2
@RobertoRizzi Унікальне обмеження або первинний ключ у поєднанні DomainID + LocalPart або навпаки.
Аарон Бертран

5

Є кілька міркувань щодо цього рішення. Перш за все, це використання поточних та майбутніх прогнозів необхідних обмежень, яким повинні відповідати дані. Існує причина, чому ви не хочете встановлювати тип даних для кожного стовпця рядків, varchar(1024)коли ви просто зберігаєте рядок, що не повинна перевищувати 32 символи (акцент на ключовому слові слід ).

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

Що веде мене до мого наступного моменту. Швидше за все, база даних є лише рівнем даних. Для чого використовується рівень програми? Наприклад, якщо у вас є програма, де ви можете ввести лише 80 символів для адреси електронної пошти, чому ви хочете, щоб тип даних був більшим? Бізнес повинен відповісти на два питання:

  1. Що це може бути?
  2. Що це повинно бути?

Тільки тоді ви отримаєте свою відповідь.

Чи не varchar за визначенням не використовує лише стільки місця, скільки потрібно для зберігання даних?

Так і ні. Буде своєрідне зміщення даних змінної довжини для запису довжини.


3

RFC 5321 (поточна специфікація SMTP, застаріла RFC2821) визначає:

Максимальна загальна довжина імені користувача або іншої локальної частини - 64 октети. Максимальна загальна довжина доменного імені або числа - 255 октетів

Отже, знак 64 + 255 + @ передбачає VARCHAR (320). Напевно, вам ніколи не знадобиться стільки, але це безпечно, на всякий випадок.


4
Правильна межа - 254. rfc-editor.org/errata_search.php?rfc=3696&eid=1690
Ніл

1

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

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

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

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


1

Як коментар до чудових відповідей вже тут:

По-перше, якщо ви створили поле як varchar(240)і ви хочете пізніше змінити його на довше поле, скажімо varchar(320), ця зміна має бути тривіальною операцією на сервері баз даних - залежно, звичайно, від продукту вашої бази даних.

alter table Schema.Object alter column EmailAddress varchar(320) ;

По-друге, залежно від середнього розміру рядка та розміру сторінки, використовуючи varchar(320)замість того, щоб varchar(240)не змінювати кількість виділених сторінок (дисковий простір, фактично зайнятий таблицею).

По-третє, хтось вище говорив про перевірку електронної адреси. Я стверджую, що існує лише один надійний спосіб підтвердити адресу електронної пошти, а це надіслати електронний лист на неї. :-)


0

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

У моєму середовищі ми використовуємо varchar (70), оскільки найдовші, з якими я стикався, мають близько 60-70 знаків, але це також залежить від клієнтської бази вашої компанії. Також в якості побічної примітки переконайтеся, що у вас є певна перевірка електронної пошти на предмет дійсності адрес електронної пошти .. як, наприклад, використання обмежень для перевірки або CHARINDEX


0

Використання SQL DOMAIN

Якщо ви використовуєте сервер бази даних Enterprise, слід зберегти адресу електронної пошти як а DOMAINз певним рівнем дійсності. Домени вказані в специфікації SQL

Домен - це іменований користувачем об'єкт, який може бути визначений як альтернатива типу даних у певних місцях, де можна вказати тип даних. Домен складається з типу даних, можливо, за замовчуванням, та нуля або більше (домен) обмежень.

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

  • Створіть користувачу DOMAINнад специфікацією електронної пошти HTML5.
  • Або над RFC822, RFC2822, RFC5322 специфікаціями електронної пошти.
  • Створіть звичай, DOMAINякий перевіряє на сервері MX-запис на момент перевірки.

У цій відповіді я оцінюю ці параметри, характерні для PostgreSQL

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