博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PostgreSQL 务实应用(二/5)插入冲突
阅读量:4605 次
发布时间:2019-06-09

本文共 1400 字,大约阅读时间需要 4 分钟。

在项目中,有时会动态地按周期(如按月)封存统计数据,通常需要做这样的处理:

以按月封存为例,当月数据到达时,先需要检查该月是否有过记录,有则以更新的方式累加统计数字,无则添加一条记录。

假设我们创建以下月封存表 month_stat,字段 month_name 表示月份,字段 total_count 表示统计数字。

CREATE TABLE month_stat (month_name varchar(6), total_count int, UNIQUE (month_name));

普通处理

假设数据到达,我们用 v_month_name 表示到达数据的月份,v_count 表示本次到达的数量,则通常我们使用以下方式完成月封存数据的记录:

DO $$ DECLARE   v_month_name varchar := '201904'; -- 本次数据的月份   v_count int          := 3;        -- 本次数据相关的数量BEGIN   -- 如果月份已经存在,则更新统计,将数量累加上去   IF EXISTS (SELECT 1 FROM month_stat WHERE month_name = v_month_name FOR UPDATE) THEN      UPDATE month_stat set total_count = total_count + v_count        WHERE month_name = v_month_name;   ELSE    -- 插入月份,数量为本次数量      INSERT INTO month_stat (month_name, total_count) VALUES (v_month_name, v_count);   END IF;END $$;

判断逻辑在 BEGIN 与 END 之间,先判断月份是否存在,再按分支进行更新或插入处理。

使用 ON CONFLECT

好消息是,从 postgres-9.5 起增加了插入冲突的支持:

INSERT … ON CONFLICT DO NOTHING/UPDATE

于是有了以下写法:

INSERT INTO month_stat (month_name, total_count) VALUES ('201904', 3)ON CONFLICT(month_name)DO   UPDATE set total_count = month_stat.total_count + EXCLUDED.total_count;

CONFLICT 后边括号中必须是建立了唯一索引(或主键)的字段或字段集。

DO 后边可以是 NOTHING 表示冲突时忽略,什么都不做。也可以是 UPDATE,表示冲突时需要更新,本次冲突相关的数据使用 EXCLUDED 来引用。

使用 ON CONFILECT 至少有两个好处:

  • 不需要自已费心去加事务锁,因为它就是一个语句
  • 代码简洁无分支结构

至于使用 NOTHING 还是 UPDATE,以及 UPDATE 更新的内容与条件则要根据业务规则(如值变化时才更新,或存在则不更新等)具体分析。

转载于:https://www.cnblogs.com/timeddd/p/10860248.html

你可能感兴趣的文章
关于七牛进行图片添加文字水印操作小计
查看>>
DataSource数据库的使用
查看>>
CentOS开启samba实现文件共享
查看>>
MSSQL使用sqlbulkcopy批量插入数据
查看>>
证明一个数能被3整除,当且仅当它的各位数的和能被3整除
查看>>
2018秋寒假作业4—PTA编程总结1
查看>>
android自适应屏幕
查看>>
2019-北航面向对象-电梯作业总结
查看>>
SqlHelper
查看>>
初识算法、数据结构
查看>>
QTP中对EXCEL进行读操作的格式
查看>>
Luogu4069 SDOI2016 游戏 树链剖分、李超线段树
查看>>
Java的内部类真的那么难以理解?
查看>>
一文搞懂Java环境,轻松实现Hello World!
查看>>
hash实现锚点平滑滚动定位
查看>>
也谈智能手机游戏开发中的分辨率自适应问题
查看>>
开始一个django项目
查看>>
重新学习angularjs--第一篇(入门)
查看>>
【转】MYSQL数据库设计规范与原则
查看>>
《中国大历史》—— 读后总结
查看>>