Как нормализовать базу данных, в которой разные группы пользователей имеют разные типы профилей?
В моей базе данных приложений есть таблица групп, которая разделяет пользователей на логические роли и определяет уровни доступа (администратор, владелец, продавец, служба поддержки и т. д.)
Группы имеют много пользователей. В таблице пользователи содержатся данные для входа, такие как имя пользователя и пароль.
Теперь я хочу добавить профили пользователей в свою базу данных. Проблема, с которой я сталкиваюсь (вероятно, из-за моего относительного незнания правильной нормализации базы данных), заключается в том, что разные группы пользователей имеют разные виды профили. Следовательно, профиль продавца будет включать его процент комиссионных, в то время как администратору или службе поддержки клиентов это значение не понадобится.
Итак, будет ли правильным методом создать уникальную таблицу профилей для каждой группы? (например, admin_profiles или salesperson_profiles). или есть лучший способ, который объединяет определенные детали в общий профиль, в то время как некоторые пользователи имеют расширенную информацию. И если да, то какой хороший пример того, как это сделать с приведенным примером комиссии?
6 ответов:
В подобном случае, когда эти профили действительно определяются реальными критериями, я бы, вероятно, предложил использовать таблицы, посвященные каждому типу. В интересах полного раскрытия информации, однако, вы можете использовать систему подслушивания, чтобы хранить их. Что-то вроде:
User: UserID ... ProfileID Profile: ProfileID Name Criteria: CriteriaID Name ProfileCriteria: ProfileID CriteriaID UserCriteria: UserID CriteriaID
Таблица
Profile
определяет родительскую таблицу для профилей. У вас будет одна строка для каждого типа вашего профиля.
Criteria
определяет основные критерии, которые могут существовать на профиле, независимо от того, какой профиль (для например, у вас могут быть одинаковые критерии для нескольких профилей).
CriteriaProfile
служит для создания отношения m:m междуProfile
иCriteria
. Здесь также можно добавить такие вещи, как сортировка по критерию в определенном профиле.
UserCriteria
указывает на конкретные значения пользователя для данного критерия. Это также позволит вам переключать профили для пользователя и поддерживать любые критерии, которые были общими, просто удаляя те, которые не были частью нового профиль.Однако
Структуры EAV приходят с большим количеством накладных расходов для поддержания. Вместо того чтобы полагаться на средства СУБД для управления структурированными данными (за что людям платят большие деньги), теперь вы должны управлять ими самостоятельно. Таблицы, как правило, становятся очень большими значительно быстрее, чем в системах без EAV, поскольку у вас во много раз больше строк (как теперь у вас есть строка для того, что было бы каждым столбцом в нормальной структуре).
EAV являются мощными и гибкими, но не всегда решение. Если ваши профили должны быть динамическими, то они могут быть подходящим инструментом.
Ну, это зависит от того, насколько различна информация профиля. В нашем случае у продавцов гораздо больше информации, которую мы храним, чем у других пользователей. Нам нужно знать территорию, на которой они находятся, торговый персонал или силы, которые они представляют, бренды, которые они представляют, и т. д.
Если у вас есть только один или два фрагмента различных данных, просто добавьте столбцы и сделайте их недействительными. Если у вас есть много дополнительных данных, вам понадобятся таблицы для данных продавца и других групп. Это могут быть таблицы с отношением один к одному или один ко многим в зависимости от характера данных.
Но храните общую информацию профиля, которая относится ко всем, в одном месте. В конечном итоге у вас могут быть пользователи с несколькими ролями (продавец и администратор), и поэтому вы хотите, чтобы основная информация о пользователе сохранялась только один раз.
Вероятно, лучший способ сделать это-иметь таблицу
admin_profiles
, таблицуsalesperson_profiles
и так далее. Каждая таблица должна иметь внешний ключ, ссылающийся на базовую таблицу "пользователи", и любые свойства, которые применяются ко всем (или большинству) типам пользователей, должны быть столбцами в таблице" пользователи".Я предполагаю, что список различных ролей будет фиксированным, то есть что новые, произвольные типы ролей не будут добавлены пользователями системы. Если бы это было так, вы, вероятно, были бы на территории подслушивания, что я и сделал. понимать-это не очень весело.
Другой вариант, который был использован другими поставщиками, состоит в том, чтобы иметь только 2 таблицы. В одном из них перечислены атрибуты, определяющие профиль, такие как дисковое пространство, количество возвращаемых строк и т. д. Остальные перечисляют, какие группы имеют такую возможность. Оракул делает нечто очень похожее.
Это позволяет выполнять расширение проще, чем другие методы, но ограничивает вас в том, как вы добавляете новые пары имя-значение в структуру. Например, если в паре имя-значение есть 3 элемента, то у вас могут возникнуть проблемы. Но я думаю, что это более простой, чистый, масштабируемый и простой подход.
Лучше всего использовать таблицу user_meta, в которой хранятся идентификатор пользователя, мета-имя (комиссия или другое значение, которое вы хотите сохранить) и мета-значение.
Таким образом, вы можете добавлять и удалять поля без необходимости изменять базу данных, а также вам не придется постоянно просматривать разные таблицы.
Таким образом, вы могли бы иметь
Где пользователь №10-продавец, а пользователь № 50-представитель службы поддержки клиентов.user_id | meta_name | meta_value 10 | commission | 1.5% 50 | CS rating | 85%
Если ваши группы не собираются меняться в долгосрочной перспективе, я бы посоветовал сохранить отдельную таблицу для каждого профиля для каждой группы-admin_profile, salesperson_profile. Создайте объектную модель таким образом, чтобы все эти типы профилей были доступны в самом объекте пользователя.
Править
Если ваша объектная модель является звуковой, то вы можете сделать следующее.
Создать таблицу пользовательских профилей с внешней ссылки от пользователей и в группах. Добавьте два coloumns, ProfileFieldName и ProfileFieldValue. Также добавьте поле первичного ключа. Во время выполнения продолжайте добавлять ProfileFieldName и значения для каждой пары групп и пользователей, где это применимо. Самое главное, в объекте User вашей объектной модели укажите типизированные свойства, которые адресуют ProfileFieldName.
Я бы все равно рекомендовал сделать это предыдущим способом, так как это будет стоить вам больше запросов и больше циклов обработки. Построение объекта пользователя займет сравнительно больше времени и обработки в этом случае подход.