8

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

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

如果是,为什么?

4

5 回答 5

10

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

  • User_Roles应该只有 2 列User_idRole_id
    这两列都构成主键
  • 您不需要额外的 id 列User_Roles
  • User_id是一个外键Users.id
  • Role_id是一个外键Roles.id

编辑:现在我明白了。是的,总是使用外键

还...

  • 如果passwordnvarchar(50),这意味着纯文本。这很糟糕
  • 如果你有重复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])
)
于 2012-06-04T09:41:48.560 回答
1

Spring Security 提出以下建议:

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);
于 2015-05-18T20:00:15.383 回答
0

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

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

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

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

于 2012-06-04T11:34:50.480 回答
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
于 2018-03-25T07:34:22.390 回答
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)
);
于 2019-08-14T09:13:47.460 回答