离线数据分析平台实战——130Hive Shell命令介绍 02(熟悉Hive略过)
导入数据
Hive的导入数据基本上可以分为三类, 第一种是从linux系统上导入数据到hive表中, 第二种是从hdfs上导入数据到hive表中, 第三种是从已有的hive表中导入数据到新的hive表中。
其中第一种和第二种语法基本类似; 在前面介绍的使用create table ... as... 命令创建表并导入数据,也属于第三种导入数据方法。 使用前两种方式导入数据,只是复制或者移动数据文件,并不会对数据的模式(数据类型)进行检查,对数据模式的检查要等到查询数据的时候才会进行。采用这种"schema on read"的模式可以提高数据加载效率。
导入数据命令
第一种命令和第二种命令的区别在于,
导入linux系统上的数据是进行文件复制,导入hdfs上的数据是进行文件移动。
也就是说在hdfs上进行数据的导入后,原位置的文件将不存在。命名如下:
load data [local] inpath 'filepath' [overwrite] into table tablename
。
使用local关键字来区分是从linux系统还是从hdfs上获取数据。
注意:
其实当不指定local的时候,数据来源是根据hadoop的fs.defaultFS和hive的hive.metastore.warehouse.dir来定义的,当然也可以指定路径的全部schema信息。
最后一种导入数据的命令其实我们是比较常用的一种,底层是使用mapreduce程序进行数据的导入操作的。命令如下:
INSERT (OVERWRITE|INTO) TABLE tablename1 select_statement1 FROM from_statement where_statement;
使用overwrite和into的区别在于,overwrite是进行重写操作,也就是说会将原始数据进行删除。
into是进行添加操作,原始数据不会进行删除。
注意:当我们将from语句提到最前面的时候,我们可以进行多表插入。
select命令详解
select命令和表中sql中的定义是一样的,都是查询数据表的数据,命令格式如下所示:
代码语言:javascript复制SELECT [ALL | DISTINCT] select_expr, select_expr, ... -- 返回的查询列表
FROM table_reference -- from语句,一般可以放到with之后,select之前
[WHERE where_condition] -- where过滤条件
[GROUP BY col_list [HAVING having_condition]] -- 分组条件
[ORDER|SORT BY colName (ASC|DESC)] -- 排序条件
[LIMIT number] -- limit条件
From语句
From语句主要是指定从那个数据表中查询数据,有两种使用方式:
分别可以在select后和with后&select前使用,
语法格式:
- [with ...] select ... from ...
- [with ...] from ... select ... 示例: select * from students; from students select *;
CTE语句
Common Table Expression(CTE)主要作用是保存临时结果,作为查询语句的公用部分,方便后面的select查询中重复使用。
语法规则为:
with cte_name [AS (select statment)] (,cte_name [AS (select statment)])* select ....
order/sort by语句
Order/Sort by语句主要用于hive中的数据排序,这两个命令的使用方式都类似sql语法中的order by。
两者的主要区别是:
sort by保证单reducer有序,order by保证全局有序,也就是说当reducer个数为多个的时候,使用sort by可能出现局部有序的情况。
另外对于order by操作,有一个小的限制,就是当hive.mapred.mode模式为strict的时候,在order by语句后面必须跟着limit语句。
语法格式如下:
(order|sort) by colname [asc|desc] (,colname [asc|desc])*
Join语法
在多表查询的时候,由于表与表之间有关联性,所有hive提供了join的语法,基本类似sql的join语法。
主要分为以下五类:
- 内连接(JOIN)
- 外链接({LEFT|RIGHT|FULL} [OUTER] JOIN)
- 半连接(LEFT SEMI JOIN)
- 笛卡尔连接(CROSS JOIN)
- 其他连接方式(eg. mapjoin等)
语法格式:
left_table_reference [join type] right_table_ref [join_condition]* ([join type] right_table_ref [join_condition]*)*
使用join建议&问题
- 等值连接:hive中的所有连接条件必须为等值连接条件,不支持<>等非等值连接方式。
- 多表连接:多表连接的时候,一般先进行left semi join,然后再进行join, 再进行外连接。(减少数据量)。
- join过滤条件,可以将where的过滤条件移动到join的过滤条件中去,这样可以减少网络数据量。
- join执行顺序都是从左到右,不管是那种join方式,那么一般将大的表放到右边,这样可以节省内存&减少网络传输。
- mapjoin只适合连接表是小表的情况,是一种空间换时间的解决方案。
内连接语法
内连接(JOIN)主要作用是获取连接的两张表全部匹配的数据,如果不给定join_condition的话,会进行笛卡尔乘积。
笛卡尔连接(CROSS JOIN)和内连接语法一样,区别在于:笛卡尔连接是对内连接的一种优化。
语法格式为:
table_reference [cross] join table_factor [join_condition]
外连接语法
外连接的主要作用是保留一部分没有匹配的数据。
左外连接(LEFT OUTER JOIN)的结果是包括左表中的所有行,如果左表中的某一个行在右表中不存在,那么则在相关联的结果集中右表的所有选择列值均设置为空值。
右外连接(RIGHT OUTER JOIN)就是左外连接的反先连接,将返回右表的所有行,左表进行空值填充。
全外连接(FULL OUTER JOIN)返回左表和右表的所有行,关联表中没有匹配值的直接设置为空值。
语法格式为:
table_reference {left|right|full} [outer] join table_factor join_condition
半连接语法
半连接(LEFT SEMI JOIN)是hive特有的,hive中不支持in/exists操作,所以hive提供了一个替代方案。
需要注意的是,被连接的表(右表),不能出现在查询列/其他部分(where等)中,只能出现在on字句中。(出现也是无效的)。
提出半连接的主要作用其实是提高查询效率,真正来讲的话,hive中可以使用其他连接方式来代替半连接,但是就效率而已的话,还是半连接比较高效。
语法格式:
table_reference LEFT SEMI JOIN table_factor join_condition
mapjoin
如果所有被连接的表都是小表,那么可以使用mapjoin,将需要连接的表数据全部读入mapper端内存中。
也就是说你使用mapjoin的前提就是你的连接数据比较小,mapjoin需要和其他join方式一起使用,一般情况下使用mapjoin的时候,推荐使用内连接。
语法格式为:
select /* MAPJOIN(table_ref1) */ ... from table_ref join table_ref1 on ....;
子查询语法
Hive对子查询的支持有限,只支持嵌套select子句,而且只能在from和with语句块中使用子查询。
语法规则如下:
.... from (select statement) [[as] tmp_name]....
导出数据
Hive中导出数据主要分为两大类,
分别是导出数据到linux系统和导出数据到hdfs文件系统上。
另外也可以认为导出数据到其他hive表也算导出数据(不过该方式也是导入数据)。
命令如下:
INSERT OVERWRITE [LOCAL] DIRECTORY directory1 [row format row_format] [stored as file_format] SELECT ... FROM ...
注意:hive导出数据支持一次导出到多个文件夹中,同多表同时导入数据一样。
其他常用命令&组件
union: 进行数据合并,格式为:
select1 union all select2... union all selectn
explain: hql执行计划查询。格式为: explain hql
hive -e "hql"
:在linux系统中执行hive语句。
hive -f "filepath"
: 执行linux系统中的包含hive语句的文件。
view:hive支持视图的使用,单只支持逻辑视图,不支持物理视图。
使用语法和table类型,创建语法格式为: create view viewname as select_statement