简体   繁体   English

如何在postgres的多个表中定义多个列的唯一约束?

[英]How to define unique constraint on multiple columns in multiple tables in postgres?

I have some tables, let's say 2 for simplicity:我有一些表,为了简单起见,我们说 2:

CREATE TABLE A (
    name varchar
    ...
);
CREATE TABLE B (
    name varchar
    ...
);

These tables have different structures but all have the same column ( name )这些表具有不同的结构,但都具有相同的列( name

I want to add a unique constraint on all of these columns in all of these tables.我想在所有这些表中的所有这些列上添加一个唯一约束。

How can I do this?我怎样才能做到这一点? This seems like a simple thing but my googling haven't proven successful so far.这似乎是一件简单的事情,但到目前为止我的谷歌搜索还没有被证明是成功的。 Most existing questions seem to deal with multiple columns in the same table.大多数现有问题似乎都处理同一张表中的多个列。

Since UNIQUE constraints cannot span multiple tables, you'll need to create an extra table to store all the names.由于UNIQUE约束不能跨越多个表,因此您需要创建一个额外的表来存储所有名称。 Then each table will have a foreign key against the extra table.然后每个表都会有一个针对额外表的外键。

For example:例如:

create table all_names (
  zone int not null,
  name varchar(20) not null,
  constraint uq1 unique (zone, name),
  constraint uq2 unique (name) -- this is the critical constraint!
);

create table a (
  zone int not null default 1 check (zone = 1),
  name varchar(20) not null,
  constraint fk1 foreign key (zone, name) references all_names (zone, name)
);

insert into all_names (zone, name) values (1, 'Jenny'); -- succeeds
insert into a (name) values ('Jenny'); -- succeeds

create table b (
  zone int not null default 2 check (zone = 2),
  name varchar(20) not null,
  constraint fk2 foreign key (zone, name) references all_names (zone, name)
);

insert into all_names (zone, name) values (2, 'Ivan'); -- succeeds
insert into b (name) values ('Ivan'); -- succeeds

insert into all_names (zone, name) values (2, 'Jenny'); -- fails!
insert into b (name) values ('Jenny'); -- fails!

Note that each insert now requires an extra insert in the extra all_names table.请注意,现在每个插入都需要在额外的all_names表中进行额外的插入。 This can, however, be automated (and happen behind the scenes) by the use of a pre/post-insert trigger (not shown).然而,这可以通过使用插入前/插入后触发器(未显示)来自动化(并在幕后发生)。

See running example at DB Fiddle .请参阅DB Fiddle上的运行示例。

If you implement a trigger, then your inserts will look simple, as in:如果您实现触发器,那么您的插入将看起来很简单,如下所示:

insert into a (name) values ('Jenny'); -- succeeds
insert into b (name) values ('Ivan'); -- succeeds
insert into b (name) values ('Jenny'); -- fails!

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

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