我有以下表格
CREATE TABLE [dbo].[User]
(
[Id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY,
[Username] NVARCHAR(200) NOT NULL,
[Domain] NVARCHAR(200) NOT NULL,
[IsAdministrator] BIT NOT NULL DEFAULT 'false',
[IsGroup] BIT NULL DEFAULT 'false',
)
CREATE TABLE [dbo].[Role]
(
[Id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY,
[Name] NVARCHAR(500) NOT NULL,
[Description] NVARCHAR(1000) NOT NULL,
[ResourceType] NVARCHAR(100) NOT NULL,
)
可以为用户分配特定资源的一个或多个角色
例如,
假设有两种类型的资源(Workspace
和Process
)
每种资源类型都有一个表,每种资源的模式都不同(因此我不能使用通用资源表)
CREATE TABLE [dbo].[Workspace]
(
[WorkspaceId] UNIQUEIDENTIFIER NOT NULL,
[WorkspaceName] NVARCHAR(100) NOT NULL,
[Description] NVARCHAR(500) NULL,
CONSTRAINT [UC_WorkspaceName] UNIQUE([WorkspaceName]),
CONSTRAINT [PK_Workspace] PRIMARY KEY([WorkspaceId])
)
CREATE TABLE [dbo].[Process]
(
[ProcessId] UNIQUEIDENTIFIER NOT NULL ,
[ProcessName] NVARCHAR(100) NOT NULL,
CONSTRAINT [PK_BusinessProcessId] PRIMARY KEY ([ProcessId]),
)
但无论资源类型如何,主键始终为UNIQUEIDENTIFIER
。
每个用户可以为特定的ResourceId和ResourceType
分配一个或多个角色CREATE TABLE [dbo].[UserRole]
(
[UserId] UNIQUEIDENTIFIER NOT NULL,
[RoleId] UNIQUEIDENTIFIER NOT NULL,
[ResourceType] NVARCHAR(100) NOT NULL,
[ResourceId] UNIQUEIDENTIFIER NOT NULL,
CONSTRAINT [PK_User_Role] PRIMARY KEY (ResourceId, UserId, RoleId, ResourceType),
CONSTRAINT [FK_UserId] FOREIGN KEY ([UserId]) REFERENCES [User]([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [Role]([Id]) ON DELETE CASCADE
)
但是使用此设计,我无法将UserRole.ResourceId
设置为外键,因为它可能来自WorkspaceId
表Workspace
或来自{ProcessId
Process
1}}表。
这在资源删除期间成为一个问题,因为我必须手动删除过时的条目。
我知道我可以在UserRole
中有两列名为WorkspaceId
和ProcessId
,根据资源类型设置NULL
,但在我的情况下,资源类型的数量将会非常大。
我的问题是,
还有其他方法我不必为每种新资源类型添加一列,还是应该使用当前设计(没有外键)?
答案 0 :(得分:0)
我将工作空间和流程组合到一个表中,并将它们链接到ResourceType表。
CREATE TABLE [dbo].[User]
(
[Id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY,
[Username] NVARCHAR(200) NOT NULL,
[Domain] NVARCHAR(200) NOT NULL,
[IsAdministrator] BIT NOT NULL DEFAULT 'false',
[IsGroup] BIT NULL DEFAULT 'false',
)
CREATE TABLE [dbo].[ResourceType]
(
[Id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY,
[Description] NVARCHAR(100)
)
CREATE TABLE [dbo].[Role]
(
[Id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY,
[Name] NVARCHAR(500) NOT NULL,
[Description] NVARCHAR(1000) NOT NULL,
[ResourceType_id] UNIQUEIDENTIFIER NOT NULL
)
CREATE TABLE [dbo].[Resource]
(
[ResourceId] UNIQUEIDENTIFIER NOT NULL,
[ResourceName] NVARCHAR(100) NOT NULL,
[Description] NVARCHAR(500) NULL,
[ResourceType_id] UNIQUEIDENTIFIER NOT NULL,
CONSTRAINT [UC_ResourceName] UNIQUE([ResourceName]),
CONSTRAINT [PK_Resource] PRIMARY KEY([ResourceId])
)
CREATE TABLE [dbo].[UserRole]
(
[UserId] UNIQUEIDENTIFIER NOT NULL,
[RoleId] UNIQUEIDENTIFIER NOT NULL,
[ResourceType] NVARCHAR(100) NOT NULL,
[ResourceId] UNIQUEIDENTIFIER NOT NULL,
CONSTRAINT [PK_User_Role] PRIMARY KEY (ResourceId, UserId, RoleId, ResourceType),
CONSTRAINT [FK_UserId] FOREIGN KEY ([UserId]) REFERENCES [User]([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [Role]([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_ResourceId] FOREIGN KEY ([ResourceId]) REFERENCES [Resource]([ResourceId]) ON DELETE CASCADE
)