1. PostgreSQL UPSERT 核心机制解析
PostgreSQL的UPSERT功能(INSERT ON CONFLICT)是我在数据库开发中最常用的特性之一。这个功能完美解决了"存在则更新,不存在则插入"的业务场景需求。相比传统方案,它不仅在性能上有显著优势,更重要的是保证了操作的原子性。
1.1 传统方案的致命缺陷
在UPSERT出现之前,我们通常使用两种替代方案:
方案A:先查询后操作
sql复制BEGIN;
SELECT * FROM users WHERE id = 100;
-- 如果不存在
INSERT INTO users(id, name) VALUES(100, '张三');
-- 如果存在
UPDATE users SET name = '张三' WHERE id = 100;
COMMIT;
这个方案存在严重的竞态条件问题。在高并发场景下,两个事务可能同时判断记录不存在,然后都尝试插入,导致唯一约束冲突。
方案B:捕获异常
sql复制BEGIN;
INSERT INTO users(id, name) VALUES(100, '张三');
EXCEPTION WHEN unique_violation THEN
UPDATE users SET name = '张三' WHERE id = 100;
END;
虽然这个方案解决了原子性问题,但异常处理会带来额外的性能开销,特别是在冲突频繁的场景下。
1.2 UPSERT的语法本质
PostgreSQL的UPSERT语法结构如下:
sql复制INSERT INTO table_name (columns)
VALUES (values)
ON CONFLICT (conflict_target)
DO UPDATE SET column1 = value1, ...;
关键组成部分:
conflict_target:指定检测冲突的列或约束DO UPDATE SET:定义冲突发生时的更新操作DO NOTHING:冲突时静默忽略
提示:
conflict_target必须对应表上的唯一约束或主键,否则语法会报错。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
