2 列的独特组合,与顺序无关
Unique combination of 2 columns, order independent
我有一个这样的table,代表社交网络中人与人之间的友谊
CREATE TABLE friendships
(
requester INT,
acceptor INT
);
现在我想要(请求者、接受者)的唯一组合,与顺序无关。普通的唯一约束 UNIQUE (requester, acceptor)
对于这种情况是不够的,因为如果已经有一行包含组合 (1, 2) 组合 (2, 1) 仍然是允许的,我不会我不想那样。
如何解决?我正在使用 MySQL.
一个简单的方法是:
create table friendships (
requester int,
acceptor int,
check(requester < acceptor),
unique (requester, acceptor)
);
使用此设置,您无法插入类型 (2, 1)
。您需要使其成为 (1, 2)
,并且唯一约束可防止重复。
如果您想要更灵活的东西,另一种解决方案是使用生成的列,这些列在最近的 MySQL 版本中可用:
create table friendships (
requester int,
acceptor int,
v1 int generated always as (least(requester, acceptor)),
v2 int generated always as (greatest(requester, acceptor)),
unique (v1, v2)
);
这让您可以插入 (2, 1)
或 (1, 2)
;一旦元组被插入,另一个就不能。
insert into friendships(requester, acceptor) values(2, 1);
-- ok
insert into friendships(requester, acceptor) values(1, 2);
-- ERROR: Duplicate entry '1-2' for key 'friendships.v1'
从 MySQL 8.0.13 开始,您可以在表达式上创建索引。这使您可以:
create unique index unq_friendships_requestor_acceptor on
friendships( (least(requestor, acceptor)) , (greatest(requestor, acceptor)) );
您还应该将这两列声明为 NOT NULL
。
对于旧版本。 GMB 的回答是恰当的。
我有一个这样的table,代表社交网络中人与人之间的友谊
CREATE TABLE friendships
(
requester INT,
acceptor INT
);
现在我想要(请求者、接受者)的唯一组合,与顺序无关。普通的唯一约束 UNIQUE (requester, acceptor)
对于这种情况是不够的,因为如果已经有一行包含组合 (1, 2) 组合 (2, 1) 仍然是允许的,我不会我不想那样。
如何解决?我正在使用 MySQL.
一个简单的方法是:
create table friendships (
requester int,
acceptor int,
check(requester < acceptor),
unique (requester, acceptor)
);
使用此设置,您无法插入类型 (2, 1)
。您需要使其成为 (1, 2)
,并且唯一约束可防止重复。
如果您想要更灵活的东西,另一种解决方案是使用生成的列,这些列在最近的 MySQL 版本中可用:
create table friendships (
requester int,
acceptor int,
v1 int generated always as (least(requester, acceptor)),
v2 int generated always as (greatest(requester, acceptor)),
unique (v1, v2)
);
这让您可以插入 (2, 1)
或 (1, 2)
;一旦元组被插入,另一个就不能。
insert into friendships(requester, acceptor) values(2, 1);
-- ok
insert into friendships(requester, acceptor) values(1, 2);
-- ERROR: Duplicate entry '1-2' for key 'friendships.v1'
从 MySQL 8.0.13 开始,您可以在表达式上创建索引。这使您可以:
create unique index unq_friendships_requestor_acceptor on
friendships( (least(requestor, acceptor)) , (greatest(requestor, acceptor)) );
您还应该将这两列声明为 NOT NULL
。
对于旧版本。 GMB 的回答是恰当的。