Отделение таблицы пользователей от таблицы людей в реляционной базе данных

StackOverflow https://stackoverflow.com/questions/92894

  •  01-07-2019
  •  | 
  •  

Вопрос

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

Разумно ли создать вторую таблицу, people_tb, это основная реляционная таблица и хранилище данных, и используйте только users_tb для аутентификации?Разделяет ли user_tb от people_tb представлять какие-либо проблемы?Если это обычно делается, каковы некоторые стратегии и решения, а также недостатки?

Это было полезно?

Решение

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

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

С точки зрения кодирования, если вы используете прямой SQL, потребуется немного больше усилий, чтобы мысленно проанализировать оператор выбора.Это может быть немного сложнее, если вы используете библиотеку ORM.У меня недостаточно опыта работы с ними.

В своем приложении я пишу его на Ruby on Rails, поэтому я постоянно делаю такие вещи, как «сотрудник.имя пользователя», где, если бы я оставил их вместе, это было бы просто «имя сотрудника» или «имя пользователя».

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

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

Другие советы

Я регулярно делаю это, потому что для меня понятие «пользователь» (имя пользователя, пароль, дата создания, дата последнего входа в систему) отличается от понятия «человек» (имя, адрес, телефон, адрес электронной почты).Одним из недостатков, с которым вы можете столкнуться, является то, что вашим запросам часто потребуется больше объединений для получения искомой информации.Если у вас есть только имя для входа, вам нужно будет присоединиться к таблице «Люди», чтобы получить, например, имя и фамилию.Если вы основываете все на первичном ключе идентификатора пользователя, это немного смягчается, но все равно всплывает.

Если у user_tb есть информация для аутентификации, я бы хранил ее отдельно от People_tb.Однако я бы сохранил связь между ними, и большая часть информации пользователей будет храниться в файле People_tb, за исключением всей информации, необходимой для аутентификации (которая, я думаю, не будет использоваться ни для чего другого). Это хороший компромисс между дизайном и эффективностью. думать.

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

Тогда для людей, которые входят в систему, вы можете иметь users таблица, которая имеет отношение 1~1 с people.В этой таблице могут храниться имя пользователя и пароль.

Я бы посоветовал использовать нормализованный дизайн (две таблицы) и денормализовать (перейти к одной таблице «пользователь/человек») только в том случае, если это действительно облегчит вашу жизнь в будущем.Однако если практически все люди также являются пользователями, возможно, будет проще провести денормализацию заранее.Тебе решать;Я использовал нормализованный подход без проблем.

Очень разумно.

В качестве примера взгляните на таблицы служб aspnet_*. здесь.

Их встроенная схема имеет aspnet_Users и aspnet_Membership при этом более поздняя таблица содержит более расширенную информацию о данном пользователе (хешированные пароли и т. д.), но aspnet_User.UserID используется в других частях схемы для ссылочной целостности и т. д.

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

Это определенно то, что мы делаем, поскольку у нас есть записи миллионов людей и только тысячи пользователей.Мы также разделяем адреса, телефоны и электронные письма на реляционные таблицы, поскольку у многих людей есть более одного из этих элементов.Крайне важно не полагаться на имя как на идентификатор, поскольку имя не уникально.Убедитесь, что таблицы объединены с помощью суррогатного ключа определенного типа (предпочтительно целое число или GUID), а не имени.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top