如何在两列上强制执行“唯一”组合检查约束,但在PostgreSQL中仍然允许重复?

时间:2018-12-12 01:16:18

标签: sql postgresql constraints unique-constraint check-constraints

我有一张桌子,说:

CREATE TABLE test (
    id SERIAL UNIQUE,
    first integer NOT NULL,
    second integer NOT NULL,
    data text NOT NULL
);

如何执行检查,使第二列相对于第一列为“唯一”,但允许重复值?换句话说,对于每个“第一”列值,在“第二”中只允许一个值。将值插入“第一”列后,只能再次插入与现有(第一,第二)列组合匹配的其他值。

例如,给定:

INSERT INTO test (first, second, data) VALUES (1, 2, 'test');

违反约束:

INSERT INTO test (first, second, data) VALUES (1, 3, 'testing');

会发生,但是

INSERT INTO test (first, second, data) VALUES (1, 2, 'testing');

INSERT INTO test (first, second, data) VALUES (2, 1, 'testing');

INSERT INTO test (first, second, data) VALUES (2, 2, 'testing');

会成功。

2 个答案:

答案 0 :(得分:1)

问题是您需要两个表。您正在尝试将信息从一行传送到另一行-但这是一个坏主意。我猜您确实有两个实体,只是不想承认。

所以:

CREATE TABLE firstSecond (
    firstSecondId SERIAL PRIMARY KEY,
    first integer NOT NULL,
    second integer NOT NULL,
    constraint unq_firstSecond_first_second unique (first, second)
);

CREATE TABLE test (
    testId SERIAL PRIMARY KEY,
    firstSecondId int not null references firstSecond(firstSecondId),
    data text NOT NULL
);

这些表具有您想要的语义。

当然,您也可以为第一个表使用复合主键:

CREATE TABLE firstSecond (
    first integer NOT NULL,
    second integer NOT NULL,
    primary key (first, second)
);

CREATE TABLE test (
    testId SERIAL PRIMARY KEY,
    first int not null,
    second int not null,
    data text NOT NULL,
    foreign key (first, second) references firstSecond(first, second)
);

答案 1 :(得分:0)

复合主键(如果您要查找组合)。

定义:

  

表中两个或多个列的组合,可用于   唯一标识表中的每一行。

演示= Demo