可互换的复合主键
Interchangeable, composite primary keys
我有一个 table foo
,它只有两个字段:fooIdA
和 fooIdB
(都是同一类型)。这些是复合主键,所以:
primary key (fooIdA, fooIdB)...
考虑到这一点,我怎样才能使键的所有排列都相同?
即(fooIdA, fooIdB) = (fooIdB, fooIdA)
.
根据您的 DBMS,您可以在防止插入 (1,2)
和 (2,1)
的表达式上创建唯一索引
在 Postgres 和 Oracle 中,您可以这样做:
create unique index unique_combinations
on the_table (least(fooida, fooidb), greatest(fooida, fooidb));
您没有指定 RDBMS。您还可以添加具有 MAX、MIN 值的计算字段,并在这些计算字段上添加 UNIQUE 约束。这是 MSSQL 示例:
CREATE TABLE ATest (id1 int, id2 int);
ALTER TABLE ATest ADD idMax AS (CASE WHEN id1>=id2 THEN id1 ELSE id2 END);
ALTER TABLE ATest ADD idMin AS (CASE WHEN id1>=id2 THEN id2 ELSE id1 END);
ALTER TABLE ATest ADD CONSTRAINT UniqueConstCalc UNIQUE(idMax,idMin);
insert into ATest values (1,1);
insert into ATest values (1,2);
insert into ATest values (2,1);
(1 row(s) affected)
(1 row(s) affected)
Msg 2627, Level 14, State 1, Line 3
Violation of UNIQUE KEY constraint 'UniqueConstCalc'.
Cannot insert duplicate key in object 'dbo.ATest'.
The duplicate key value is (2, 1).
The statement has been terminated.
我有一个 table foo
,它只有两个字段:fooIdA
和 fooIdB
(都是同一类型)。这些是复合主键,所以:
primary key (fooIdA, fooIdB)...
考虑到这一点,我怎样才能使键的所有排列都相同?
即(fooIdA, fooIdB) = (fooIdB, fooIdA)
.
根据您的 DBMS,您可以在防止插入 (1,2)
和 (2,1)
在 Postgres 和 Oracle 中,您可以这样做:
create unique index unique_combinations
on the_table (least(fooida, fooidb), greatest(fooida, fooidb));
您没有指定 RDBMS。您还可以添加具有 MAX、MIN 值的计算字段,并在这些计算字段上添加 UNIQUE 约束。这是 MSSQL 示例:
CREATE TABLE ATest (id1 int, id2 int);
ALTER TABLE ATest ADD idMax AS (CASE WHEN id1>=id2 THEN id1 ELSE id2 END);
ALTER TABLE ATest ADD idMin AS (CASE WHEN id1>=id2 THEN id2 ELSE id1 END);
ALTER TABLE ATest ADD CONSTRAINT UniqueConstCalc UNIQUE(idMax,idMin);
insert into ATest values (1,1);
insert into ATest values (1,2);
insert into ATest values (2,1);
(1 row(s) affected)
(1 row(s) affected)
Msg 2627, Level 14, State 1, Line 3
Violation of UNIQUE KEY constraint 'UniqueConstCalc'.
Cannot insert duplicate key in object 'dbo.ATest'.
The duplicate key value is (2, 1).
The statement has been terminated.