hive(I)--学习总结之常用技能
hive是Apache的一个顶级项目,由facebook团队开发,基于java开发面向分析师或BI等人员的数据工具(常用作数据仓库),它将hdfs文件组织成表,使用hive-sql调用mapreduce任务完成计算。即使你不知道它的内部机制也不懂java,却不影响你使用。
这里主要以CLI使用为主,材料来源《Hive权威指南》、个人工作和网上讨论。在阅读前,希望可以先了解一下hive的安装(上一篇博客有),这对理解hive的运行机制有一定帮助。如有疑问或问题,欢迎沟通讨论。
shell执行hive
hive命令在shell中执行有多种,可以通过hive --help --service cli进行查询具体参数,使用如下
- #执行SQL语句
- hive -e "sql语句" #可以添加-S参数,设置静默状态,不输出ok等消息
- #执行SQL文件
- hive -f sql_file (或者加载hive -S -f sql_file 注:S-Silence)
- #执行SQL文件并留在hive交互窗口
- hive -i sql_file
hive中用(hadoop) shell命令
>当我们进入hive的交互模式后,不需要像shell(hadoop fs -cmd -para dir/file)那样与hadoop文件交互,使用dfs就可以了。
例如:当我们想看看一张表的大小时,我们首先找到这张表的位置(假设我们用desc formatted table_name我找到对应表的location)
hive > dfs -du -s -h hdfs://usr/hive/warehouse/mydb.db/tab2
>当我们需要执行一个hive文件时,可以使用source关键字.
例如:hive> source /home/shj/sql_file.sql;
>当我们希望执行一个shell之后而又不想退出hive时,可以在命令前后添加"!"和";"就可以了。
例如:hive > ! ls /home/shj/ ;
hive中的表
hive通过metastore实现与文件的映射。hive中的数据库其实是一个目录(该目录我们可在hive-site.xml中设置hive.metastore.warehouser.dir,假设该值我们设置为/usr/hive/warehouse,那么后期创建的数据库都是该目录的子目录),以db格式的文件。比如说我create database mydb;那么这个数据库文件就是:/usr/hive/warehouse/mydb.db,后期建的表对应文件是这个目录的子文件。
I、hive表类型:管理表(内部表)、外部表、分区表(静态、动态)、分桶表。 (不同维度的划分)
>内部表:我们正常建立的表属于内部表,hive管理着这个表(元数据和文件数据),我们操作该表就是操作该元数据以及文件数据。要是我们删了这个表,也就是删了这个表对应的文件
>外部表(external):外部表类似于将hive与文件的链接(link),hive仅管理着元数据。当我们删除该表时,也只是删除数据结构,底层文件并没有被删除。
>分区表(partition):当数据量比较大,进行查询时必然导致性能问题。而分区表,就是对大量的表文件以一个虚拟列(如地区、时间)的方式进行拆分成多个文件。指定分区进行查询时,仅扫描对应分区文件,有效提升查询性能。(查询时应指定,在不确定分区范围时将进行全分区扫描,性能差)
>分桶表(bucket):工作中遇到的不多,会用来进行数据抽样(tablesample其实也可以用,此外两个分桶表join进行查询时效率会提升很多)。它与分区表的不同,它分桶的列是表中真实存在的列。文件组织分式与分区相似。
II、查看表信息
当一个表已经创建好了,我们怎么看这个表呢?(它的字段,备注,创建人,基本统计信息,文件地址等等)
>desc [extended/formatted] mydb.tab2; desc是describe的缩写,当我们查看表时补充上extended或formatted时输出的信息将更多。推荐使用formatted,这样输出的信息相对标准化,更容易找到我们要的信息。这些信息中,Table Type如果是"MANAGED_TABLE"是内部表,"EXTERNAL_TABLE"是外部表;分区和分桶信息可以参见:Partition Infomation和Number Buckets
>show tables in mydb like '*tab1*';查询在mydb库中,关键字“tab1”的表名称。(这里非%)
>set hive.cli.print.current.db=true;set hive.cli.print.header=true;第一个:显示当前库名;第二个:输出列名;
III、hive表的创建
创建或修改或删除都可以在语句中添加if判断来避免系统报错(if [not] exists),文章中不再说明这点。在表的创建中,我们除了指定分隔符,还可以指定表备注(COMMENT)、表属性(TBLPROPERTIES)、指定文件地址(LOCATION)等。如果想复制他表结构:create table mydb.tab2 like mydb.tab_tmp;
>内部表:create table mydb.tab2(col1 string,col2 int,col3 bigint,...)row format delimited fields terminated by '\001' stored as textfile;(存储格式不指定时,默认以textfile;)
>外部表:create external table mydb.tab2(col1 string,col2 int,col3 bigint,...) row format delimited fields terminated by '\001' location ‘/other/data’;(创建时便指定加载)
>分区表:create table mydb.tab2(col1 string,...) partitioned by (year string,month string) row format delimited fields terminated by '\t';
>分桶表:create table mydb.tab2(col1 string,...) clustered by (type) into 10 buckets row format delimited fields terminated by ',';(这里其实还需要配置一些参数,暂略)
数据创建时,默认存储格式textfile;此外,常用的还有orcfile(通过对行记录块进行列存储并压缩,每个块提供一个存储),相比于textfile而言,对于大数据量,orcfile写入较慢,但查询和空间都比textfile更好(写入时需要启动解压缩)。下面的列表是对150万的数据进行的比照。很明显大数据量下orcfile对查询和磁盘占用更加友好。【补充:并不是所有的查询都会比textfile快】
IV、hive表的修改
>修改表名:alter table mydb.tab3 rename to mydb.tab2;
>修改列:alter table mydb.tab2 change column col_old col_new bigint [comment'修改示例'] after other_col;
>增加列:alter table mydb.tab2 add columns(col1 string ,col2 int.col3 bigint);
>删除列:alter table mydb.tab2 replace columns (var1 int comment '***' ,var2 bigint comment '***',.....) 仅保留这些字段,其他字段都将被删除
>增减分区:alter table mydb.tab2 add(/drop) if [not] exists partition(year='17',month='02') [....] ;
V、数据导入/导出hive
>数据导入
load data [local] inpath '/test/hive/data/' [overwrite] into table mydb.tab2 [partition (year='201709')];
说明:local参数指示为本地文件,无则为hdfs文件。overwrite是否为覆盖原有【分区】数据,partition为指定分区;
hive > load data local inpath '/home/shj/data/' into table mydb.tab_tmp;(说明,路径最好就是一个文件夹,hive将加载文件下的所有数据;对应的加载表应该已创建)
hive > load data inpath '/hive/warehouse/data/input/' into table mydb.tab_tmp_1 partition(year='2017');(hdfs中数据就move了,不同于本地的复制;注意inpath文件夹下不能含有文件夹)
除了load,还可以使用查询语句导入数据(hdfs)
hive > insert into mydb.tab2 select * from mydb.tab_tmp where conditions;
hive > create table mydb.tab2 as select * from mydb.tab_tmp where conditions;
>数据导出
insert overwrite [local] directory '/hive/data' select * from mydb.tab2 where conditions;(指定local则为本地文件,directory后面后文件夹,如果没有对应路径,会自动创建)
hive > insert overwrite directory 'home/shj/data/export/' select * from mydb.tab2 where conditions;(导出到本地,默认列分割符为'\t'。建表时的分隔符被取代)
hive > insert overwrite directory '/cluster/hive/warehouse/mydb.db/test/' select * from mydb.tab2 where conditions;(导出到hdfs,列分割符默认是'\001'即^A)
此外,常用的还是用hive -e/f > /directory/filename进行数据的导出。
hive中的查询
hql与t-sql还是有一定的差异的。这里我们谈谈join、排序和抽样。
join:hive中的join是只支持等值链接。也就是a join b on a.c1=b.c1;不支持非等值连接。此外,hive中除了支持常用的left join /right join /full outer join,还有一种join类型:left semi-join(左半开链接)。用来返回左边表记录,只要记录满足与右边表的on条件,是对in/exists的一种优化。(join优化将在后面单独说明。)
hive > select a.* from tab2 t1 left semi join tab_tmp t2 on t1.c1=t2.c1 and t1.c2=t2.c2;
排序:hive中可实现排序有distritute by 、sort by、order by。distribute by是在map输出时以什么样的方式到reduce中(多个reduce,根据什么key);sort by 是reduce完成后,单个reduce怎么将结果进行排序;order by是全局的排序,在一个reduce中完成。当数据量大时,order by将耗时较长。可以先指定distribute by 后指定sort by。实现输出的结果根据某些字段排序。当distribute by与sort by的字段相同时,则等同于cluster by。
hive > select * from tab2 distribute by c1,c2 sort by c1;
hive > select * from tab2 cluster by c1;
抽样:当数据很大时,就避免不了抽样。在hive中关键字tablesample实现,一种分桶抽样,一种数据块抽样。
hive > select * from mydb.tab2 tablesample(bucket 12 out of 1000 on rand()) s;(分母是分桶数,分子是指定桶序号;关键字rand()保障随机性,即同样两次抽样结果不同)
hive > select * from mydb.tab2 tablesample(0.02 percent) s;(百分比抽样,这里相当于10000中取2个)
hive参数调整
hive中的参数常常用于调优,设定map/reduce数,map-join,block大小,是否本地化等等。这个我们会在后期进行探讨和沟通。现在我们看看,使用CLI端,有哪些设置让操作更加舒适
> set hive.cli.print.header=true;设置输出是否带有表头(当我们输出文件时,没有表头可能对导入数据库和阅读带来一定影响。这个参数完美解决这个问题。)
> set hive.cli.print.current.db=true;显示当前数据库位置(可以使用use database;进行数据库切换)
> set hive.exec.parallel=true;允许任务并行,可以提高我们查询效率
未完待续!
原创博客,转载请注明出处!欢迎邮件沟通:shj8319@sina.com
hive(I)--学习总结之常用技能的更多相关文章
- Hive入门学习
Hive学习之路 (一)Hive初识 目录 Hive 简介 什么是Hive 为什么使用 Hive Hive 特点 Hive 和 RDBMS 的对比 Hive的架构 1.用户接口: shell/CLI, ...
- Java学习-005-初学常用的几个经典循环控制源代码
最近一段时间公司 App 改版,一直处在需求评审.代码评审.测试计划.测试用例.用例评审.用例执行.缺陷管理.测试总结的循环中,因而博客也好久没有更新了.虽然工作确实忙了点,但是也是自己懒惰了,从今天 ...
- Java学习中,常用的命令管理(Java 学习中的小记录)
Java学习中,常用的命令管理 作者:王可利(Star·星星) 一.Window中常见的dos命令 在哪里操作dos命令: Win7 ---> 开始 ---->所有程序---& ...
- IDEA第五章----Git常用技能
前几篇已经介绍了idea的环境搭建及基础配置常用模板等,这一章我们介绍下idea中git的一些常用技能,包括提交文件,排除提交文件,合并分支,解决冲突,还原代码等等等. 第一节:Git常用技能 Git ...
- ROS(indigo)机器人操作系统学习资料和常用功能包汇总整理(ubuntu14.04LTS)
ROS(indigo)机器人操作系统学习资料和常用功能包汇总整理(ubuntu14.04LTS) 1. 网站资源: ROSwiki官网:http://wiki.ros.org/cn GitHub ...
- redis学习-集合set常用命令
redis学习-集合set常用命令 1.sadd:添加一个元素到集合中(集合中的元素无序的并且唯一) 2.smembers:查看集合中所有的元素(上图事例) 3.srem:删除结合中指定的元素 4 ...
- redis学习-散列表常用命令(hash)
redis学习-散列表常用命令(hash) hset,hmset:给指定散列表插入一个或者多个键值对 hget,hmget:获取指定散列表一个或者多个键值对的值 hgetall:获取所欲哦键值以及 ...
- python3.4学习笔记(十) 常用操作符,条件分支和循环实例
python3.4学习笔记(十) 常用操作符,条件分支和循环实例 #Pyhon常用操作符 c = d = 10 d /= 8 #3.x真正的除法 print(d) #1.25 c //= 8 #用两个 ...
- python3.4学习笔记(六) 常用快捷键使用技巧,持续更新
python3.4学习笔记(六) 常用快捷键使用技巧,持续更新 安装IDLE后鼠标右键点击*.py 文件,可以看到Edit with IDLE 选择这个可以直接打开编辑器.IDLE默认不能显示行号,使 ...
随机推荐
- hibernate注解--@transient
@transient:表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性. 如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient,否则,ORM框架默认其注解为@Bas ...
- "SetDestination" can only be called on an active agent that has been placed on a NavMesh. 解决办法
1.设置了 navmesh之后 要bake 也就是烘焙之后 才有效果 2.在unity 中 window->navigation 4.基本上问题应该得以解决:
- 【JavaScript框架封装】实现一个类似于JQuery的属性框架的封装
// 属性框架 (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({ /** * 获取/设置某一个元素 ...
- ZOJ 2315 New Year Bonus Grant
New Year Bonus Grant Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on ZJU. Or ...
- js 阻止冒泡
$this.click(function(e){ e.stopPropagation(); });
- 洛谷—— P1262 间谍网络
https://www.luogu.org/problem/show?pid=1262 题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果A间谍手中掌握着关于B间谍的犯罪证据,则称A ...
- logstash tcp multihost output(多目标主机输出,保证TCP输出链路的稳定性)
在清洗日志时,有一个应用场景,就是TCP输出时,须要在一个主机挂了的情况下,自已切换到下一个可用入口.而原tcp output仅支持单个目标主机设定.故本人在原tcp的基础上,开发出tcp_multi ...
- 一个关于 UIPickerView 的 bug
首先,我下描写叙述一下bug的发生情况: 在使用UIPickerView实现选择城市的时候.出现这样一个Bug 1.在iOS 6的系统上 2.Picker的数据上省份一栏选择了"香港&quo ...
- .NET泛型初探
总所周知,.NET出现在.net framework 2.0,为什么要在2.0引入泛型那,因为微软在开始开发.net框架时并没有想过多个类型参数传输时对方法的重构,这样一来,开发人员就要面对传输多种类 ...
- @Autowired 凝视遇到的问题,@Qualifier 帮助解决这个问题
当候选 Bean 数目不为 1 时的应对方法 在默认情况下使用 @Autowired 凝视进行自己主动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个. 当找不到一个匹配的 Be ...