如何避免MySQL复合主键排列? 创建表朋友\u关系( buddy_id VARCHAR(255)不为空, mate_id VARCHAR(255)不为空, 主键(伙伴id、伙伴id), 外键(buddy_id)引用删除级联上的用户(id), 外键(mate_id)引用删除级联上的用户(id) );

如何避免MySQL复合主键排列? 创建表朋友\u关系( buddy_id VARCHAR(255)不为空, mate_id VARCHAR(255)不为空, 主键(伙伴id、伙伴id), 外键(buddy_id)引用删除级联上的用户(id), 外键(mate_id)引用删除级联上的用户(id) );,mysql,sql,unique-constraint,Mysql,Sql,Unique Constraint,有一种相互的友谊关系,(朋友A,朋友B)和(朋友B,朋友A)是一样的 我已尝试添加唯一密钥,但无效: altertablefriends\u关系添加唯一键(mate\u id,buddy\u id); 有没有办法避免这些排列?您可以: create table friends_relations ( buddy_id varchar(255) not null, mate_id varchar(255) not null, constraint uq1 unique ( (

有一种相互的友谊关系,(朋友A,朋友B)和(朋友B,朋友A)是一样的

我已尝试添加唯一密钥,但无效:

altertablefriends\u关系添加唯一键(mate\u id,buddy\u id);
有没有办法避免这些排列?

您可以:

create table friends_relations (
  buddy_id varchar(255) not null,
  mate_id varchar(255) not null,
  constraint uq1 unique (
    (least(buddy_id, mate_id)), (greatest(buddy_id, mate_id))
  ),
  primary key (buddy_id, mate_id)
);
CREATE TABLE Friends_Relations (
    buddy_id VARCHAR(255) NOT NULL,
    mate_id VARCHAR(255) NOT NULL,
    PRIMARY KEY (buddy_id, mate_id),
    FOREIGN KEY (buddy_id) REFERENCES Users(id) ON DELETE CASCADE,
    FOREIGN KEY (mate_id) REFERENCES Users(id) ON DELETE CASCADE,
    constraint ck1 CHECK (buddy_id < mate_id) -- added constraint
);
然后,如果它不接受对称行:

insert into friends_relations (buddy_id, mate_id) values (456, 123);
insert into friends_relations (buddy_id, mate_id) values (123, 456); -- fails
请参阅上的运行示例

还有一个窍门。您也可以执行
buddy\u id
。但是,这将限制插入数据的方式。例如,您可以执行以下操作:

create table friends_relations (
  buddy_id varchar(255) not null,
  mate_id varchar(255) not null,
  constraint uq1 unique (
    (least(buddy_id, mate_id)), (greatest(buddy_id, mate_id))
  ),
  primary key (buddy_id, mate_id)
);
CREATE TABLE Friends_Relations (
    buddy_id VARCHAR(255) NOT NULL,
    mate_id VARCHAR(255) NOT NULL,
    PRIMARY KEY (buddy_id, mate_id),
    FOREIGN KEY (buddy_id) REFERENCES Users(id) ON DELETE CASCADE,
    FOREIGN KEY (mate_id) REFERENCES Users(id) ON DELETE CASCADE,
    constraint ck1 CHECK (buddy_id < mate_id) -- added constraint
);


这允许按任意顺序进行配对,但仍然只有一次。

最简单的方法可能是使用触发器添加反向关系。拥有两个方向通常有助于查询……使用标志来识别真实关系(有时很重要)检查约束是一个优雅的解决方案(它还通过强制一个值小于另一个值来强制执行某种数据完整性)。应该注意的是,它只在MySQL的最新版本中可用(如果我没记错的话,是8.0.13)。在早期版本中,检查约束的解析没有错误,但被忽略(这相当棘手)。关闭-