Hadoop之Hive(使用篇)

Posted _TIM_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hadoop之Hive(使用篇)相关的知识,希望对你有一定的参考价值。

创建数据库

create database if not exists myhive;
use myhive;

设置数据库键值对信息

create database foo with dbproperties ('owner'='itcast', 
'date'='20190120');

删除数据库

drop database myhive2;

创建表的语法

create [external] table [if not exists] table_name (
col_name data_type [comment '字段描述信息']
col_name data_type [comment '字段描述信息'])
[comment '表的描述信息']
[partitioned by (col_name data_type,...)]
[clustered by (col_name,col_name,...)]
[sorted by (col_name [asc|desc],...) into num_buckets buckets]
[row format row_format]
[storted as ....]
[location '指定表的路径']

external 可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径,Hive 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据

partitioned by 表示使用表分区,一个表可以拥有一个或者多个分区,每一个分区单独存在一个目录下
clustered by 对于每一个表分文件, Hive可以进一步组织成桶,也就是说桶是更为细粒
度的数据范围划分。Hive也是 针对某一列进行桶的组织

外部表
外部表因为是指定其他的hdfs路径的数据加载到表当中来,所以hive表会认为自己不完全独占这份数据,所以删除hive表的时候,数据仍然存放在hdfs当中,不会删掉

内部表和外部表的使用场景
每天将收集到的网站日志定期流入HDFS文本文件。在外部表(原始日志表)的基础上做大量的统计分析,用到的中间表、结果表使用内部表存储,数据通过SELECT+INSERT进入内部表

分区表

分区是指按照数据表的某列或某些列分为多个区,区从形式上可以理解为文件夹,比如我们要收集某个大型网站的日志数据,一个网站每天的日志数据存在同一张表上,由于每天会生成大量的日志,导致数据表的内容巨大,在查询时进行全表扫描耗费的资源非常多。那其实这个情况下,我们可以按照日期对数据表进行分区,不同日期的数据存放在不同的分区,在查询时只要指定分区字段的值就可以直接从该分区查找。

分桶表
分桶就是将数据按照指定的字段进行划分到多个文件当中去,分桶就是MapReduce中的分区

分桶是相对分区进行更细粒度的划分。分桶将整个数据内容按照某列属性值的hash值进行区分,如要按照name属性分为3个桶,就是对name属性值的hash值对3取摸,按照取模结果对数据分桶。如取模结果为0的数据记录存放到一个文件,取模为1的数据存放到一个文件,取模为2的数据存放到一个文件。

区别

  1. 分桶随机分割数据库,分区是非随机分割数据库。因为分桶是按照列的哈希函数进行分割的,相对比较平均;而分区是按照列的值来进行分割的,容易造成数据倾斜。
  2. 分桶是对应不同的文件(细粒度),分区是对应不同的文件夹(粗粒度)。桶是更为细粒度的数据范围划分,分桶的比分区获得更高的查询处理效率,使取样更高效。
  3. 注意:普通表(外部表、内部表)、分区表这三个都是对应HDFS上的目录,桶表对应是目录里的文件。

结合项目中使用
在逻辑上分区表与未分区表没有区别,在物理上分区表会将数据按照分区键的列值存储在表目录的子目录中,目录名=“分区键的键值”。其中需要注意的是分区键的值不一定要基于表的某一列(字段),它可以指定任意值,只要查询的时候指定相应的分区键来查询即可。我们可以对分区进行添加、删除、重命名、清空等操作。因为分区在特定的区域(子目录)下检索数据,作为where查询条件,可以减少扫描成本。

分桶则是指定分桶表的某一列,让该列数据按照哈希取模的方式随机、均匀地分发到各个桶文件中。因为分桶操作需要根据某一列具体数据来进行哈希取模操作,故指定的分桶列必须基于表中的某一列(字段)。因为分桶改变了数据的存储方式,它会把哈希取模相同或者在某一区间的数据行放在同一个桶文件中。

如此一来便可提高查询效率,如:我们要对两张在同一列上进行了分桶操作的表进行JOIN操作的时候,只需要对保存相同列值的桶进行JOIN操作即可。同时分桶也能让取样(Sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。

Hive 查询语法

由于Hive是类SQL语言,所一基本语法相似,在这里不做展示

SELECT [ALL | DISTINCT] select_expr, select_expr, ...
FROM table_reference
[WHERE where_condition]
[GROUP BY col_list [HAVING condition]]
[CLUSTER BY col_list
| [DISTRIBUTE BY col_list] [SORT BY| ORDER BY col_list]
]
[LIMIT number]
  1. order by 会对输入做全局排序,因此只有一个reducer,会导致当输入规模较大时,需要
    较长的计算时间。
  2. sort by不是全局排序,其在数据进入reducer前完成排序。因此,如果用sort by进行排
    序,并且设置mapred.reduce.tasks>1,则sort by只保证每个reducer的输出有序,不保证全
    局有序。
  3. distribute by(字段)根据指定的字段将数据分到不同的reducer,且分发算法是hash散列。
  4. cluster by(字段) 除了具有distribute by的功能外,还会对该字段进行排序.

因此,如果distributesort字段是同一个时,此时,cluster by = distribute by + sort by

自定义函数UDF

Hive自带了一些函数,比如:max/min等,当Hive提供的内置函数无法满足你的业务处
理需要时,此时就可以考虑使用用户自定义函数UDF
Step 1 创建 Maven 工程
Step 2 开发Java类集成UDF

public class MyUDF  extends UDF
    public Text evaluate(final Text str)
        String tmp_str = str.toString();
        if(str != null && !tmp_str.equals(""))
          String str_ret =   tmp_str.substring(0, 1).toUpperCase() +
tmp_str.substring(1);
          return  new Text(str_ret);
       
        return  new Text("");
   

Step 3 项目打包,并上传到hivelib目录下
Step 4 添加jar
Step 5 设置函数与我们的自定义函数关联
Step 6 使用自定义函数

Hive的数据存储格式

Hive支持的存储数的格式主要有:TEXTFILE(行式存储) 、SEQUENCEFILE(行式存储)、
ORC(列式存储)、PARQUET(列式存储)

以上是关于Hadoop之Hive(使用篇)的主要内容,如果未能解决你的问题,请参考以下文章

Hadoop之Hive函数

Hadoop之Hive的排序

(第7篇)灵活易用易维护的hadoop数据仓库工具——Hive

Hadoop之Hive的Join语句

hive优化之小文件合并

大数据学习系列之六 ----- Hadoop+Spark环境搭建