Лучшая схема для отношений «oneOf» в СУБД

#sql #rdbms

Вопрос:

Пусть существует 3 типа администраторов,

  1. Администратор службы
  2. Администратор проекта
  3. Администратор группы проектов

И таблицы, как показано ниже,

 CREATE TABLE UserInfo {  userid BIGINT PRIMARY KEY,  ... } CREATE TABLE ProjectInfo {  projectid BIGINT PRIMARY KEY,  ... } CREATE TABLE ProjectTeamInfo {  teamid BIGINT PRIMARY KEY,  projectid BIGINT NOT NULL,  CONSTRAINMT `rfk_team_to_project`  FOREIGN KEY `projectid` REFERENCES TO ProjectInfo(projectid)  ON DELETE CASCADE ON UPDATE CASACDE,  ... }  

И если я хочу предоставить конкретное разрешение администратора User Management , Project Management , ProjectTeam Management конкретному пользователю, какова была бы лучшая схема для определения AdminInfo таблицы?

Предположим, что есть таблицы, подобные приведенным ниже,

 CREATE TABLE AdminInfo {  userid BIGINT NOT NULL,  isServiceAdmin BOOLEAN NOT NULL,  isProjectAdmin BOOLEAN NOT NULL,  admProjectId BIGINT DEFAULT NULL, (ref to projectinfo table)  isTeamAdmin BOOLEAN NOT NULL,  teamId BIGINT DEFAULT NULL, (ref to teaminfo table) }  

Есть 3 возможных случая,

  1. Администратор службы(Управление пользователями) : { идентификатор пользователя: 1, isServiceAdmin: true }
  2. Администратор проекта : { идентификатор пользователя: 2, isProjectAdmin: true, admProjectId: 1000 }
  3. Администратор команды : { идентификатор пользователя : 3, isTeamAdmin: true, идентификатор команды: 100 }

Но это выглядит очень ужасно, а также не то, чем должна была быть СУБД.

Подводя итог, схема выглядит следующим образом,

Пользователь может иметь различные типы AdminPreviliges в зависимости от своей категории, например ServiceAdmin , ProjectAdmin , TeamAdmin .

Как определить таблицы, которые могут варьировать информацию в зависимости от конкретной категории?

Единственный способ сделать это так-просто определить ServiceAdminInfo ProjectAdminInfo , TeamAdminInfo отдельно?

Ответ №1:

Возможно, вы ищете дизайн пользовательского членства.

Базовый дизайн будет соответствовать этому :

 Users gt; Roles (Groups) gt; Privileges (Permissions)  

Таким образом, вы можете использовать Roles для создания ролей для каждого типа использования, таких как Admin , Project ..и т.д., И использовать Privileges для определения привилегий каждой роли (базовыми могут быть SELECT , INSERT , DELETE )

Последнее, что вам нужно, — это просто связать их вместе one-to-many отношениями. (у каждого пользователя может быть одна или несколько ролей, и каждая роль может иметь одну или несколько привилегий).

Оттуда вы можете расширить свой дизайн до того места, где, по вашему мнению, он соответствует вашему текущему бизнесу.

ОБНОВИТЬ Комментарии

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

Вы связываете Groups Permissions и Users с таблицами , используя их внешние ключи.

Нравится

 CREATE TABLE GroupPermissions {  Id INT PRIMARY KEY,  GroupId INT,  PermissionId INT,  CONSTRAINT `FK_GroupPermissions_GroupId` FOREIGN KEY GroupId REFERENCES TO Groups(Id)   ON DELETE CASCADE   ON UPDATE CASCADE,   CONSTRAINT `FK_GroupPermissions_PermissionId` FOREIGN KEY PermissionId REFERENCES TO Permissions(Id)  }   CREATE TABLE GroupUsers {  Id INT PRIMARY KEY,  GroupId INT,  UserId INT,  CONSTRAINT `FK_GroupUsers_GroupId` FOREIGN KEY GroupId REFERENCES TO Groups(Id)   ON DELETE CASCADE   ON UPDATE CASCADE,   CONSTRAINT `FK_GroupUsers_PermissionId` FOREIGN KEY UserId REFERENCES TO Users(Id)  }   CREATE TABLE GroupPermissionUsers {  Id INT PRIMARY KEY,  GroupPermissionId INT,  UserId INT,  CONSTRAINT `FK_GroupPermissions_GroupPermissionId` FOREIGN KEY GroupPermissionId REFERENCES TO GroupPermissions(Id)   ON DELETE CASCADE   ON UPDATE CASCADE,   CONSTRAINT `FK_GroupUsers_PermissionId` FOREIGN KEY UserId REFERENCES TO Users(Id)  }  

Groups и Permissions являются таблицами, в которых вы храните определения для обоих. В то время GroupPermissions как и GroupUsers являются таблицами, в которых вы храните assigned целые числа. Однако GroupPermissionUsers это таблица, в которой вы фактически проверяете каждого пользователя, чтобы получить группы пользователей и разрешения. Поэтому, когда пользователь пытается что-то сделать, и вам нужно проверить его/ее разрешение, вы просто используете GroupPermissionUsers get назначенные разрешения и проверяете их на соответствие разрешениям объекта, которым вы назначили.

Комментарии:

1. Очень признателен за ответ. Что касается таких примеров, как «Существует несколько групп, и привилегии отличаются от каждой группы для каждого пользователя». В этом случае, как я могу это решить? Я думаю, что могу создать другую таблицу, например «GroupMemberInfo», и, когда пользователь пытается что-то сделать со своей группой, 1)Проверьте, есть ли у участника группы 2)Проверьте, есть ли у него правильное разрешение. будет логика для реализации. Что вы думаете об этом? Еще раз спасибо:)

2. @Gipyo. Чой, проверь обновление.