如何在SQL Server数据库中设计用户/角色架构?

How to design a user/role schema in a SQL Server database?

我想设计一个用户/角色系统:

用户有一个名字和一个密码,然后用户可以有几个角色,如Admin

为此,我创建了如下模式:

用户:

1
2
3
4
5
6
7
8
CREATE TABLE [dbo].[Users]
(
    [id] [int] NOT NULL,
    [name] [nvarchar](50) NULL,
    [password] [nvarchar](50) NULL,

    CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED ([id] ASC)
)

角色:

1
2
3
4
5
6
7
CREATE TABLE [dbo].[Roles]
(
    [id] [int] NOT NULL,
    [name] [nvarchar](50) NULL,

    CONSTRAINT [PK_Roles] PRIMARY KEY CLUSTERED ([id] ASC)
)

用户角色:

1
2
3
4
5
6
7
8
CREATE TABLE [dbo].[User_Roles]
(
    [id] [int] NOT NULL,
    [User_id] [int] NOT NULL,
    [Role_id] [int] NOT NULL,

    CONSTRAINT [PK_User_Roles] PRIMARY KEY CLUSTERED ([id] ASC)
)

我的问题是:我应该使用外键User_Roles.User_id -> User.Id吗?

如果是,为什么?


不太清楚你的意思,但是…

  • User_Roles只应有两列User_idRole_id。这两个都构成了主键
  • 您不需要额外的ID列User_Roles
  • User_idUsers.id的外键。
  • Role_idRoles.id的外键。

编辑:现在我明白了。是的,一定要用外国钥匙

也。。。

  • 如果passwordnvarchar(50),这意味着纯文本。这很糟糕。
  • 如果在Users中有重复的name值,您如何知道哪个用户是哪个用户?尤其是如果他们有相同的密码(这会发生,因为我们肉袋是愚蠢的)

创建主键后在注释后编辑…

1
2
3
4
5
6
7
8
CREATE TABLE [dbo].[User_Roles]
(
    [User_id] [int] NOT NULL,
    [Role_id] [int] NOT NULL,

    CONSTRAINT [PK_User_Roles] PRIMARY KEY CLUSTERED ([User_id], [Role_id]),
    CONSTRAINT [UQ_ReversePK] UNIQUE ([Role_id], [User_id])
)


Spring Security提出以下建议:

1
2
3
4
5
6
7
8
9
10
11
12
create table users(
    username varchar_ignorecase(50) not null primary key,
    password varchar_ignorecase(50) not null,
    enabled boolean not null
);

create table authorities (
    username varchar_ignorecase(50) not null,
    authority varchar_ignorecase(50) not null,
    constraint fk_authorities_users foreign key(username) references users(username)
);
create unique index ix_auth_username on authorities (username,authority);


与@gbn稍有不同的最佳方法之一是:

我希望这对你或其他人有帮助

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
CREATE TABLE [dbo].[UserRoles](
    [roleId] [int] NOT NULL,
    [userId] [int] NOT NULL,
    [CreateDate] [datetime] NULL,
    [CreateUser] [nvarchar](30) NULL,
    [ModifyDate] [datetime] NULL,
    [ModifyUser] [nvarchar](30) NULL,
 CONSTRAINT [PK_User_Roles] PRIMARY KEY CLUSTERED
(
    [roleId] ASC,
    [userId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
 CONSTRAINT [UQ_ReversePK] UNIQUE NONCLUSTERED
(
    [roleId] ASC,
    [userId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[UserRoles] ADD  CONSTRAINT [DF_UserRoles_ModifyDate]  DEFAULT (getdate()) FOR [ModifyDate]
GO

ALTER TABLE [dbo].[UserRoles]  WITH CHECK ADD  CONSTRAINT [FK_UserRoles_roleId] FOREIGN KEY([roleId])
REFERENCES [dbo].[Roles] ([roleId])
GO

ALTER TABLE [dbo].[UserRoles] CHECK CONSTRAINT [FK_UserRoles_roleId]
GO

ALTER TABLE [dbo].[UserRoles]  WITH CHECK ADD  CONSTRAINT [FK_UserRoles_userId] FOREIGN KEY([userId])
REFERENCES [dbo].[Users] ([uId])
GO

ALTER TABLE [dbo].[UserRoles] CHECK CONSTRAINT [FK_UserRoles_userId]
GO

数据建模关系时始终使用外键。在示例中,如果不创建外键,则不会阻止您(或具有数据库访问权限的其他人)错误(或故意)删除当前使用的角色。

假设您有许多用户和一些角色。其中一个角色称为"admin",在应用程序中是执行某些任务所必需的。如果没有设置外键,则数据库中没有任何内容可以阻止某人删除管理角色,将应用程序设置为:

  • 可能会崩溃,因为它将查找不再在数据库中的角色
  • 如果不是以上所述,那么至少没有用户具有"管理员"角色,在需要时关闭应用程序的各个部分。

另一方面,如果已经设置了外键,则如果试图删除当前分配给某个用户的角色(通过"用户角色"表),则将从数据库中收到错误。