Отделение таблицы пользователей от таблицы людей в реляционной базе данных - PullRequest
9 голосов
/ 18 сентября 2008

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

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

Ответы [ 7 ]

8 голосов
/ 18 сентября 2008

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

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

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

В моем приложении я пишу это в Ruby on Rails, поэтому я постоянно делаю такие вещи, как employee.user.name, где, если я их храню, это будет просто employee.name или user.name.

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

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

3 голосов
/ 18 сентября 2008

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

1 голос
/ 18 сентября 2008

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

0 голосов
/ 18 сентября 2008

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

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

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

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

0 голосов
/ 18 сентября 2008

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

0 голосов
/ 18 сентября 2008

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

0 голосов
/ 18 сентября 2008

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

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

...