初识HIVE

858 阅读6分钟

什么是HIVE?HIVE是建立在Hadoop HDFS上的数据仓库基础架构,它可以用来进行数据的提取转换加载。HIVE定义了简单的类似SQL的查询语言HQL,HIVE会将解析后的语句转移成MapReduce Job在Hadoop执行,一张Hive的表其实就是HDFS的文件

HIVE的元数据,用来描述表本身信息,存储在deby中

HIVE中一些表的概念

  • 管理表:也称作内部表,删除这张表的同时,数据也会被删除;
  • 外部表:创建时用external标识,hive没有完全拥有这张表的数据,删除外部表只会删除hive中元数据,而数据仍会保留;
  • 分区表:是管理表和外部表在创建时指定的一种水平分散压力的方式,在创建表时,通过语句PARTITION BY指定,查询可以通过where语句添加分区字段进行过滤(分区过滤器)
  • 桶表:对数据进行哈希取值,然后放到不同文件中存储
  • view :基本语法是 create view view_name(col_1,col_2,col_n) as select XXX,视图是只读的,不能修改里面的内容,只能改元数据属性

hive建表的时候默认的分割符是'\001'

HIVE支持的一些基本数据结构

  • 基本类型: TINYINT SMALLINT INT BIGINT BOOLEAN FLOAT DOUBLE STRING TIMESTAMP BINARY(字节数组)
  • 集合数据类型:STRUCT(一旦声明好,位置不可以改变) MAP ARRAY

集合声明:ARRAY<String>,MAP<String,String>,STRUCT<f1:STRING,f2:STRING>

HIVE 的一些特性

  • 读时模式:hive不会在数据加载时进行验证,这个过程发生在查询
  • 数据格式不匹配处理:如果发现表的字段少于要查的字段,会返回null,如果发现类型不对也会返回null
  • 默认库default没有目录,会直接存在于默认仓库下面(/user/hive/warehouse)
  • 查询的数据类型是集合类型,会优先以json的方式输出
  • hive.exec.mode.local.auto=true设定可以不触发mapreduce操作,hive会尝试本地模式,比如简单的查询10条数据,不需要mapreduce select * from table limit 10
  • hive默认数据最大的那个表是最后那张表,会把之前的表缓存起来,因此,查询的时候,最好表的大小是从左到右依次增加的
  • namenode会加载所有分区的元数据
  • hive支持列存储,适用于字段很多(成百上千),但是查询确只是用于几个较少的字段,RCFile,使用列式存储进行压缩比较高效,并且部分列式存储不需要物理存储null值的列

HIVE的一些基本查询语法

  • 查看数据库的位置:describe database database_name
  • 查看表的属性:describe extended table_name
  • 查看某个表的的分区:SHOW PARTITIONS TABLE_NAME
  • 查询数组:可以通过下标的方式查找,如arr[0],map元素可以使用数组的键值查询,如arr[key_name],struct则可以使用点的方式访问,如arr.field_name
  • CASE WHERN THEN,用来处理单列 CASE 相当于java中SWITCH的用法:
case 
   when s<100 then 'low'
   when s>100 then 'high'
   else 'hundred'
end as brancket
  • where语句中不能使用别名,可以通过嵌套成一张表的方式,来获取字段 ,以下方式是无效的 select A as a from table where a>0 可以使用 selct e.* from (select A as a from table) e where e.a>0 解决
  • RLIKE中 点号(.)代表和任意字符匹配,星号(*)代表重复左边的字符串零次到无数次,(x|y)表示和x或者y匹配,LIKE中 % 表示匹配任意字符任意长度
  • union all:将两个或多个表进行合并,每一个union子查询都必须具有相同的列
  • inner join,带on条件,左右两个表都有值的时候,才输出;
  • left outer join,符合where条件的左表有值就输出,右表没有用NULL代替;
  • right outer join 符合where条件的右表有值就输出,左表没有用NULL代替;
  • full outer join,返回符合where条件的所有记录,两边都没有用NULL代替;
  • left semi join 符合where条件左表以及符合on的右表会被返回;
  • 笛卡尔join直接使用join不带条件;
  • mapjoin则指的是缓存小表的数据,达到优化查询速度的目的

right outer join和full outer join不支持

hive查询的时候,如果行的数据比预期的少,那么缺少的字段会返回null,如果行的数据比预期的多会忽略,比如查询map的某个key,没有会返回NULL

HIVE中的排序

  • distribute by:控制一行数据是如何被reducer处理,必须放在group by之前,配合 sort by则可以对每个reducer进行排序;

如果 distribute by和sort by的字段完全一致,并且都是升序排列,那么可以用cluster by代替,区别在于cluster by 的排序是全局排序的,但是是以去掉并行性为代价

  • sort by:是对每个ruducer排序,多个reducer顺序不一样,速度会快于order by ,order by是全局排序

动态分区与静态分区

  • 静态分区:在从一个表获取数据插入另外一张表的时候(insert),如果要保留原有的分区信息,或者创建新的分区,直接指定数据分区的名字,比如 country=“china”

  • 动态分区:直接使用字段的值,比如 insert table A select …,b.country from b

默认情况下动态分区是关闭的,一般情况下,会要求至少有一个静态分区,这样可以避免设计错误而导致大量的分区

数据导入与导出

导入hive:load data local inpath ‘./examples/files/kv1.txt’ overwrite into table pokes; 没有local就从hdfs中拿文件;用overwrite表示原来表中的数据都会被清除,没有overwrite数据就会追加到表的后面。

load data的时候,源文件和目标文件以及目录都应该在同一个文件系统中

导出数据:由于hive存储在hdfs中,以文件方式存储(有默认的分隔符)。如果只需要文件,可以直接通过hadoop fs -cp source_path target_path的方式直接拷贝

可以用专门的工具sqoop

数据装载有无local的区别

load data local 是对数据的一份拷贝,而没有local(load data)则是数据的转移,hive认为分布式系统中不需要多份的数据备份

附录

本文来自<HIVE 编程指南>。推荐。可以理解HIVE的基本概念