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

时间:2012-06-04 09:32:28

标签: sql-server

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

用户拥有姓名和密码,然后用户可以拥有多个角色,例如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

如果是,为什么?

5 个答案:

答案 0 :(得分:8)

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

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

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

也...

  • 如果passwordnvarchar(50),则表示纯文本。 This is bad.
  • 如果name中有Users个重复值,您如何知道哪个用户是哪个?
    特别是如果他们有相同的密码(这将发生因为我们的meatsacks是愚蠢的)

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

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