Phoenix的插入语句是Upsert,Update和Insert的组合语义。即,如果数据表中没有这条记录那么插入这条记录,如果有则更新。判断是否存在相同的数据是使用ON DUPLICATE KEY来验证的,这里的KEY就是建表时候的主键(PRIMARY KEY)。和Oracle的Merge Into以及MySQL的Insert …on duplicate key 是类似的功能。ON DUPLICATE KEY这个语法要到Phoenix 4.9之后才有。这个功能把HBase的Increment和CheckAndPut两个原子操作合在了一起。当Upsert语句被提交到服务端的时候,所要更新的行会被lock住,同时相关的列会被读取,ON DUPLICATE KEY语句会被执行。由于会锁住所在的行,所以会有一些性能损耗,但是这个损耗比较小,类似于HBase中Put和CheckAndPut的之间的性能差异。

由于有了ON DUPLICATE KEY分句,如果行存在,那么VALUES后面的值将会为忽略。在ON DUPLICATE KEY后面还有其他的语法来实现不同的功能:

  • 如果分句是ON DUPLICATE KEY IGNORE 的话,那么这行就不会被Update。
  • 如果分句是ON DUPLICATE KEY UPDATE 的话,行就会被后面的Update语句更新,这个更新是获取了行级锁的。

如果操作同一行的多个Upsert在同一时间被批量提交的话,服务端将会按顺序执行它们。所以无论自动提交是开还是关,都会得到一样的结果。

下面列出了UPSERT的一些常用语法:

UPSERT INTO TEST VALUES('foo','bar',3);
UPSERT INTO TEST(NAME,ID) VALUES('foo',123);
UPSERT INTO TEST(ID, COUNTER) VALUES(123, 0) ON DUPLICATE KEY UPDATE COUNTER = COUNTER + 1;
UPSERT INTO TEST(ID, MY_COL) VALUES(123, 0) ON DUPLICATE KEY IGNORE;

如果是4.9之前的版本的话,ON DUPLICATE KEY 分句是不存在的。只有上例的第一和第二种语法。如果原表中有数据重复的话,就会直接更新。

和Oracle和MySQL一样,Phoenix也有Upsert Select语法。插入或更新的数据是另外一个查询结果集。插入或更新的列和查询结果集的列要一一匹配,如果不显式的列出列,那么查询结果集的列要和目标表的列的元数据保持顺序一致。如果auto commit开启的话,会在服务端就提交了,否则会缓存到客户端,等着显式提交的时候进行批量upsert。自动提交的话,可以通过客户端配置“phoenix.mutate.upsertBatchSize”指定大小,默认10000行/次。

示例语法如下:

UPSERT INTO test.targetTable(col1, col2) SELECT col3, col4 FROM test.sourceTable WHERE col5 < 100
UPSERT INTO foo SELECT * FROM bar;

最后,来说一下ON DUPLICATE KEY的一些限制。

1. 主键不会被更新,它是创建新行的基础。

2. 事务表不应该使用这个功能,因为当冲突发生时,原子的Upsert操作有可能已经被异常处理掉了。

3. 不可变表不应该使用这个功能,因为不应该有数据更新不可变表。

4. 如果要使用这个子句,在连接时,就不能设置CURRENT_SCN属性,因为除非最新的值正在被更新,否则HBase的操作不是原子的。

5. 同一列在同一句语句中不应该被更新超过一次。

6. ON DUPLICATE KEY 子句中不能有聚合或者序列。

7. 虽然在列上的全局索引是支持原子化的更细你的,但是还是不推荐在全局索引表上使用这个子语句。因为当维护二级索引的时候,行会被锁定,这个子句胡产生一个RPC调用。

Phoenix系列:原子的Upsert的更多相关文章

  1. Apache Phoenix系列 | 从入门到精通(转载)

    原文地址:https://cloud.tencent.com/developer/article/1498057 来源: 云栖社区 作者: 瑾谦 By 大数据技术与架构 文章简介:Phoenix是一个 ...

  2. Phoenix系列:二级索引(2)

    上一篇介绍了Phoenix基于HBase的二级索引的基本知识,这一篇介绍一下和索引相关的一致性和优化相关内容. 一致性的保证 Phoenix客户端在成功提交一个操作并且得到成功响应后,就代表你所做的操 ...

  3. Phoenix系列:二级索引(1)

    Phoenix使用HBase作为后端存储,对于HBase来说,我们通常使用字典序的RowKey来快速访问数据,除此之外,也可以使用自定义的Filter来搜索数据,但是它是基于全表扫描的.而Phoeni ...

  4. phoenix技术(安装部署和基本使用)讲解

    1.phoenix简介 Apache Phoenix是构建在HBase之上的关系型数据库层,作为内嵌的客户端JDBC驱动用以对HBase中的数据进行低延迟访问.Apache Phoenix会将用户编写 ...

  5. Postgresql插入或更新操作upsert

    幂等性的一个要求是多次操作的结果一致.对于update操作,多次直接的结果都是最后update的值,是满足需求的. 但对于insert,如果已经插入,第二次会报错,duplicate error, 主 ...

  6. Hadoop生态圈-phoenix完全分布式部署以及常用命令介绍

    Hadoop生态圈-phoenix完全分布式部署 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. phoenix只是一个插件,我们可以用hive给hbase套上一个JDBC壳,但是你 ...

  7. HBase之八--(2):HBase二级索引之Phoenix

    1. 介绍 Phoenix 是 Salesforce.com 开源的一个 Java 中间件,可以让开发者在Apache HBase 上执行 SQL 查询.Phoenix完全使用Java编写,代码位于 ...

  8. Apache Phoenix的序列

    序列作为标准SQL特性,允许生成递增的序列并应用在典型的ID中.为了创建一个序列,可以使用: 0:jdbc:phoenix:SZB-L0023780:2181:/hbase114> CREATE ...

  9. Apache Phoenix基本操作-1

    本篇我们将介绍phoenix的一些基本操作. 1. 如何使用Phoenix输出Hello World? 1.1 使用sqlline终端命令 sqlline.py SZB-L0023780:2181:/ ...

随机推荐

  1. bat遍历目录

    方法一: for /r  D:\要遍历的目录\  %%i  (*.exe)  do ( echo  %%i ) 方法二: set DestPath=D:\你的目录\ rem 你的后缀 set Dest ...

  2. DHCP服务原理与搭建(Linux系统+路由器,二选一方案)

    大家都知道上网的最基本前提是要在终端上设置IP.子网掩码.网关.DNS等地址信息,在家里或者在办公室很多时候打开电脑后发现就可以上网,并没有手动设置IP.掩码.DNS地址也能上网,这是什么原因呢?其实 ...

  3. web中ajax跨域与同源文章 from 阮一峰

    跨域资源共享 CORS 详解 http://www.ruanyifeng.com/blog/2016/04/cors.html  //这个是最明白的..建议看看. http://www.ruanyif ...

  4. log4net.Layout.PatternLayout 用 conversion 模式格式化日志事件【翻译】

    原文地址 log4net.Layout.PatternLayout,是一个灵活的布局,配置模式字符串. 线程安全.该类型的 Public static 成员对多线程操作是安全的.实例成员不保证线程安全 ...

  5. angularjs 动态表单, 原生事件中调用angular方法

    1. 原生事件中调用angular方法, 比如 input的onChange事件想调用angular里面定义的方法 - onChange="angular.element(this).sco ...

  6. 关于html,body{height:100%}的解释

    来源:https://www.cnblogs.com/QianBoy/p/8571682.html 今天看到一个CSS样式:html,body{height:100%},第一次看到,感觉挺奇怪,为什么 ...

  7. IDEA使用笔记(四)——工具栏的显示隐藏切换

    这也是在玩快捷键的时候,自己试验出来的,觉得不常用但是一旦想用了可能一下不知道怎么弄,还需要找,不如记下来,起码能加深一下印象!

  8. java多线程之线程的同步与锁定(转)

    一.同步问题提出 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 例如:两个线程ThreadA.ThreadB都操作同一个对象Foo对象,并修改Foo对象上的数据. publicc ...

  9. android 加载远程Jar、APK

    参考链接: .http://blog.csdn.net/bboyfeiyu/article/details/117104972\ http://www.cnblogs.com/LittleRedPoi ...

  10. js实现禁止pc端浏览器缩放和获取当前页面浏览器的缩放大小

    众所周知:移动端页面禁止用户缩放界面只需加上<meta name="viewport" content="user-scalable=0">即可,但 ...