如何使用 SQL ON CONFLICT DO NOTHING 实现 upsert 幂等性保障

来源:编程学习作者:澳门程序员头衔:程序员
导读:本期聚焦于小伙伴创作的《如何使用 SQL ON CONFLICT DO NOTHING 实现 upsert 幂等性保障》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何使用 SQL ON CONFLICT DO NOTHING 实现 upsert 幂等性保障》有用,将其分享出去将是对创作者最好的鼓励。

在 PostgreSQL 等支持 upsert 的数据库中,ON CONFLICT DO NOTHING 是实现写入幂等性的轻量方案。它依赖于表中已存在的唯一约束或唯一索引,当插入数据违反约束时直接忽略该行,而不是报错或更新。

如何使用 SQL ON CONFLICT DO NOTHING 实现 upsert 幂等性保障

为什么需要幂等写入

在消息队列消费、定时任务重跑、接口重试等场景中,同一批数据可能被反复提交。如果直接执行 INSERT,第二次就会因为主键或唯一键冲突而失败;如果先查再插,又会存在并发下的竞态问题。使用 upsert 配合 DO NOTHING,可以让重复请求安全地变成无操作。

基础表结构与约束

要实现冲突跳过,必须先有唯一约束。下面创建一个用户积分表,以 user_id 作为唯一键:

CREATE TABLE user_score (
    user_id BIGINT PRIMARY KEY,
    score INT NOT NULL DEFAULT 0,
    updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);

这里的 user_id 是主键,天然具备唯一约束,可以作为 ON CONFLICT 的冲突目标。

标准幂等插入写法

使用 ON CONFLICT (冲突列) DO NOTHING 即可实现幂等:

INSERT INTO user_score (user_id, score, updated_at)
VALUES (1001, 50, NOW())
ON CONFLICT (user_id) DO NOTHING;

当 user_id 为 1001 的记录已存在时,该语句不会插入新行,也不会报错,事务正常提交。

批量写入的幂等保障

批量场景同样适用,一次插入多行,冲突的行自动跳过:

INSERT INTO user_score (user_id, score, updated_at)
VALUES
    (1001, 50, NOW()),
    (1002, 30, NOW()),
    (1003, 80, NOW())
ON CONFLICT (user_id) DO NOTHING;

复合唯一约束下的写法

如果幂等依据是多列组合,需要先建复合唯一索引:

CREATE TABLE order_log (
    order_id BIGINT,
    item_id BIGINT,
    qty INT,
    CONSTRAINT uk_order_item UNIQUE (order_id, item_id)
);

插入时指定约束名或列组合:

INSERT INTO order_log (order_id, item_id, qty)
VALUES (9001, 2001, 2)
ON CONFLICT ON CONSTRAINT uk_order_item DO NOTHING;

注意事项

  • DO NOTHING 不会更新已有记录,若需同步最新值应使用 DO UPDATE。
  • 冲突目标必须对应已存在的唯一索引或主键,否则语法报错。
  • 在 RR 及以上隔离级别下仍安全,不会因并发插入导致异常。
合理运用 ON CONFLICT DO NOTHING,可以用最简 SQL 成本换来实现可靠的幂等写入,特别适合日志、计数、配置类数据的去重落库。

SQLupsertON_CONFLICT_DO_NOTHING修改时间:2026-07-26 01:09:20

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。