Первичный ключ таблицы пользователей веб-приложения: суррогатный ключ, имя пользователя, адрес электронной почты, идентификатор клиента - PullRequest
6 голосов
/ 01 апреля 2012

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

enter image description here

таблица пользователей имеет следующее определение

CREATE  TABLE IF NOT EXISTS `mydb`.`user` (
  `id` INT NOT NULL ,
  `username` VARCHAR(25) NOT NULL ,
  `email` VARCHAR(25) NOT NULL ,
  `external_customer_id` INT NOT NULL ,
  `subscription_end_date` DATETIME NULL ,
  `column_1` VARCHAR(45) NULL ,
  `column_2` VARCHAR(45) NULL ,
  `colum_3` VARCHAR(45) NULL ,
  PRIMARY KEY (`id`) ,
  UNIQUE INDEX `username_UNIQUE` (`username` ASC) ,
  UNIQUE INDEX `email_UNIQUE` (`email` ASC) ,
  UNIQUE INDEX `customer_id_UNIQUE` (`external_customer_id` ASC) )
ENGINE = InnoDB

У меня возникают следующие проблемы со столбцами кандидатов первичного ключа:

Идентификационный столбец

Плюсы

  • Нет делового значения (стабильный первичный ключ)
  • быстрое соединение таблиц
  • индекс сжатия

против

  • не "естественный" ключ
  • Все таблицы атрибутов должны быть объединены с "основной" пользовательской таблицей, поэтому прямые запросы на неприсоединение невозможны
  • вызывает меньше "естественных" SQL-запросов
  • Утечка информации: пользователь может выяснить количество зарегистрированных пользователей, если начальное значение равно 0 (при изменении начального значения это выяснить) ii) Пользователь, зарегистрировавший профиль как user_A в time_X и через некоторое время как user_B в time_Y, сможет легко рассчитать количество зарегистрированных пользователей за период времени ((Id для user_B) - (Id для user_A) / (time_Y - время_X))

столбец электронной почты

Плюсы

Против

  • пользователь должен иметь возможность изменить адрес электронной почты. Не подходит для первичного ключа

имя пользователя столбец

Плюсы

  • "естественный" первичный ключ
  • Меньше объединений таблиц
  • простых и более "естественных" запросов

Против

  • Столбец varchar медленнее при объединении таблиц
  • индекс столбца varchar менее компактен, чем индекс столбца int
  • очень сложно изменить имя пользователя, так как внешние ключи зависят от значения. Решение: «Синхронизировать» все внешние ключи в приложении или , не позволяя пользователю изменить имя пользователя, например,. пользователь должен удалить профиль, зарегистрировать новый

колонка external_customer

профи

  • может использоваться как внешняя ссылка для клиента и не содержит никакой информации (может быть, вместо этого можно использовать не редактируемое имя пользователя?)

    минусы

  • может привести к утечке информации, если она является автоинкрементной (если это возможно)

  • проблематично сгенерировать unqiue-значение, если автоинкрементный суррогатный идентификатор уже используется, так как движок MySQL innodb не создает несколько столбцов auto_increment в одной таблице

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

Ответы [ 3 ]

11 голосов
/ 02 апреля 2012

Мне нечего сказать о вашем анализе. Если я сократил некоторые ваши плюсы или минусы, это означает, что я не думаю, что мне есть что добавить.

Идентификационный столбец

Плюсы

  • Нет делового значения (стабильный первичный ключ)
  • быстрое соединение таблиц
  • индекс сжатия

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

В вашем случае ваша структура позволяет 4 столбцам быть целью ссылки на внешний ключ: идентификатор, имя пользователя, адрес электронной почты и external_customer_id. Вам не нужно использовать один и тот же все времени. Возможно, имеет смысл использовать идентификатор для 90% ваших ссылок на FK и электронное письмо для 10% из них.

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

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

У вас есть три других уникальных индекса. ( Хорошо для вас. Я думаю, что по крайней мере 90% людей, которые создают базу данных, не понимают этого правильно.) Так что не только индекс на идентификационном номере является более компактным, чем любой из них. три; это также дополнительный индекс. (В этой таблице.)

столбец электронной почты

Плюсы

  • нет

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

Но адреса электронной почты могут быть "потеряны". В США большинство студентов университетов теряют свои адреса электронной почты * .edu примерно через год после выпуска. Если ваш адрес электронной почты поступает через домен, за который вы платите, и вы прекращаете платить, адрес электронной почты исчезает. Я полагаю, что такие адреса электронной почты могут быть предоставлены новым пользователям. Создает ли это невыносимое бремя, зависит от приложения.

Против

  • пользователь должен иметь возможность изменить адрес электронной почты. Не подходит для первичного ключа

Все значения в базе данных SQL могут быть изменены. Это только не подходит, если ваша среда не позволяет вашим dbms своевременно выполнять декларацию ON UPDATE CASCADE. Моя среда делает. (Но я запускаю PostgreSQL на приличном неразделенном оборудовании.) YMMV.

имя пользователя столбец

За

  • "естественный" первичный ключ
  • Меньше объединений таблиц
  • более простые и более "естественные" запросы

Меньше объединений - важный момент. Я был на консультациях, где видел бессмысленное использование идентификационных номеров, заставляющих людей писать запросы с 40+ объединениями. Разумное использование натуральных ключей исключено до 75% из них.

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

Против

  • столбец varchar медленнее при объединении таблиц
  • индекс столбца varchar менее компактен, чем индекс столбца int

Вы не можете сказать, что присоединение к varchar () происходит медленнее, без проверки этого утверждения. Дело в том, что, хотя большинство объединений в varchar () медленнее , чем объединения в идентификаторах, они не обязательно настолько медленны, что их нельзя использовать. Если запрос занимает 4 мс с номерами идентификаторов и 6 мс с varchar (), я не думаю, что это хорошая причина для дисквалификации varchar (). Кроме того, использование естественного ключа устранит множество соединений, поэтому общий отклик системы может быть быстрее. (При прочих равных условиях 40 соединений по 4 мс будут хуже, чем 10 соединений по 6 мс.)

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

колонка external_customer

профи

  • может использоваться как внешняя ссылка для клиента и не содержит никакой информации (может быть, вместо этого можно использовать нередактируемое имя пользователя?)

На самом деле существует несколько систем, которые позволяют мне менять свое имя пользователя. Большинство позволит мне изменить свое настоящее имя (я думаю), но не мое имя пользователя. Я думаю, что не редактируемое имя пользователя вполне разумно.

4 голосов
/ 02 апреля 2012

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

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

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

0 голосов
/ 01 апреля 2012

Я думаю, что с колонкой имени пользователя у вас также есть следующие минусы:

  • Пользователь должен иметь возможность изменить имя пользователя.Не подходит для первичного ключа.

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

...