三个表:用户,角色和数据透视表(多对多)role_user。
user:
- id
- name
role:
- id
- name
role_user
- id
- user_id: foreign key link to user
- role_id: foreign key link to role
如果我想限制用户可以拥有的最大角色数量,例如,我可以将role_id外部链接作为role_1字段放在用户上,而不是使用多对多的数据透视表。
users:
- id
- name
- role_id_1
如果我每个用户只需要两个角色,那也是如此。
users:
- id
- name
- role_id_1
- role_id_2
如果我想使用数据透视表将数量限制为1,2或其他内容(不在用户表上使用外部角色链接),该怎么办?在sql中有一个选项吗?
类似于复合唯一索引选项,包括数据透视表中的role_id和user_id,但不是对唯一性的约束,而是对user_id出现次数限制的自定义约束。
答案 0 :(得分:3)
有一种方法可以在没有触发器的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
需要单独的查询来维护编号方案。