How to design a user/role schema in a SQL Server database?
我想设计一个用户/角色系统:
用户有一个名字和一个密码,然后用户可以有几个角色,如
为此,我创建了如下模式:
用户:
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 和Role_id 。这两个都构成了主键- 您不需要额外的ID列
User_Roles User_id 是Users.id 的外键。Role_id 是Roles.id 的外键。
编辑:现在我明白了。是的,一定要用外国钥匙
也。。。
- 如果
password 是nvarchar(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",在应用程序中是执行某些任务所必需的。如果没有设置外键,则数据库中没有任何内容可以阻止某人删除管理角色,将应用程序设置为:
- 可能会崩溃,因为它将查找不再在数据库中的角色
- 如果不是以上所述,那么至少没有用户具有"管理员"角色,在需要时关闭应用程序的各个部分。
另一方面,如果已经设置了外键,则如果试图删除当前分配给某个用户的角色(通过"用户角色"表),则将从数据库中收到错误。