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

Posted

技术标签:

【中文标题】如何在 SQL Server 数据库中设计用户/角色架构?【英文标题】:How to design a user/role schema in a SQL Server database? 【发布时间】:2012-06-08 09:33:57 【问题描述】:

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

用户拥有名称和密码,然后用户可以拥有多个角色,例如Admin

为此,我创建了这样的架构:

用户:

CREATE TABLE [dbo].[Users]
(
    [id] [int] NOT NULL,
    [name] [nvarchar](50) NULL,
    [password] [nvarchar](50) NULL,

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

角色:

CREATE TABLE [dbo].[Roles]
(
    [id] [int] NOT NULL,
    [name] [nvarchar](50) NULL,

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

用户角色:

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

如果是,为什么?

【问题讨论】:

是的! 当然你应该有外键。你为什么问?? FK 有助于确保数据一致性 - 如果没有 FK,您可以将任何类型的 id 存储到您的 user_roles 表中 - 无需检查它们是否引用有效的用户和/或角色 - 这不是您想要的去做(而不是你以后想清理的事情!) 【参考方案1】:

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

User_Roles 应该只有 2 列 User_idRole_id 这两者都构成了主键 您不需要额外的 id 列 User_Roles User_idUsers.id 的外键 Role_idRoles.id 的外键

编辑:现在我明白了。是的,always use foreign keys

还有……

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

主键创建后评论后编辑...

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])
)

【讨论】:

密码和用户名仅用于演示,不是纯文本。我的重点是角色系统 user_roles中如何设置主键? 为什么首先使用User_Roles association table? Users.idRoles 表中存在作为外键还不够吗? @Jens:用户可以有多个角色,角色可以有多个用户?您的建议意味着“每个角色只有一个用户”【参考方案2】:

Spring Security 提出this 推荐:

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);

【讨论】:

【参考方案3】:

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

假设您有很多用户和几个角色。其中一个角色称为“管理员”,在您的应用程序中需要它才能执行某些任务。如果您没有设置外键,则数据库中没有任何内容可以阻止某人删除管理员角色,从而导致您的应用程序:

可能会崩溃,因为它会寻找不再在数据库中的角色 如果不是上述情况,那么至少没有用户将拥有“管理员”角色,从而关闭需要它的应用程序部分

另一方面,如果您已经设置了外键,如果您尝试删除当前分配给某个用户的角色(通​​过 User_Roles 表),您将收到来自数据库的错误。

【讨论】:

【参考方案4】:

与@GBN 略有不同的最佳方法之一是:

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

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

【讨论】:

【参考方案5】:

users_roles 表应包含每个用户及其角色之间的映射。每个用户可以有多个角色,每个角色可以有多个用户:

TABLE users
  id INTEGER NOT NULL PRIMARY KEY,
  userName VARCHAR(50) NOT NULL

TABLE roles
  id INTEGER NOT NULL PRIMARY KEY,
  role VARCHAR(20) NOT NULL

CREATE TABLE users_roles (
  userId INTEGER NOT NULL,
  roleId INTEGER NOT NULL,
  primary key (userId, roleId),
  foreign key (userId) references users(id),
  foreign key (roleId) references roles(id)
);

【讨论】:

以上是关于如何在 SQL Server 数据库中设计用户/角色架构?的主要内容,如果未能解决你的问题,请参考以下文章

如何在efcore中设计一对多关系?

链接到 SQL Server 的 Active Directory

如何将数据库从mysql工作台导出到sql server

如何在 reduxjs 中设计独立模块?

在 ASP.Net 中设计网站 - 用户登录设计和注意事项

如何在salesforce中设计dashboard