
浅谈PostgreSQL的UPSERT
UPSERT一词在关系型数据库中被称为合并。当你试图在表中插入一条新的记录时,那么PostgreSQL将检查表中是否已经存在相同的记录。如果表中已经存在类似的记录,PostgreSQL将更新现有的记录;否则,它将插入该记录作为一个新条目。正如我们所看到的,UPSERT操作要么更新记录,要么将记录插入到表中,由于这个原因,我们把这个术语称为UPSERT(无论是UPDATE还是INSERT)。在这个主题中,我们将学习PostgreSQL的UPSERT。
语法
我们可以使用下面的 INSERT ON CONFLICT 语句作为语法,以便在 PostgreSQL 中使用 UPSERT 操作。
INSERT INTO table(columns) VALUES(values)
ON CONFLICT target action;
解释
为了支持UPSERT操作,PostgreSQL增加了ON CONFLICT目标动作。
- 列。定义列的名称。
- ON CONSTRAINT constraint_name: 定义了约束的名称,可以是UNIQUE约束。
- WHERE条件。定义了带有条件的WHERE子句
- 行动。 DO NOTHING:定义了如果一个表已经包含了什么都不做。
- DO UPDATE SET column_name_1 = value_field_1, ... WHERE predicate :定 义了我们可以更新表中的一些字段。
UPSERT在PostgreSQL中如何工作?
- UPSERT结合了两个DML,第一个是UPDATE,第二个是INSERT。
- 如果我们比较IF EXISTS和UPSERT来理解UPSERT的工作,那么对于每一个更新操作,UPSERT都会从表中删除一个额外的读数。但是在INSERT操作的情况下,UPSERT和IF EXISTS操作对表的读操作数量相同。
- 为了检查一个记录是否已经存在于表中,PostgreSQL的UPSERT语句使用记录的唯一标识符作为键来匹配表中的记录。
在PostgreSQL中实现UPSERT的例子
让我们创建一个名为 "公司 "的表,以了解PostgreSQL的UPSERT功能。
我们将使用下面的CREATE TABLE语句来创建一个公司表。
CREATE TABLE company (
comp_id serial PRIMARY KEY,
comp_name VARCHAR UNIQUE,
comp_email VARCHAR NOT NULL,
comp_contact VARCHAR
);
在这里你可以看到,表company包含四个列,分别是comp_id, comp_name, comp_email, 和comp_contact。此外,我们在公司表的comp_name列上添加了UNIQUE约束,以确保公司的唯一性。
现在我们将通过INSERT INTO语句向表中插入一些记录,如下所示。
INSERT INTO company (comp_name, comp_email)
VALUES
('Bloomberg', 'contact@bloomberg.com'),
('Facebook', 'contact@fb.com' ),
('Google', 'contact@google.com' );
通过使用下面的快照和SELECT语句来说明上述INSERT语句的结果。
select * from company;

现在我们可以用UPDATE语句更新任何一条记录的email id信息。考虑一个例子,Facebook将其电子邮件ID从contact@fb.com 改为contact@facebook.com。
我们将使用以下INSERT ON CONFLICT语句来演示UPSERT功能。
INSERT INTO company (comp_name, comp_email) VALUES ( 'Facebook', 'contact@facebook.com' ) ON CONFLICT ON CONSTRAINT company_comp_name_key DO NOTHING;
上述语句定义,如果公司名称存在于公司表中,则什么也不做,只是忽略掉。
通过使用下面的快照和SELECT语句来说明上述INSERT语句的结果。
select * from company;

下面的语句与上面的语句相似,但它将使用公司表中的comp_name列而不是唯一约束comp_name作为INSERT语句的目标。
INSERT INTO company (comp_name, comp_email)
VALUES
(
'Facebook',
'contact@facebook.com'
)
ON CONFLICT ON CONSTRAINT company_comp_name_key
DO NOTHING;
现在,如果我们想在插入已经存在的公司表时,将新公司的电子邮件与旧公司的电子邮件连接起来。
我们可以使用UPDATE子句作为INSERT INTO语句的动作,定义如下。
INSERT INTO company (comp_name, comp_email)
VALUES
(
'Facebook',
'contact@facebook.com'
)
ON CONFLICT (comp_name)
DO UPDATE
SET comp_email = EXCLUDED.comp_email || ';' || customers.comp_email;
通过使用下面的快照和SELECT语句来说明上述INSERT语句的结果。
select * from company;

在PostgreSQL中使用UPSERT的优点
- PostgreSQL的UPSERT只不过是将两个数据处理操作结合在一起,成为一个更新操作和一个插入操作。
- 如果我们使用PostgreSQL的UPSERT功能,那么对于每一次更新,我们实际上从表中删除了一个额外的读。
- 我们可以通过使用UPSERT操作更新记录来避免对数据库进行不必要的读操作。
- 通过使用UPSERT操作,我们可以避免重复键的违反,因为它将在表中更新或插入一条记录。
总结
我们希望从上面的文章中你已经了解了如何使用PostgreSQL UPSERT以及PostgreSQL UPSERT是如何工作的。此外,我们还添加了一些PostgreSQL UPSERT的例子来详细了解它。