RDBMS 中“OneOf”关系的最佳模式
Best schema for `OneOf` relationship in RDBMS
假设有 3 种类型的管理员,
- 服务管理员
- 项目管理员
- 项目团队管理员
和table如下,
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
的最佳模式是什么 [= =59=]?
猜猜下面有table个,
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种可能的情况,
- 服务管理员(用户管理):{ userid: 1, isServiceAdmin: true }
- 项目管理员:{ userid: 2, isProjectAdmin: true, admProjectId: 1000 }
- 团队管理员:{ userid:3,isTeamAdmin:true,teamId:100}
但这看起来很糟糕,也不是 RDBMS 的本意。
总而言之,架构如下所示,
用户可以拥有不同类型的 AdminPreviliges
,这取决于它的特权类别,例如 ServiceAdmin
、ProjectAdmin
、TeamAdmin
。
如何定义 table 可以根据特定类别改变其信息的信息?
唯一的方法就是分别定义 ServiceAdminInfo
、ProjectAdminInfo
、TeamAdminInfo
?
也许您正在寻找用户会员设计。
基本设计应该是这样的:
Users > Roles (Groups) > Privileges (Permissions)
因此,您可以使用 Roles
为每个使用类型创建角色,例如 Admin
、Project
..等。并使用Privileges
来定义每个角色的权限(基本可以是SELECT
、INSERT
、DELETE
)
您最不需要的就是 link 他们与 one-to-many
关系。 (每个用户可以有一个或多个角色,每个角色可以有一个或多个权限)。
从那里您可以将您的设计扩展到您认为适合您当前业务的地方。
更新评论
There are several groups, and privileges are differ from each groups
per user." In this case, how can I resolve it?
您 link Groups
、Permissions
和 Users
与 table 使用他们的外键。
喜欢
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
是 table,您可以在其中存储两者的定义。而 GroupPermissions
和 GroupUsers
是 table 存储 assigned
完整性的地方。但是,GroupPermissionUsers
是 table,您实际上会在其中检查每个用户以获取用户组和权限。因此,当用户尝试做某事时,您需要验证 his/her 权限,您只需使用 GroupPermissionUsers
获取分配的权限,并根据您分配给的对象权限验证它们。
假设有 3 种类型的管理员,
- 服务管理员
- 项目管理员
- 项目团队管理员
和table如下,
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
的最佳模式是什么 [= =59=]?
猜猜下面有table个,
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种可能的情况,
- 服务管理员(用户管理):{ userid: 1, isServiceAdmin: true }
- 项目管理员:{ userid: 2, isProjectAdmin: true, admProjectId: 1000 }
- 团队管理员:{ userid:3,isTeamAdmin:true,teamId:100}
但这看起来很糟糕,也不是 RDBMS 的本意。
总而言之,架构如下所示,
用户可以拥有不同类型的 AdminPreviliges
,这取决于它的特权类别,例如 ServiceAdmin
、ProjectAdmin
、TeamAdmin
。
如何定义 table 可以根据特定类别改变其信息的信息?
唯一的方法就是分别定义 ServiceAdminInfo
、ProjectAdminInfo
、TeamAdminInfo
?
也许您正在寻找用户会员设计。
基本设计应该是这样的:
Users > Roles (Groups) > Privileges (Permissions)
因此,您可以使用 Roles
为每个使用类型创建角色,例如 Admin
、Project
..等。并使用Privileges
来定义每个角色的权限(基本可以是SELECT
、INSERT
、DELETE
)
您最不需要的就是 link 他们与 one-to-many
关系。 (每个用户可以有一个或多个角色,每个角色可以有一个或多个权限)。
从那里您可以将您的设计扩展到您认为适合您当前业务的地方。
更新评论
There are several groups, and privileges are differ from each groups per user." In this case, how can I resolve it?
您 link Groups
、Permissions
和 Users
与 table 使用他们的外键。
喜欢
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
是 table,您可以在其中存储两者的定义。而 GroupPermissions
和 GroupUsers
是 table 存储 assigned
完整性的地方。但是,GroupPermissionUsers
是 table,您实际上会在其中检查每个用户以获取用户组和权限。因此,当用户尝试做某事时,您需要验证 his/her 权限,您只需使用 GroupPermissionUsers
获取分配的权限,并根据您分配给的对象权限验证它们。