我查看了PostgreSQL的INSERT INTO .. ON CONFLICT (..) DO UPDATE ..
语法并意识到,您不能使用它进行多个唯一的约束检查。我的意思是,您可以通过列名引用复合唯一索引ON CONFLICT (Name, Symbol)
(如果为这两列定义了唯一索引),或者您可以使用主键。如果为列定义两个单独的唯一索引,则只能检查一个。
CREATE TABLE student
(Id int primary key, Name varchar(50), Symbol varchar(50),
CONSTRAINT col1_unique UNIQUE (Name),
CONSTRAINT col2_unique UNIQUE (Symbol)
);
INSERT INTO student
(Id, Name, Symbol)
VALUES
(1, 'John', 'J'),
(2, 'David', 'D'),
(3, 'Will', 'W');
INSERT INTO student
(Id, Name, Symbol)
VALUES
(4, 'Jeremy', 'J')
on conflict(Name) DO UPDATE
set Name = 'Jeremy';
可能抛出错误,说J
是重复的。但是,此示例的设计很糟糕,因为Symbol应该位于另一个表中,并通过一对多关系连接到Student表。这就是为什么我想知道,也许PostgreSQL on conflict
是按这种方式设计的,因为您总是可以以只有一个唯一索引的方式来重组表。是真的还是另一个原因?
您可以总是以一种唯一的唯一索引的方式重组表,其中有 EntityA和EntityB。每个实例有2个实例。任何EntityA实例都可以与任何EntityB实例结合,因此有2种可能的组合使用所有实例。实现了这些组合之一,您必须将其存储。现在尝试制定一个方案,其中不存在具有2个唯一性的表,并且具有所有约束来防止非法数据。
—
Akina
@Akina我想念你的意思。如果两个实体通过多对多关系连接,则将创建一个链接表,并存储它们的外键,因此不存在带有2个唯一索引的表。
—
appl3r
一个实例只能使用一次,因此在链接表中必须有2个uniqie索引(每个实体分别),以防止使用已经使用的实例。
—
Akina
虽然这是事实,但是这很麻烦:请参阅Michael Green答案中的示例。将这样一个简单的表分成4个表绝对是一件令人头疼的事,因为这是一个简单的字典,所以并不是您需要“ ON CONFLICT”选项。
—
Walfrat