简体   繁体   English

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

[英]How to enforce a ‘unique’ combination check constraint on two columns but still allow duplicates in PostgreSQL?

I have a table, say: 我有一张桌子,说:

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

How do I enforce a check such that the second column is 'unique' with respect to the first column, but duplicate values are allowed? 如何执行检查,以使第二列相对于第一列为“唯一”,但允许重复值? In other words, only allow one value in the 'second' for each of the 'first' column values. 换句话说,对于“第一”列的每个值,在“第二”中仅允许一个值。 Once a value has been inserted into column 'first', only additional values that match the existing (first, second) column combination can be inserted again. 将值插入“第一”列后,只能再次插入与现有(第一,第二)列组合匹配的其他值。

For example, given: 例如,给定:

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

A constraint violation for: 违反约束条件:

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

would occur, but 会发生,但是

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

or 要么

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

or 要么

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

would succeed. 会成功。

The problem is that you need two tables. 问题是您需要两个表。 You are trying to carry information from one row to another -- but that is a bad idea. 您正在尝试将信息从一行传送到另一行-但这是一个坏主意。 I'm guessing you really have two entities and just don't want to admit it. 我猜您确实有两个实体,只是不想承认这一点。

So: 所以:

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
);

These tables have the semantics you want. 这些表具有所需的语义。

Of course, you can also use a composite primary key for the first table: 当然,您也可以为第一个表使用复合主键:

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)
);

Composite Primary Key if you are looking for combination. 复合主键(如果您正在寻找组合)。

Definition : 定义:

Combination of two or more columns in a table that can be used to uniquely identify each row in the table. 表中两个或更多列的组合,可用于唯一标识表中的每一行。

The demo = Demo 演示= 演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM