PostgreSQL 务实应用(二/5)插入冲突
在项目中,有时会动态地按周期(如按月)封存统计数据,通常需要做这样的处理:
以按月封存为例,当月数据到达时,先需要检查该月是否有过记录,有则以更新的方式累加统计数字,无则添加一条记录。
假设我们创建以下月封存表 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 更新的内容与条件则要根据业务规则(如值变化时才更新,或存在则不更新等)具体分析。
PostgreSQL 务实应用(二/5)插入冲突的更多相关文章
- PostgreSQL的存储系统二:REDOLOG文件存储结构二
REDOLOG文件里的用户数据和数据文件里的用户数据存储结构相同 几个月前同事给台湾一家公司培训<pg9 ad admin>时,有个学员提及WAL里记录的内容为Query时的SQL语句(比 ...
- PostgreSQL 务实应用(五/5)常用表达
在实际应用中,对于具体的数据计算我们会找相应的函数来实现.而计算需求不同的表达,往往会使得我们使用不同的函数或方式来实现.或者也可以说,同一计算可以使用多种不同的表达方式实现. PostgreSQL ...
- postgresql优化数据的批量插入
原文:http://www.cnblogs.com/mchina/archive/2012/08/11/2537393.html 有以下几种方法用于优化数据的批量插入. 1. 关闭自动提交: ...
- 富文本编辑器UEditor自定义工具栏(二、插入图片、音频、视频个性化功能按钮和弹层及自定义分页符)
导读:本篇将简单探讨插入图片.音频.视频的功能按钮实现方式 传送门:富文本编辑器UEditor自定义工具栏(一.基础配置与字体.背景色.行间距.超链接实现) 一.效果图 1.UEditor自定义工具栏 ...
- postgreSQL学习(二):pgsql的一些基础操作
在上一篇文章中我们学习了怎么安装pgsql,安装好了后,我们来学习一下怎么对pgsql进行创建操作以及相关的crud的操作啦 一 创建数据库 $ createdb test 然后你可能会遇到如下的错误 ...
- 跟我一起读postgresql源码(二)——Parser(查询分析模块)
上篇博客简要的介绍了下psql命令行客户端的前台代码.这一次,我们来看看后台的代码吧. 十分不好意思的是,上篇博客我们只说明了前台登陆的代码,没有介绍前台登陆过程中,后台是如何工作的.即:后台接到前台 ...
- postgreSQL 常用命令 二
本次测试基与PostgreSQL 10.x版本 创建用户 [postgres@rtm2 data]$ /opt/pgsql-10/bin/createuser rentaomin [postgres@ ...
- PostgreSQL 务实应用(四/5)JSON
JSON 可谓风靡互联网,在数据交换使用上,其优势特别明显,其结构简洁.可读易读.形式灵活.很多 API 接口的数据都采用 JSON 来表示. PostgreSQL 对 JSON 提供了良好的支持.具 ...
- PostgreSQL 务实应用(三/5)分表复制
问题的提出 在项目中,有些表的记录增长非常快,记录数过大时会使得查询变得困难,导致整个数据库处理性能下降.此时,我们会考虑按一定的规则进行分表存储. 常用的分表方式是按时间周期,如每月一张,每天一张等 ...
随机推荐
- (转)Understanding C parsers generated by GNU Bison
原文链接:https://www.cs.uic.edu/~spopuri/cparser.html Satya Kiran PopuriGraduate StudentUniversity of Il ...
- Android-基本控件和详解四种布局方式
转自:https://www.cnblogs.com/ludashi/p/4883915.html 一.常用基本控件 1.TextView 看到Android中的TextView, 我不禁的想到了iO ...
- 【BZOJ2339】[HNOI2011]卡农 组合数+容斥
[BZOJ2339][HNOI2011]卡农 题解:虽然集合具有无序性,但是为了方便,我们先考虑有序的情况,最后将答案除以m!即可. 考虑DP.如果我们已经知道了前m-1个集合,那么第m个集合已经是确 ...
- mac 权限问题
终端输入sudo chown -R zjtc /usr/local
- Java面试-Hibernate总结
1 Hibernate的检索方式 Ø 导航对象图检索(依据已经载入的对象.导航到其它对象. ) Ø OID检索(依照对象的OID来检索对象. ) Ø HQL检索(使用面向对象的HQL查询语言. ...
- Python2.7使用virtualenv windows7
环境: python2.7 windows7 一.安装 H:\>pip install virtualenv 二.创建项目目录 H:\>mkdir envtest H:\>cd en ...
- [CPP - STL] swap技巧
最近在看<Effective STL>,[条款17:使用“交换技巧”修整过剩容量]中提到容器的成函数void swap(container& from),即实现容器对象与from对 ...
- Package 'sun-java6-jdk' has no installation candidate 解决方式【转】
本文转载自:http://www.cnblogs.com/changefuture/archive/2012/06/19/2554876.html 解决方式: sudo add-apt-reposit ...
- ubuntu下安装android模拟器genymotion【转】
本文转载自:http://www.jianshu.com/p/e6062ebb8fc9 去genymotion下载对应的安装包genymotion-2.4.0_x64.bin sudo ./genym ...
- 谈谈网站测试中的AB测试方法
什么是A/B测试? A / B测试,即你设计的页面有两个版本(A和B),A为现行的设计, B是新的设计.比较这两个版本之间你所关心的数据(转化率,业绩,跳出率等) ,最后选择效果最好的版本. A / ...