Mysql 在Sql中按数字限制多对多关系
三个表:用户、角色和数据透视表(多对多)角色\用户Mysql 在Sql中按数字限制多对多关系,mysql,sql,Mysql,Sql,三个表:用户、角色和数据透视表(多对多)角色\用户 user: - id - name role: - id - name role_user - id - user_id: foreign key link to user - role_id: foreign key link to role 例如,如果我想将用户可以拥有的最大角色数量限制为1,我可以将用户上的role_id外部链接作为role_1字段,而不是使用多对多的透视表 users: - id - name - role_id
user:
- id
- name
role:
- id
- name
role_user
- id
- user_id: foreign key link to user
- role_id: foreign key link to role
例如,如果我想将用户可以拥有的最大角色数量限制为1,我可以将用户上的role_id外部链接作为role_1字段,而不是使用多对多的透视表
users:
- id
- name
- role_id_1
如果每个用户只需要两个角色,情况也是一样的
users:
- id
- name
- role_id_1
- role_id_2
如果我想使用透视表(不使用用户表上的外部角色链接)将数量限制为1、2或其他什么,该怎么办?在sql中有这样的选项吗
类似于复合唯一索引选项,包括透视表中的角色id和用户id,但不是对唯一性的约束,而是对用户id出现次数的限制的自定义约束 有一种方法可以在不使用触发器的SQL中实现这一点。这有点复杂,但你可以做到 它首先添加另一个表。让我称之为
RoleNumbers
。此表将由一个用户的每个可能角色的一行组成。因此,您可以将其设置为1个、2个或任意多个角色
然后,对于连接表:
create table UserRoles (
UserRoleId int not null auto_increment primary key,
UserId int not null references users(user_id),
RoleId int not null references roles(role_id),
RoleNumber int not null references RoleNumbers(Number),
unique (UserId, RoleId),
unique (UserId, RoleNumber)
);
这使用了我的命名约定。我对在连接表上使用合成键没有问题
插入新记录时,必须为RoleNumber
分配一个尚未使用的值。因此,你得到了限制。最有效的方法是通过触发器,但这并不是绝对必要的。您可以按以下方式进行插入:
insert into UserRoles(UserId, RoleId, RoleNumber)
select $UserId, $RoleId, coalesce(max(RoleNumber), 0) + 1
from UserRoles
where UserId = $UserId;
delete
需要一个单独的查询来维护编号方案。这通常使用触发器来完成(因为大多数DBMS不支持必要的复杂检查约束)。顺便说一句,向users表中添加两个role_ID将违反第一个正常形式,永远不要这样做。另外,role\u user
表(不是透视表,它是连接或交叉引用表)不需要无用的id
列,有一个主键(user\u id,role\u id)感谢触发器引用。这是一种创新的方法。如果我理解正确,UserRoles中的RoleNumber和UserId列应该是唯一的,RoleNumber表表示用户的抽象角色可能性。行数表示所需的最大角色数。这是正确的吗?在此基础上,我是否可以放弃RoleNumber表并在UserRoles表中使用enum RoleNumber列,该列将通过检查约束进行检查,例如“check(RoleNumber<2)”?RoleNumber int not null distinct references RoleNumber(Number),
我从未见过distinct
语法,它是如何工作的,哪些DBMS支持它?当然,您也可以执行RoleNumber int not null检查(RoleNumber介于1和2之间)
并添加另一个unique(UserId、RoleId、RoleNumber)
。但无论如何,维护都会很糟糕。@dnoeth。这应该是唯一的。至于check
约束,这是一个好主意,但是MySQL实际上不做检查。但是unique
是一个不允许多行具有相同值的约束,那么它在这里应该如何工作呢?还是mysql(再次)没有遵循标准SQL?