我想设计一个用户/角色系统:
用户拥有姓名和密码,然后用户可以拥有多个角色,例如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)
)
user_roles:
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
如果是,为什么?
答案 0 :(得分:8)
不太清楚你的意思,但......
User_Roles
应该只有2列User_id
和Role_id
User_Roles
User_id
是Users.id
Role_id
是Roles.id
编辑:现在我明白了。是的,always use foreign keys
也...
password
是nvarchar(50)
,则表示纯文本。 This is bad. name
中有Users
个重复值,您如何知道哪个用户是哪个? 创建主键后评论后编辑...
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])
)
答案 1 :(得分:1)
Spring Security提出documentation建议:
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);
答案 2 :(得分:0)
当数据为关系建模时,始终使用外键。在您的示例中,如果您不创建外键,则不会阻止您(或其他有权访问数据库的人)错误地(或故意)删除当前使用的角色。
假设您有很多用户和一些角色。其中一个角色称为“管理员”,在您的应用程序中是必需的,以便执行某些任务。如果您没有设置外键,数据库中没有任何内容可以防止有人删除管理员角色,将您的应用程序归档到:
如果您设置了外键,如果您尝试删除当前分配给某个用户的角色(通过User_Roles表),则会从数据库收到错误。
答案 3 :(得分:0)
与@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
答案 4 :(得分:0)
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)
);