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. 9.5 dubbo事件通知机制

    dubbo事件通知机制:http://dubbo.io/books/dubbo-user-book/demos/events-notify.html 一.使用方式 两个服务: DemoService: ...

  2. Python:提取网页中的电子邮箱

    import requests, re #regex = r"([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)"#这个正则表达式过滤 ...

  3. JNI的native代码中打印日志到eclipse的logcat中

    1 添加ndk对log支持若需要添加ndk对log的支持,只需要通过以下2步即可实现. 1.1 修改Android.mk如生成的库文件是“.so文件”,则在Android.mk中添加如下内容:LOCA ...

  4. JSR-303 Bean Validation 介绍及 Spring MVC 服务端验证最佳实践

    任何时候,当要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情. 应用程序必须通过某种手段来确保输入参数在上下文来说是正确的. 分层的应用在很多时候,同样的数据验证逻辑会出现在不同的层, ...

  5. plsql 操纵表数据的2种方式

      1.情景展示 在plsql中,对表的操作(增.删.改.查),其实有2种方式,只是很多人都只会第一种方式罢了. 2.方式介绍 第1种方式:直接将值与sql写到一起 直接按F8运行即可. 第2种方式: ...

  6. Microsoft/Git-Credential-Manager-for-Mac-and-Linux

    纠正Mac上的错误: Fatal: java.lang.Error encountered. Details: unexpected errorfatal: credential helper '!/ ...

  7. vmlinux,zImage,bzImage,vmlinuz,uImage,关系

    zImage和uImage的区别 一.vmlinuz vmlinuz是可引导的.压缩的内核.“vm”代表“Virtual Memory”.Linux 支持虚拟内存,不像老的操作系统比如DOS有640K ...

  8. POCO Log库

    http://pocoproject.org/index.html 有个想法,把这个所谓的跨平台log库阉割成只支持win的,然后使代码尽量简化,高效,以后有时间就开始研究,哈哈.

  9. 浅谈MySQL备份字符集的问题

    1 引子 MySQL备份时选择字符集是一个难题,特别是字符集不定的业务.mysqldump默认使用utf8,而官方也推荐使用utf8.但实际上,对于中文,部分相当一部分gbk编码字符没有对应的unic ...

  10. HTTP Status 500 - Unable to create directory

    分析原因: 例如:java web项目 上传图片创建文件夹cd /data/apps/static-web/sjk/driver/attachment/编号/文件名称.jpg 在创建文件目录 /dat ...