Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 在Sql中按数字限制多对多关系_Mysql_Sql - Fatal编程技术网

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?