目录
[Hive 分区Hive 中的表分区比较简单,就是将同一组数据放到同一个 HDFS 目录下,当查询中过滤条件指定了某一个分区值时候,只将该分区对应的目录作为 Input,从而减少 MapReduce 的输入数据,提高查询效率。](#Hive 分区Hive 中的表分区比较简单,就是将同一组数据放到同一个 HDFS 目录下,当查询中过滤条件指定了某一个分区值时候,只将该分区对应的目录作为 Input,从而减少 MapReduce 的输入数据,提高查询效率。)
[动态分区启用 Hive 动态分区,只需要在 Hive 会话中设置两个参数:](#动态分区启用 Hive 动态分区,只需要在 Hive 会话中设置两个参数:)
[map类型Hive 之所以能在大数据领域比较受欢迎,很大一部分原因在于相比其他SQL类存储系统支持更加复杂的数据类型,map 就是其中一种。](#map类型Hive 之所以能在大数据领域比较受欢迎,很大一部分原因在于相比其他SQL类存储系统支持更加复杂的数据类型,map 就是其中一种。)
[编程要求平台中有一个表 employee, 建表的语法如下:](#编程要求平台中有一个表 employee, 建表的语法如下:)
Hive动态分区中的视图和map类型
相关知识
Hive 分区
Hive 中的表分区比较简单,就是将同一组数据放到同一个 HDFS 目录下,当查询中过滤条件指定了某一个分区值时候,只将该分区对应的目录作为 Input,从而减少 MapReduce 的输入数据,提高查询效率。
创建一个分区的案例如下:
- CREATE EXTERNAL TABLE t_lxw1234 (
- id INT,
- ip STRING COMMENT '访问者IP',
- avg_view_depth DECIMAL(5,1),
- bounce_rate DECIMAL(6,5)
- ) COMMENT 'lxw的大数据田地-lxw1234.com'
- PARTITIONED BY (month STRING, day STRING)
- ROW FORMAT DELIMITED
- FIELDS TERMINATED BY ','
- STORED AS textfile;
在创建表时候,使用 PARTITIONED BY 关键字来指定该表为分区表,后面括号中指定了分区的字段和类型,分区字段可以有多个,在 HDFS 中对应多级目录。
比如,上面的表 t_lxw1234 分区 month='2015-06',day='2015-06-15'对应 HDFS 上的路径为:/user/hive/warehouse/default.db/t_lxw1234/month=2015-06/day=2015-06-15/,当查询中指定了 month='2015-06' AND day='2015-06-15',MapReduce 直接从该目录中读取数据,如果只指定了 month='2015-06',那么 MapReduce 将 /month=2015-06/ 下所有的子目录都作为 Input。
对以上案例进行分区操作入下:
分区追加数据:INSERT INTO TABLE t_lxw1234 PARTITION (month = '2015-06',day = '2015-06-15') SELECT * FROM dual;
使用INSERT添加分区:ALTER TABLE t_lxw1234 ADD PARTITION (month = '2015-06',day = '2015-06-15') location 'hdfs://namenode/tmp/lxw1234/month=2015-06/day=2015-06-15/';
查看表的所有分区:show partitions t_lxw1234;
删除分区:ALTER TABLE t_lxw1234 DROP PARTITION (month = '2015-01', day = '2015-01-25');
动态分区
启用 Hive 动态分区,只需要在 Hive 会话中设置两个参数:
- set hive.exec.dynamic.partition=true;
- set hive.exec.dynamic.partition.mode=nonstrict;
map类型
Hive 之所以能在大数据领域比较受欢迎,很大一部分原因在于相比其他SQL类存储系统支持更加复杂的数据类型,map 就是其中一种。
案例:
-
map结构的表结构创建
- hive> create table employee(id string, perf map<string, int>)
- > ROW FORMAT DELIMITED
- > FIELDS TERMINATED BY '\t'
- > COLLECTION ITEMS TERMINATED BY ','
- > MAP KEYS TERMINATED BY ':';
-
原始数据格式
- 1 job:80,team:60,person:70
- 2 job:60,team:80
- 3 job:90,team:70,person:100
-
数据导入
- hive> LOAD DATA LOCAL INPATH '/home/work/data/test7.txt' INTO TABLE employee;
-
数据查询
- hive> select perf['person'] from employee;
- 70
- NULL
-
使用explode()函数查询
- hive> select explode(perf) as (p_name,p_score) from employee limit 4;
- job 80
- team 60
- person 70
-
使用explode()和lateral view结合查询
- hive> select id,p_name,p_score from employee lateral view explode(perf) perf as p_name,p_score limit 3;
- 1 job 80
- 1 team 60
- 1 person 70
-
使用size()函数查看map结构中的键值对个数[也可查看array中的元素个数]
- hive> select size(perf) from employee
- 3
- 2
- 3
编程要求
根据提示,在右侧编辑器补充代码。
平台中创建了一个带有 map 类型字段的表,创建语法如下:
- create table person(id int, name string, family map<string, string>)
- > ROW FORMAT DELIMITED
- > FIELDS TERMINATED BY ' '
- > COLLECTION ITEMS TERMINATED BY ','
- > MAP KEYS TERMINATED BY ':';
导入的数据格式为:
- 1 Mary ma:Maria,fa:Bob,da:Lily,son:John
- 2 Bob ma:Kristin,fa:Leon,da:Mary
- 3 John ma:Maria,fa:Bob,son:David
请你建立一个视图 children_of_Maria,存放所有母亲叫做 Maria 的人的信息。
create view children_of_Maria
as
select id, name, family
from person
where family['ma'] = 'Maria';
Hive使用视图降低查询复杂度
编程要求
平台中有一个表 employee, 建表的语法如下:
- CREATE TABLE IF NOT EXISTS employee(
- Id int,
- Name string,
- Salary int,
- Designation string,
- Dept string
- )
- row format delimited
- fields terminated by','
- lines terminated by'\n'
- stored as textfile;
导入的数据如下:
- 1201,Mary,45000,Technical manager,TP
- 1201,Bob,45000,Proofreader,PR
- 1203,Kristin,40000,Technical writer,TP
- 1204,Krian,40000,Hr Admin,HR
- 1205,Krathi,30000,Op Admin,Admin
- 1206,John,45000,Technical manager,TP
- 1207,Jake,50000,Proofreader,PR
- 1208,Adela,60000,Technical writer,TP
- 1209,Betty,55000,Hr Admin,HR
- 1210,Sam,40000,Op Admin,Admin
你需要在右边的代码框中编写 Hive SQL 语句。实现选出所有 Salary 超过 50000 的人的信息存为视图 rich ,然后展示视图的信息。
CREATE VIEW IF NOT EXISTS rich AS
SELECT *
FROM employee
WHERE Salary > 50000;