# Hive 简介

Hive 是 Facebook 开源的一款基于 Hadoop 的数据仓库工具,是目前应用最广泛的大数据处理解决方案,它能将 SQL 查询转变为 MapReduce(Google 提出的一个软件架构,用于大规模数据集的并行运算)任务,对 SQL 提供了完美的支持,能够非常方便的实现大数据统计。

<img src="https://gitee.com/jackfrued/mypic/raw/master/20220210080608.png">

说明:可以通过 https://www.edureka.co/blog/hadoop-ecosystem 来了解 Hadoop 生态圈。

如果要简单的介绍 Hive,那么以下两点是其核心:

  1. 把 HDFS 中结构化的数据映射成表。
  2. 通过把 Hive-SQL 进行解析和转换,最终生成一系列基于 Hadoop 的 MapReduce 任务 / Spark 任务,通过执行这些任务完成对数据的处理。也就是说,即便不学习 Java、Scala 这样的编程语言,一样可以实现对数据的处理。

Hive 和传统关系型数据库的对比如下表所示。

HiveRDBMS
查询语言HQLSQL
存储数据HDFS本地文件系统
执行方式MapReduce / SparkExecutor
执行延迟
数据规模

# 准备工作

  1. 搭建如下图所示的大数据平台。

    bigdata-basic-env

  2. 通过 Client 节点访问大数据平台。

    bigdata-vpc

  3. 创建文件 Hadoop 的文件系统。

    hadoop fs -mkdir /data
    hadoop fs -chmod g+w /data
    
  4. 将准备好的数据文件拷贝到 Hadoop 文件系统中。

    hadoop fs -put /home/ubuntu/data/* /data
    

# 创建 / 删除数据库

创建。

create database if not exists demo;

hive -e "create database demo;"

删除。

drop database if exists demo;

切换。

use demo;

# 数据类型

Hive 的数据类型如下所示。

基本数据类型。

数据类型占用空间支持版本
tinyint1-Byte
smallint2-Byte
int4-Byte
bigint8-Byte
boolean
float4-Byte
double8-Byte
string
binary0.8 版本
timestamp0.8 版本
decimal0.11 版本
char0.13 版本
varchar0.12 版本
date0.12 版本

复杂数据类型。

数据类型描述例子
struct和 C 语言中的结构体类似struct<first_name:string, last_name:string>
map由键值对构成的元素的集合map<string,int>
array具有相同类型的变量的容器array<string>

# 创建和使用表

  1. 创建内部表。

    create table if not exists user_info 
    (
    user_id string,
    user_name string, 
    sex string,
    age int,
    city string,
    firstactivetime string,
    level int,
    extra1 string,
    extra2 map<string,string>
    )
    row format delimited fields terminated by '\t'
    collection items terminated by ','
    map keys terminated by ':'
    lines terminated by '\n'
    stored as textfile;
    
  2. 加载数据。

    load data local inpath '/home/ubuntu/data/user_info/user_info.txt' overwrite into table user_info;
    

    load data inpath '/data/user_info/user_info.txt' overwrite into table user_info;
    
  3. 创建分区表。

    create table if not exists user_trade 
    (
    user_name string,
    piece int,
    price double,
    pay_amount double,
    goods_category string,
    pay_time bigint
    )  
    partitioned by (dt string)
    row format delimited fields terminated by '\t';
    
  4. 设置动态分区。

    set hive.exec.dynamic.partition=true;
    set hive.exec.dynamic.partition.mode=nonstrict;
    set hive.exec.max.dynamic.partitions=10000;
    set hive.exec.max.dynamic.partitions.pernode=10000;
    
  5. 拷贝数据(Shell 命令)。

    hdfs dfs -put /home/ubuntu/data/user_trade/* /user/hive/warehouse/demo.db/user_trade
    
  6. 修复分区表。

    msck repair table user_trade;
    

# 查询

# 基本语法

select user_name from user_info where city='beijing' and sex='female' limit 10;
select user_name, piece, pay_amount from user_trade where dt='2019-03-24' and goods_category='food';

# group by

-- 查询2019年1月到4月,每个品类有多少人购买,累计金额是多少
select goods_category, count(distinct user_name) as user_num, sum(pay_amount) as total from user_trade where dt between '2019-01-01' and '2019-04-30' group by goods_category;
-- 查询2019年4月支付金额超过5万元的用户
select user_name, sum(pay_amount) as total from user_trade where dt between '2019-04-01' and '2019-04-30' group by user_name having sum(pay_amount) > 50000;

# order by

-- 查询2019年4月支付金额最多的用户前5名
select user_name, sum(pay_amount) as total from user_trade where dt between '2019-04-01' and '2019-04-30' group by user_name order by total desc limit 5;

# 常用函数

  1. from_unixtime :将时间戳转换成日期
  2. unix_timestamp :将日期转换成时间戳
  3. datediff :计算两个日期的时间差
  4. if :根据条件返回不同的值
  5. substr :字符串取子串
  6. get_json_object :从 JSON 字符串中取出指定的 key 对应的 value ,如: get_json_object(info, '$.first_name')