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所看到的。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
图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所看到的。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
图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所看到的。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
图16
最后。我们来看看staged_employees中的数据,如图17所看到的。
图17
从图17中看到,“country等于CN。state等于BJ”分区的数据如我们所愿追加到表staged_employees中了。“country等于US。state等于CA”分区的数据并没有被覆盖。而是追加。
这非常明显是一个bug,希望大家注意!
后记:个人总结整理的《深入理解Spark:核心思想与源代码分析》一书如今已经正式出版上市,眼下京东、当当、天猫等站点均有销售,欢迎感兴趣的同学购买。
Hive通过查询语句向表中插入数据过程中发现的坑的更多相关文章
- Hive通过查询语句向表中插入数据注意事项
最近在学习使用Hive(版本0.13.1)的过程中,发现了一些坑,它们或许是Hive提倡的比关系数据库更加自由的体现(同时引来一些问题),或许是一些bug.总而言之,这些都需要使用Hive的开发人员额 ...
- hive中创建子表并插入数据过程初始化MR报错解决方法
本文继成上一篇通过hive分析nginx日志文章,详情参考下面链接: http://www.cnblogs.com/wcwen1990/p/7066230.html 接着来: 创建业务子表: drop ...
- 使用SQL语句建表,插入数据
--选中数据库,点击新建查询,然后执行即可--这是SQL中的注释信息,使用两个减号来注释. drop table Book --删除表Book create table Book --创建表Book ...
- SQL语句的使用,SELECT - 从数据库表中获取数据 UPDATE - 更新数据库表中的数据 DELETE - 从数据库表中删除数据 INSERT INTO - 向数据库表中插入数据
SQL DML 和 DDL 可以把 SQL 分为两个部分:数据操作语言 (DML) 和 数据定义语言 (DDL). SQL (结构化查询语言)是用于执行查询的语法. 但是 SQL 语言也包含用于更新. ...
- 第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 ...
- 触发器修改后保存之前的数据 表中插入数据时ID自动增长
create or replace trigger t before update on test5 for each rowbegin insert into test55 values (:old ...
随机推荐
- Python爬虫基础示例
使用pip安装相关依赖: pip install requests pip install bs4 安装成功提示:Successfully installed *... 爬取中国天气网数据示例代码: ...
- 【Loadrunner】Vugen录制脚本为空的解决办法
1. ie -> 工具 -> Internet选项 - 高级 - 勾除“启动第三方浏览器扩展选项”,然后重启电脑 2. 还有一种可能,就是机器上安装了多个浏览器,从而导致出现问题,解决方法 ...
- OpenJDK源码研究笔记(七)–Java字节码文件(.class)的结构
最近在看OpenJDK源码的过程中,顺便看了Java编译器(javac)的源码. 为了理解javac的源码,需要先搞懂Java字节码文件(.class)的结构. 于是,我就认真看了下OpenJDK中J ...
- CSU 1374 Restore Calculation 数位DP
题意: 给你三个数A, B, C(没有前导0),但是其中某些位不知道. 问A+B=C成立有多少种情况. 思路: 从最后一位往前推,枚举A, B的每一种情况,考虑进位和不进位两种情况. 代码: #inc ...
- Unity C# 设计模式(四)抽象工厂模式
定义: 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 工厂方法模式针对的是一个产品等级结构:而抽象工厂模式针对的是多个产品等级结构. 抽象工厂模式使用同一个 工厂等级结构负责这 ...
- 题解 CF327C 【Magic Five】
这道题带坑,假如没有发现肯定会爆. 首先先搜索一遍0和5,储存在数组a里面. 那么应当有2 ^ a1 +2 ^ a2 +...+ 2 ^ an. 然而这道题没那么简单,数串还可以重复k次. 因此,需要 ...
- 洛谷 P1754 球迷购票问题
P1754 球迷购票问题 题目背景 盛况空前的足球赛即将举行.球赛门票售票处排起了球迷购票长龙. 按售票处规定,每位购票者限购一张门票,且每张票售价为50元.在排成长龙的球迷中有N个人手持面值50元的 ...
- POJ 3150 Cellular Automaton(矩阵高速幂)
题目大意:给定n(1<=n<=500)个数字和一个数字m,这n个数字组成一个环(a0,a1.....an-1).假设对ai进行一次d-step操作,那么ai的值变为与ai的距离小于d的全部 ...
- BootstrapDialog模态框
5最近是比较烦直接使用Bootstrap里面的模态框,满屏都是模态框代码,看得心烦.然后想起以前使用的BootstrapDialog.show()的方式,挺简单好用的.然后就拿出来分享一下. 1.下载 ...
- 之前写的收集的一些c++代码片,算法排序,读文件,写日志,快速求积分等等
写日志: class LogFile { public: static LogFile &instance(); operator FILE *() const { return m_file ...