Hive通过查询语句向表中插入数据注意事项
最近在学习使用Hive(版本0.13.1)的过程中,发现了一些坑,它们或许是Hive提倡的比关系数据库更加自由的体现(同时引来一些问题),或许是一些bug。总而言之,这些都需要使用Hive的开发人员额外注意。本文旨在列举我发现的3个通过查询语句向表中插入数据过程中的问题,希望大家注意。
为了验证接下来出现的问题,需要先准备两张表employees和staged_employees,并准备好测试数据。首先使用以下语句创建表employees:
- create table employees (
- id int comment 'id',
- name string comment 'name')
- partitioned by (country string, state string)
- row format delimited fields terminated by ',';
employees的结构比较简单,有id、name、country、state四个字段,其中country和state都是分区字段。特别需要提醒的是这里显示的给行格式指定了字段分隔符为逗号,因为默认的字段分隔符\001不便于笔者准备数据。然后创建表staged_employees:
- create table staged_employees (
- id int comment 'id',
- user_name string comment 'user name')
- partitioned by (cnty string, st string);
staged_employees也有4个字段,除了字段名不同之外,和employees的4个字段的含义是相同的。
我们首先使用以下语句给employees的country等于US,state等于CA的分区加载一些数据:
- load data local inpath '${env:HOME}/test.txt'
- into table employees
- partition (country = 'US', state = 'CA');
再给employees的country等于CN,state等于BJ的分区加载一些数据:
- load data local inpath '${env:HOME}/test2.txt'
- overwrite into table employees
- partition (country = 'CN', state = 'BJ');
以上语句的执行过程如图1所示。
图1 给employees加载数据
最后我们看看employees中准备好的数据,如图2所示。
图2 employees中准备好的数据
INSERT OVERWRITE的歧义
由于staged_employees中还没有数据,所以我们查询employees的数据,并插入staged_employees中:
- insert overwrite table staged_employees
- partition (cnty = 'US', st = 'CA')
- select * from employees e
- where e.country = 'US' and e.state = 'CA';
大家看看这条sql有没有问题?最终的执行结果如图3所示。
由于图3中的文字太小,这里把这些错误提示信息列在下边:
- FAILED: SemanticException [Error 10044]: Line 1:23 Cannot insert into target table because column number/types are different ''CA'': Table insclause-0 has 2 columns, but query has 4 columns.
我们的sql应该没有问题吧?仔细查看提示信息,说是“表只有2列,但是查询有4列”。刚才说过,我建的两张表除了字段名称的差异,其结构完全一样。两张表都有4个字段(2个普通字段和2个分区字段),为什么说staged_employees只有2列呢?这是因为Hive遵循读时模式且遵循相对宽松的语法,在插入或装载数据时,不会验证数据与表的模式是否匹配。只有在读取数据时才会验证。因此在向表staged_employees插入数据时不会验证,而查询读取employees表中的数据时会验证。我对sql进行了调整,调整后的清单如下:
- insert overwrite table staged_employees
- partition (cnty = 'US', st = 'CA')
- select e.id, e.name from employees e
- where e.country = 'US' and e.state = 'CA';
执行这条sql的过程如图4所示。
图4 正确执行insert overwrite
我们看看staged_employees表中,现在有哪些数据(如图5所示):
图5 staged_employees中的数据
熟悉MySQL等关系型数据库的同学可能要格外注意此问题了!
FROM ... INSERT ... SELECT的歧义
本节正式开始之前,向employees表中再加载一些数据:
- load data local inpath '${env:HOME}/test3.txt'
- into table employees
- partition (country = 'CA', state = 'ML');
执行上面sql的过程如图6所示。
图6 加载新的数据
这时表employees的数据如图7所示。
图7
Hive提供了一种特别的INSERT语法,我们不妨先看看其使用方式,sql如下:
- from employees e
- insert into table staged_employees
- partition (cnty = 'CA', st = 'ML')
- select * where e.country = 'CA' and e.state = 'ML';
执行这条sql的过程如图8所示。
图8 SemanticException [Error 10044]
可以看到这里再次出现了之前提到的问题,我们依然按照之前的方式进行修改,sql如下:
- from employees e
- insert into table staged_employees
- partition (cnty = 'CA', st = 'ML')
- select e.id, e.name where e.country = 'CA' and e.state = 'ML';
现在执行这条sql,发现可以成功执行,如图9所示。
图9
现在来看看staged_employees中的数据(如图10所示),看来的确将分区数据插入了。
图10 staged_employees中的数据
FROM ... INSERT ... SELECT存在bug
我们继续使用FROM ... INSERT ... SELECT语法向staged_employees中插入数据,sql如下:
- from employees e
- insert into table staged_employees
- partition (cnty = 'US', st = 'CA')
- select e.id, e.name where e.country = 'US' and e.state = 'CA';
这条sql很明显是向staged_employees中再次插入country等于US,state等于CA分区的数据,根据INSERT INTO的通常含义,应当是向表中追加,我们执行这段sql来验证一下,如图11所示。
图11
我们看看这时staged_employees中的数据,如图12所示。
图12
的确印证了,INSERT INTO是用于追加的。
我们将sql进行调整,即将INSERT INTO改为INSERT OVERWRITE:
- from employees e
- insert overwrite table staged_employees
- partition (cnty = 'US', st = 'CA')
- select e.id, e.name where e.country = 'US' and e.state = 'CA';
执行这条sql的过程如图13所示。
图13
我们看看这时staged_employees中的数据,如图14所示。
图14
这说明INSERT OVERWRITE是用于覆盖的。
根据官方文档说明,这种FROM
... INSERT ... SELECT语法中的INSERT ...
SELECT是可以有多个的,于是我编写以下sql,用来向表staged_employees中覆盖“country等于CA,state等于ML”分区的数据,并且覆盖“country等于US,state等于CA”分区的数据。
- from employees e
- insert overwrite table staged_employees
- partition (cnty = 'US', st = 'CA')
- select e.id, e.name where e.country = 'US' and e.state = 'CA'
- insert overwrite table staged_employees
- partition (cnty = 'CA', st = 'ML')
- select e.id, e.name where e.country = 'CA' and e.state = 'ML';
执行以上sql的过程如图15所示。
图15
由于都是覆盖更新,所以staged_employees中的数据并未发生改变。
根据官方文档,以上sql中还可以将INSERT OVERWRITE和INSERT INTO进行混用,sql如下:
- from employees e
- insert overwrite table staged_employees
- partition (cnty = 'US', st = 'CA')
- select e.id, e.name where e.country = 'US' and e.state = 'CA'
- insert into table staged_employees
- partition (cnty = 'CN', st = 'BJ')
- select e.id, e.name where e.country = 'CN' and e.state = 'BJ';
这段sql将覆盖“country等于US,state等于CA”分区的数据,并且追加“country等于CN,state等于BJ”分区的数据。执行这段sql的过程如图16所示。
图16
最后,我们来看看staged_employees中的数据,如图17所示。
图17
从图17中看到,“country等于CN,state等于BJ”分区的数据如我们所愿追加到表staged_employees中了。“country等于US,state等于CA”分区的数据并没有被覆盖,而是追加。这很明显是一个bug,希望大家注意!
转自:http://blog.csdn.net/beliefer/article/details/51860510
Hive通过查询语句向表中插入数据注意事项的更多相关文章
- Hive通过查询语句向表中插入数据过程中发现的坑
前言 近期在学习使用Hive(版本号0.13.1)的过程中,发现了一些坑,它们也许是Hive提倡的比关系数据库更加自由的体现(同一时候引来一些问题).也许是一些bug.总而言之,这些都须要使用Hive ...
- 6-02使用SQL语句向表中插入数据
插入语句的语法: INSERT INTO 表() VALUES(值列表) 注意事项: 1:每次插入一行数据,不能只插入半行或几列数据. 2:每一个数据值的数据类型.精度和小数位数必须与相应的列匹配. ...
- oralce使用INSERT语句向表中插入数据
INSERT INTO table[ (column [, column. . .])] VALUES (value [,value . . .]); v 插入的数据 ...
- SQL语句的使用,SELECT - 从数据库表中获取数据 UPDATE - 更新数据库表中的数据 DELETE - 从数据库表中删除数据 INSERT INTO - 向数据库表中插入数据
SQL DML 和 DDL 可以把 SQL 分为两个部分:数据操作语言 (DML) 和 数据定义语言 (DDL). SQL (结构化查询语言)是用于执行查询的语法. 但是 SQL 语言也包含用于更新. ...
- SQL语句 在一个表中插入新字段
SQL语句 在一个表中插入新字段: alter table 表名 add 字段名 字段类型 例: alter table OpenCourses add Audio varchar(50)alter ...
- 第18课-数据库开发及ado.net 连接数据库.增.删.改向表中插入数据并且返回自动编号.SQLDataReade读取数据
第18课-数据库开发及ado.net 连接数据库.增.删.改向表中插入数据并且返回自动编号.SQLDataReade读取数据 ADO.NET 为什么要学习? 我们要搭建一个平台(Web/Winform ...
- 初学者使用MySQL_Workbench 6.0CE创建数据库和表,以及在表中插入数据。
标签: mysqlworkbench数据库 2013-10-09 20:17 19225人阅读 评论(14) 收藏 举报 分类: mysql(1) 版权声明:本文为博主原创文章,未经博主允许不得转 ...
- EF Core中,通过实体类向SQL Server数据库表中插入数据后,实体对象是如何得到数据库表中的默认值的
我们使用EF Core的实体类向SQL Server数据库表中插入数据后,如果数据库表中有自增列或默认值列,那么EF Core的实体对象也会返回插入到数据库表中的默认值. 下面我们通过例子来展示,EF ...
- 向mysql数据表中插入数据失败的原因
1.案例代码: $sql1="insert into content(category,subject,content,username,release_date) values('{$ca ...
随机推荐
- 【转】python代码风格-PEP8
转载自http://www.douban.com/note/134971609/ Python 的代码风格由 PEP 8 描述.这个文档描述了 Python 编程风格的方方面面.在遵守这个文档的条件下 ...
- Android编程之仿微信显示更多文字的View
微信朋友圈中,如果好友发表的文字过长,会自动收缩起来,底下有提示,当点击“显示更多”时才会展开. 首先定义布局文件(很简单,不解释): <?xml version="1.0" ...
- k近邻法的C++实现:kd树
1.k近邻算法的思想 给定一个训练集,对于新的输入实例,在训练集中找到与该实例最近的k个实例,这k个实例中的多数属于某个类,就把该输入实例分为这个类. 因为要找到最近的k个实例,所以计算输入实例与训练 ...
- DLX舞蹈链 hdu5046
题意: 在N个城市选出K个城市,建飞机场(1 ≤ N ≤ 60,1 ≤ K ≤ N),N个城市给出坐标,选择这K个机场,使得从城市到距离自己最近的机场的 最大的距离 最小. 输出这个最小值. 思路: ...
- 各种ORM安装
1.EF安装 2.PetaPoco安装 Install-Package PetaPoco 3.
- 教你用Cocosdx导出安卓安装文件(.apk)(一)
我也是刚弄出来,过程可能有点混乱和不具体,我尽我所能写完整.各位看官多多包涵 设备环境: 我所用的是mac 10.8.5 64位 Cocosdx-3.0rc2 xcode 5.0 一.准备 ND ...
- DropDownList的多级联动
DropDownList的多级联动的问题最典型的案例就是实现省市级三级联动的案例,对这个问题的描述是当选中山东省之后,在选择市的下拉菜单时,市一栏只出现山东省下面的市.对于县也是同样的道理. 我也做的 ...
- <转>一道面试题比较synchronized和读写锁
一.科普定义(原文:http://903497571.iteye.com/blog/1874752) 这篇博文的两个主角“synchronized”和“读写锁” 1)synchronized 这个同步 ...
- Quartz 设置一个半小时任务实现
该文章属于本人原创,转载请注明出处. spring + Quartz 设置定时任务时要求没一个半小时执行一次 设置两个相同的定时任务 第一个从整点开始每三小时执行一次 ...
- 如何使用nodejs发邮件
昨天就开始想使用nodemailer来实现一个发送邮件的功能,不过发现了很多个坑,网上给的资料也很杂很乱,所以决定写一篇真正能用的来帮助大家减少弯路 首先,我们先来看下代码,如上所示. 步骤: 1.下 ...