Hive初体验(hello hive)

不念不忘少年蓝@ 2023-03-01 09:25 11阅读 0赞

什么是Hive

Hive:由Facebook开源用于解决海量结构化日志的数据统计。

Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL查询功能。

本质是:将HQL转化成MapReduce程序

  1. Hive处理的数据存储在HDFS
  2. Hive分析数据底层的实现是MapReduce
  3. 执行程序运行在Yarn上

Hive的优缺点

优点

  1. 操作接口采用类SQL语法,提供快速开发的能力(简单、容易上手)。
  2. 避免了去写MapReduce,减少开发人员的学习成本。
  3. Hive的执行延迟比较高,因此Hive常用于数据分析,对实时性要求不高的场合。
  4. Hive优势在于处理大数据,对于处理小数据没有优势,因为Hive的执行延迟比较高。
  5. Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数。

缺点

1.Hive的HQL表达能力有限

(1)迭代式算法无法表达

(2)数据挖掘方面不擅长

2.Hive的效率比较低

(1)Hive自动生成的MapReduce作业,通常情况下不够智能化

(2)Hive调优比较困难,粒度较粗

Hive架构原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-on8dTpdT-1595483794182)(…/…/…/…/Pictures/Typora/clip_image002.png)]

  1. 用户接口:Client
    CLI(hive shell)、JDBC/ODBC(java访问hive)、WEBUI(浏览器访问hive)
  2. 元数据:Metastore
    元数据包括:表名、表所属的数据库(默认是default)、表的拥有者、列/分区字段、表的类型(是否是外部表)、表的数据所在目录等;
    默认存储在自带的derby数据库中,推荐使用MySQL存储Metastore
  3. Hadoop
    使用HDFS进行存储,使用MapReduce进行计算。
  4. 驱动器:Driver

    1. 解析器(SQL Parser):将SQL字符串转换成抽象语法树AST,这一步一般都用第三方工具库完成,比如antlr;对AST进行语法分析,比如表是否存在、字段是否存在、SQL语义是否有误。
    2. 编译器(Physical Plan):将AST编译生成逻辑执行计划。
    3. 优化器(Query Optimizer):对逻辑执行计划进行优化。
    4. 执行器(Execution):把逻辑执行计划转换成可以运行的物理计划。对于Hive来说,就是MR/Spark。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CmQRasEk-1595483794183)(…/…/…/…/Pictures/Typora/clip_image002-1594110789219.png)]

Hive通过给用户提供的一系列交互接口,接收到用户的指令(SQL),使用自己的Driver,结合元数据(MetaStore),将这些指令翻译成MapReduce,提交到Hadoop中执行,最后,将执行返回的结果输出到用户交互接口。

Interface-命令窗口模式:

  • 两种工具:beeline 和 Hive命令行(CLI)
  • 两种模式:命令行模式和交互模式

Hive-数据类型

###原始数据类型






















































类型 示例 类型 示例
TINYINT 10Y SMALLINT 10S
INT 10 BIGINT 100L
FLOAT 1.342 DOUBLE 1.234
DECIMAL 3.14 BINARY 1010
BOOLEAN TRUE STRING ’Book’ or “Book”
CHAR ‘YES’ or “YES” VARCHAR ‘Book’ or “Book”
DATE ‘2013-01-31’ TIMESTAMP ‘2013-01-31 00:13:00.345’

复杂数据类型






























类型 格式 定义 示例
ARRAY [‘Apple’,’Orange’,’Mongo’] ARRAY a[0] = ‘Apple’
MAP {‘A’:’Apple’,’O’:’Orange’} MAP<string, string> b[‘A’] = ‘Apple’
STRUCT {‘Apple’, 2} STRUCT<fruit:string, weight:int> c.weight = 2
  • ARRAY:存储的数据为相同类型
  • MAP:具有相同类型的键值对
  • STRUCT:封装了一组字段

Hive元数据结构




























































数据结构 描述 逻辑关系 物理存储(HDFS)
Database 数据库 表的集合 文件夹
Table 行数据的集合 文件夹
Partition 分区 用于分割数据 文件夹
Buckets 分桶 用于分布数据 文件
Row 行记录 文件中的行
Columns 列记录 每行中指定的位置
Views 视图 逻辑概念,可跨越多张表 不存储数据
Index 索引 记录统计数据信息 文件夹

数据库(Database)

  • 默认在hive.metastore.warehouse.dir属性目录下
  • 如果没有指定数据库,默认使用default数据库

如何知道和显示当前所在数据库?

select current_database();

创建表

分为内部表和外部表

内部表(管理表)

  • HDFS中为数据库所属目录下的子文件夹
  • 数据完全由Hive管理,删除表(元数据)会删除数据,不适合和其他工具共享数据

    普通创建表

    create table if not exists student2(
    id int, name string
    )
    row format delimited fields terminated by ‘\t’
    stored as textfile
    location ‘/user/hive/warehouse/student2’;

    根据查询结果创建表(查询的结果会添加到新创建的表中)

    create table if not exists student3 as select id, name from student;

    根据已经存在的表结构创建表

    create table if not exists student4 like student;

外部表(External Tables)

  • 数据保存在指定位置的HDFS路径中
  • Hive不完全管理数据,删除表(元数据)不会删除数据

Hive内部表和外部表概念?区别?最适合的应用场景?
默认创建的表,
内部表数据保存在数据库所在目录中,删除表会删除表数据+元数据
外部表数据保存在指定目录,删除表只删除元数据
当表中所有数据都需要有Hive管理时,使用管理表,否则使用外部表

  1. CREATE EXTERNAL TABLE IF NOT EXISTS employee_external (
  2. name string,
  3. work_place ARRAY<string>,
  4. sex_age STRUCT<sex:string,age:int>,
  5. skills_score MAP<string,int>,
  6. depart_title MAP<STRING,ARRAY<STRING>>
  7. )
  8. COMMENT 'This is an external table'
  9. ROW FORMAT DELIMITED
  10. FIELDS TERMINATED BY '|'
  11. COLLECTION ITEMS TERMINATED BY ','
  12. MAP KEYS TERMINATED BY ':'
  13. STORED AS TEXTFILE
  14. LOCATION '/user/root/employee';

外部表与内部表的相互转换

  1. #1.查询表的类型
  2. desc formatted cust_action(表名);
  3. Table Type: | EXTERNAL_TABLE
  4. #2.修改内部表cust_action为外部表
  5. alter table cust_action set tblproperties('EXTERNAL'='TRUE');
  6. #3.查询表的类型
  7. desc formatted cust_action;
  8. #4.修改外部表cust_action为内部表
  9. alter table cust_action set tblproperties('EXTERNAL'='FALSE');
  10. #5.查询表的类型
  11. desc formatted cust_action;

分区(partition)

为了搜索(一般用于DWD层,根据最终业务(你想怎么查)分区)

  • 分区主要用于提高性能

    • 分区列的值将表划分为一个个的文件夹
    • 查询时语法使用”分区”列和常规列类似
    • 查询时Hive会只从指定分区查询数据,提高查询效率
  • 分为静态分区和动态分区

静态分区

创建分区表
  1. create table if not exists employee_partitioned(
  2. name string,
  3. employee_id int,
  4. number string
  5. )
  6. partitioned by (year int,month int)
  7. row format delimited
  8. stored as textfile;
添加分区和删除分区
  1. # 添加分区
  2. alter table employee_partititoned add partition(year=2020,month=3)partition(year=2020,month=4);
  3. # 删除分区
  4. alter table employee_partititoned drop partition(year=2020,month=3),partition(year=2020,month=4);
查看分区
  1. - 查看分区表有多少分区
  2. show partitions employee_partititoned;
向分区表中加在数据
  1. load data local inpath '/opt/datas/employee.txt' into table employee_partititoned partition(year=2020,month=3);

动态分区

动态分区建表语句和静态分区相同,动态分区需要设定属性

  1. 1.开启动态分区
  2. set hive.exec.dynamic.partition=true;
  3. 2.设置非严格模式
  4. set hive.exec.dynamic.partition.mode=nonstrict;
动态分区插入数据
  1. insert into table employee_hr partition(year,month)
  2. select name,employee_id,number,year(start_date)as year,month(start_date) as month
  3. from employee_hrr;

分桶(Bucket)

  • 分桶对应于HDFS中的文件(一般为了抽样更高效)
  • 分桶只有动态分桶,首先需设定属性

    1. SET hive.enforce.bucketing = true;
  • 必须使用INSERT方式加载数据

定义分桶

  1. create table if not exists employee_buckets(
  2. name string,
  3. work_place array<String>,
  4. sex_age struct<sex:string,age:int>,
  5. skills_score map<string,int>,
  6. depart_title map<string,array<string>>
  7. )
  8. clustered by (name) into 2 buckets
  9. row format delimited
  10. fields terminated by '|'
  11. collection items terminated by ','
  12. map keys terminated by':'
  13. stored as textfile ;

分桶的列(name)是表中已有的列
分桶数最好是2的n次方

分桶抽样(Sampling)

对于非常大的数据集,有时用户需要使用的是一个具有代表性的查询结果而不是全部结果。Hive可以通过对表进行抽样来满足这个需求。

  1. select * from employee_buckets tablesample(bucket 1 out of 4 on name);

tablesample是抽样语句,语法:TABLESAMPLE(BUCKET x OUT OF y)
y必须是table总bucket数的倍数或者因子。hive根据y的大小,决定抽样的比例。

例如,table总共分了4份,当y=2时,抽取(4/2=)2个bucket的数据,当y=8时,抽取(4/8=)1/2个bucket的数据。

x表示从哪个bucket开始抽取,如果需要取多个分区,以后的分区号为当前分区号加上y。

例如,table总bucket数为4,tablesample(bucket 1 out of 2),表示总共抽取(4/2=)2个bucket的数据,抽取第1(x)个和第3(x+y)个bucket的数据。

注意:x的值必须小于等于y的值

视图

保存hql语句,不存储数据

  1. -- 创建视图,支持 CTE, ORDER BY, LIMIT, JOIN,等
  2. CREATE VIEW view_name AS SELECT statement;
  3. -- 查找视图 (SHOW VIEWS hive v2.2.0之后)
  4. SHOW TABLES;
  5. -- 查看视图定义
  6. SHOW CREATE TABLE view_name;
  7. -- 删除视图
  8. DROP view_name;
  9. --更改视图属性
  10. ALTER VIEW view_name SET TBLPROPERTIES ('comment' = 'This is a view');
  11. -- 更改视图定义,
  12. ALTER VIEW view_name AS SELECT statement;

Hive侧视图(Lateral View)

与表生成函数结合使用,将函数的输入和输出连接
通常用于规范化行或解析JSON

OUTER关键字:即使output为空也会生成结果

  1. select name,work_place,loc from employee lateral view outer explode(split(null,',')) a as loc;

支持多层级

  1. select name,wps,skill,score from employee
  2. lateral view explode(work_place) work_place_single as wps
  3. lateral view explode(skills_score) sks as skill,score;

Hive内部表和外部表概念?区别?最适合的应用场景?
如何确定一个表是否为临时表?
如何知道查询的是表还是视图?
Hive分区表的作用?静态分区和动态分区的区别?

发表评论

表情:
评论列表 (有 0 条评论,11人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Hive

    一、Hive简介 1. **Facebook为了解决海量日志数据的分析而开发了Hive,后来开源给了Apache软件基金会。** 2. Hive是一种用类SQL语...