hive学习-问题解答一

1.简述Hive工作原理

答:hive学习-问题解答一

流程步骤为:

  1. 用户提交查询等任务给Driver。

  2. 编译器获得该用户的任务Plan。

  3. 编译器Compiler根据用户任务去MetaStore中获取需要的Hive的元数据信息。

  4. 编译器Compiler得到元数据信息,对任务进行编译,先将HiveQL转换为抽象语法树,然后将抽象语法树转换成查询块,将查询块转化为逻辑的查询计划,重写逻辑查询计划,将逻辑计划转化为物理的计划(MapReduce), 最后选择最佳的策略。

  5. 将最终的计划提交给Driver。

  6. Driver将计划Plan转交给ExecutionEngine去执行,获取元数据信息,提交给JobTracker或者SourceManager执行该任务,任务会直接读取HDFS中文件进行相应的操作。

  7. 获取执行的结果。

  8. 取得并返回执行结果。

其他版本(简化):

  1、执行查询:Hive接口,命令行或 web UI发送查询驱动程序

  2、get Plan:驱动程序查询编译器

  3、词法分析/语法分析

  4、语义分析

  5、逻辑计划产生

  6、逻辑计划优化

  7、物理计划生成

  8、物理计划优化

  9、物理计划执行

  10、查询结果返回

提示:以上是hive的大致工作原理流程,一般面试问到这里就算比较深入了

2.hive 内部表和外部表区别

答:

(1) Hive的create创建表的时候,选择的创建方式:

   – create table

  – create external table

(2)特点:

  – 在导入数据到外部表,数据并没有移动到自己的数据仓库目录下,也就是说外部表中的数据并不是由它自己来管理的!而内部表则不一样;

     – 在删除内部表的时候,Hive将会把属于内部表的元数据和数据全部删掉;而删除外部表的时候,Hive仅仅删除外部表的元数据,数据是不会删除的!

**提示:内部表与外部表的区别一定要掌握,通常情况下我们都会使用外部表保证数据安全性,但是像中间表,结果表这种我们就会考虑使用内部表(管理表)**

3.有以下格式的数据创建出合适的表结构,并将数据导入表中

  战狼2,吴京:吴刚:卢婧姗,2017-08-16

  大话西游,周星驰:吴孟达,1995-09-01

  哪吒,吕艳婷:瀚墨,2019-07-26

  使徒行者2,张家辉:古天乐:吴镇宇,2019-08-07

  鼠胆英雄,岳云鹏:佟丽娅:田雨:袁弘,2019-08-02

3.1 查询出每个电影的第二个主演

3.2 查询每部电影有几名主演

3.3 主演里面包含古天乐的电影

  答:建表语句:

create table if not exists movieInfo(
  movieName string,
  actors array<string>,
  showTime TIMESTAMP
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY ':';

  导入数据:

load data local inpath "/data/movieInfo" into table movieInfo;

  3.1 select movieName ,actors [1] as actor from movieInfo

  3.2 select movieName,size(split(actors)) as actLen from movieInfo

  3.3 select movieName from movieInfo where array_contains(actors, '古天乐')

4.有以下格式的数据创建出合适的表结构,并将数据导入表中

  1,张三,18:male:北京

  2,李四,29:female:上海

  3,杨朝来,22:male:深圳 

  4,蒋平,34:male:成都

  5,唐灿华,25:female:哈尔滨

  6,马达,17:male:北京

  7,赵小雪,23:female:杭州

  8,薛文泉,26:male:上海

  9,丁建,29:male:北京

4.1 查询出每个人的id,名字,居住地址

  答:建表语句:

create table if not exists personInfo(
  id int,
  name string,
  baseInfo struct<age:int, sex:string, city:string>
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY ':';

  4.1 select id,name,baseInfo.city as city from personInfo

5.有以下格式的数据创建出合适的表结构,并将数据导入表中

  1,小明,father:张三#mother:李丽#brother:小力,28

  2,小华,father:李四#mother:吴姗#sister:小静,16

  3,Aaron,father:Abbot#mother:Abby#brother:Abner,18

  4,张启然,father:张雨勇#mother:蒋箐#sister:张业丽,21

  5,马钰林,father:马洪思#mother:郑小涵#brother:马靖文,27

  6,曾畅,father:曾文来#mother:房彤媛#sister:曾婉沁,21

  7,韩文尧,father:韩石泉#mother:郑红珊#sister:韩妤,25

  8,Dailey,father:Eddie#mother:Lacey#brother:Karla,18

5.1 查看每个人的父亲

5.2 每个人有哪些亲属关系

5.3 查出每个人的亲人名字

5.4 查出每个人的亲人数量

5.5 查出所有拥有兄弟的人的id和名字

  答:建表语句:

create table if not exists person(
  id int,
  name string,
  baseInfo map<string,string>,
  age int
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '#'
map keys terminated by ':'
;

  5.1 select id,name,baseInfo['father'] from person;

  5.2 select id,name,map_keys(baseInfo) from person;

  5.3 select id,name,map_values(baseInfo) from person;

  5.4 select id,name,size(baseInfo) from person;

  5.5 

  方案一:

select id,name,age from t_family where array_contains(map_keys(family_members),'brother');

  方案二:

select id,name,age from
(select id,name,age,map_keys(family_members) as relations from t_family) tmp where array_contains(relations,'brother');

  解析:我们可以发现比较特殊的是家庭成员这里 father:张三#mother:李丽#brother:小力 ,通过观察很容易就可以发现这是一个一个建对应一个值的kv形式,那么就可以选用map

  这里 collection items terminated by '#' 指定map中元素也就是各个键值对之间的分隔符

  而 map keys terminated by ':' 指定的是每个键值对之间键与值的分隔符

  5.1可以直接 字段名[键] 来查询

  5.2使用map_keys这个内置函数来查看所有的键

  5.3使用map_values这个内置函数来查看所有的值

  5.4使用size方法查看元素的个数

  5.5这里我们要迂回一下因为没有map_contains这个函数所以我们可以先查出所有的brother,这个返回结果可以当成一个数组来处理,因为array是可以使用contains的,这样问题就解决了

  当然如果想不到上面的方法我们也可以使用子查询的方式来解决,但是因为子查询会影响性能如果可以不用就尽量不要用.

6.复合数据类型样例演示

//分别表示id, 名字,薪水,下属员工, 薪水扣除事项(公积金、医疗保险),地址(街道,城市,省份)

create table employee(
id string,    
name string,
salary float,
subordinates array<string>,
deductions map<string,float>,
address struct<street:string,city:string,province:string>
)partitioned by (country string,state string) 
row format delimited fields terminated by ',' --列的分隔符
collection items terminated by '|' --集合内元素的分隔符
map keys terminated by ':' --kv键值对直接的连接符
;

vim data.txt

1,zhangsan,30,P1|P2,P:100|M:100,s1|c1|p1
2,lisi,40,P3|P4,P:200|M:200,s2|c2|p2
3,wangwu,50,P1|P3,P:300|M:300,s3|c3|p3
4,mayun,60,P1,P:400|M:300,s4|c4|p4

  加载数据:

    load data local inpath '/data.txt' into table employee partition (country='china',state="s1");

  查询字段:
    select subordinates[0],deductions['P'],address.street from employee;

hive学习-问题解答一

  对分区字段country 建立索引

create index employee_index on table employee(country) as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' 
with deferred rebuild idxproperties ('creator'='me','created_at'='20190722') in table employee_index_table partitioned by (country,name);