2008-09-18 10 views
9

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

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

ответ

8

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

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

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

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

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

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

1

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

3

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

0

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

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

0

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

+2

Обратите внимание, что UUID (GUIDs в MS land) на самом деле делают плохие ключи во многих случаях, потому что их случайность и размер ухудшают механизмы индексирования. Лучше всего использовать простое целое число, когда это возможно. – 2010-10-13 17:24:17

0

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

0

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

В качестве примера рассмотрим таблицы услуг aspnet_ * here.

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

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