hive 学习

时间秒杀一切 提交于 2019-12-26 22:37:47

1.概念:

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

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

本质是:将Hive SQL转化成MapReduce程序

学好HIVE可以做数据仓库开发

2.HIVE架构

在这里插入图片描述
1、用户接口:ClientCLI(hive shell)、JDBC/ODBC(java访问hive)、WEBUI(浏览器访问hive)2、元数据(hive中有哪些表,表里有哪些字段,字段类型,表的数据保存在哪里):Metastore元数据包括:表名、表所属的数据库(默认是default)、表的拥有者、列/分区字段、表的类型(是否是外部表)、表的数据所在目录等;默认存储在自带的derby数据库中,推荐使用MySQL存储Metastore3、Hadoop集群使用HDFS进行存储,使用MapReduce进行计算。4、Driver:驱动器解析器(SQL Parser)将SQL字符串转换成抽象语法树AST对AST进行语法分析,比如表是否存在、字段是否存在、SQL语义是否有误。编译器(Physical Plan):将AST编译生成逻辑执行计划。优化器(Query Optimizer):对逻辑执行计划进行优化。执行器(Execution):把逻辑执行计划转换成可以运行的物理计划。对于Hive来说默认就是mapreduce任务

hive没有队列的概念,只是把我们的程序写好后就提交。 YARN有队列的概念(谁先提交就运行谁的任务)
在这里插入图片描述

3.HIVE实操

3.1 Hive JDBC服务

netstat -nlp命令查看运行了哪些服务和端口

在这里插入图片描述

通过beeline命令进入客户端
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4、Hive的DDL操作

4.1 hive的数据库DDL操作

4.1.1、创建数据库

hive >createdatabase db_hive;

或者

hive >createdatabase ifnotexists db_hive;

数据库在HDFS上的默认存储路径是**/user/hive/warehouse/*.db**

4.1.2、显示数据库

hive> show databases;

4.1.3、查询数据库

hive> show databaseslike’db_hive*’;

4.1.4、查看数据库详情

hive>descdatabase db_hive;

4.1.5、显示数据库详细信息

hive>descdatabase extended db_hive;

4.1.6、切换当前数据库

hive > use db_hive;

4.1.7、删除数据库

#删除为空的数据库

hive>dropdatabase db_hive;

#如果删除的数据库不存在,最好采用if exists 判断数据库是否存在

hive>dropdatabase if exists db_hive;

#如果数据库中有表存在,这里需要使用cascade强制删除数据库

hive>dropdatabase if exists db_hive cascade;

4.2 hive的表DDL操作

4.2.1 、建表语法介绍

CREATE[EXTERNAL]TABLE[IFNOTEXISTS] table_name

[(col_name data_type [COMMENT col_comment], …)]

[COMMENT table_comment]

[PARTITIONEDBY(col_name data_type [COMMENT col_comment], …)] 分区

[CLUSTEREDBY(col_name, col_name, …) 分桶

[SORTEDBY(col_name [ASC|DESC], …)]INTOnum_buckets BUCKETS]

[ROW FORMAT row_format] row format delimited fields terminatedby“分隔符”

[STOREDASfile_format]

[LOCATION hdfs_path]

4.2.1.1、

Hive是一种建立在Hadoop文件系统上的数据仓库架构,并对存储在HDFS中的数据进行分析和管理;
(也就是说对存储在HDFS中的数据进行分析和管理,我们不想使用手工,我们建立一个工具把,那么这个工具就可以是hive)

4.2.1.2、 hive建表语法中的分隔符设定

ROW FORMAT DELIMITED 分隔符设置开始语句

FIELDS TERMINATED BY:设置字段与字段之间的分隔符

COLLECTION ITEMS TERMINATED BY:设置一个复杂类型(array,struct)字段的各个item之间的分隔符

MAP KEYS TERMINATED BY:设置一个复杂类型(Map)字段的key value之间的分隔符

LINES TERMINATED BY:设置行与行之间的分隔符

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

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

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

create table t_movie(movie_name string,actors array<string>,first_date date)  
row format delimited 
fields terminated by ','
collection items terminated by ':';

在这里插入图片描述

4.2.1.3、load 语法
按照建表要求,新建一个movie.txt文件
在这里插入图片描述

(终端输入pwd查看文件路径,overwrite是覆盖表中原内容)

LOAD语句:load data [local] inpath ‘filepath’ [overwrite]

into table tablename [partition (partcol1=val1,partcol2=val2…)]

–将/root/data下的所有数据文件导入t3表中,并且覆盖原来的数据

load data local inpath ‘/root/data/’ overwrite into table t3;

–将HDFS中 /input/student01.txt 导入到t3

load data inpath ‘/input/student01.txt’ overwrite into table t3;

–将数据导入分区表

load data local inpath ‘/root/data/data1.txt’ into table partition_table partition(gender=‘M’);

hive 语句区分大小写

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

select movie_name,actors[1],first_datefromt_movie;
在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

例题解析

解析:在这里首先我们看到比较特殊的是主演的名字,而名字又都是string类型的,所以考虑到使用array,因为array存储的都是相同类型的元素,这里我们要使用 collection items terminated by ‘:’ 这个设置来指定复杂数据类型中元素的分隔符。

大家要注意 collection items terminated by 不仅是用来分隔array的,它的作用是分隔复杂数据类型里面的元素的

4.2.1.4我们只需使用array的下角标即可

4.2.1.5 使用size这个内置函数判断array的元素的个数

4.2.1.4 使用array_contains来判断array中是否有这个元素

4.2.2 、字段解释说明

create table:创建一个指定名字的表

EXTERNAL :创建一个外部表,在建表的同时指定一个指向实际数据的路径(LOCATION),指定表的数据保存在哪里

COMMENT: 为表和列添加注释

PARTITIONED BY: 创建分区表

CLUSTERED BY: 创建分桶表

SORTED BY: 按照字段排序(一般不常用)

ROW FORMAT: 指定每一行中字段的分隔符row format delimited fields terminated by ‘\t’

STORED AS:指定存储文件类型:

常用的存储文件类型:SEQUENCEFILE(二进制序列文件)、TEXTFILE(文本)、RCFILE(列式存储格式文件)

如果文件数据是纯文本,可以使用STORED AS TEXTFILE。如果数据需要压缩,使用 STORED AS SEQUENCEFILE。

LOCATION: 指定表在HDFS上的存储位置。

4.2.3、 创建内部表

1、直接建表

使用标准的建表语句

create table if not exists student(
id int,
name string
) 
row format delimited fields terminated by'\t'
stored as textfile;

2、查询建表法

通过AS 查询语句完成建表:将子查询的结果存在新表里,有数据

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

3、like建表法

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

create table if not exists student2 like student;

4、查询表的类型

hive >desc formatted student;

在这里插入图片描述

4.2.4、 创建外部表

create external table if not exists default.emp(
id int,
name string,
age int
) 
row format delimited fields terminated by '\t'
location '/hive/bigdata';

创建外部表的时候需要加上external 关键字

location字段可以指定,也可以不指定

指定就是数据存放的具体目录

不指定就是使用默认目录 /user/hive/warehouse

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

1、内部表转换为外部表

#把student内部表改为外部表

alter table student set tblproperties(‘EXTERNAL’=‘TRUE’);

2、外部表转换为内部表

#把student管理表改为外部表

alter table student set tblproperties(‘EXTERNAL’=‘FALSE’);

4.2.6、 内部表与外部表的区别

1、建表语法的区别

外部表在创建的时候需要加上external关键字

2、删除表之后的区别

内部表删除后,表的元数据和真实数据都被删除了

外部表删除后,仅仅只是把该表的元数据删除了,真实数据还在,后期还是可以恢复出来

hive cli命令窗口查看本地文件系统
与操作本地文件系统类似,这里需要使用 ! (感叹号),并且最后需要加上 ;(分号)

例如

!ls /;

hive cli命令窗口查看HDFS文件系统

与查看HDFS文件系统类似

dfs -ls / ;

hive的底层执行引擎有3种

mapreduce(默认)

tez(支持DAG作业的计算框架)

spark(基于内存的分布式计算框架)

  • HIVE架构

在这里插入图片描述

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

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:北京

1建表:

create table t_user(id int,name string,info struct<age:string,sex:string,addr:string>)

row format delimited

fields terminated by ','

collection items terminated by  ':'
;

2导入数据

首先建立student.txt文件,然后再导入到表中

 load data local inpath '/home/hadoop/data/student.txt' into table t_user;

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

在这里插入图片描述

解析:这里比较特殊的字段是----- 18:male:北京
对应的是------年龄:性别:地址
每一个都是有特定含义的,我们考虑一下因为无法构成键值对,所以map不合适,而array也无法表示出这个特定含义,所以可以考虑struct,struct是C语言中的一个概念结构体,可以理解为java中的对象,那么对象中就可以有变量名和变量值,那么我们这里就可以使用struct

当我们使用的时候也比较容易理解 对象.变量名 即可查询出对应的变量值

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

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

1. 建表

create table t_family(id int,name string,family_mem map<string,string>,age int)

row format delimited

fields terminated by ','

collection items terminated by  '#'

map keys terminated by ':'
;

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

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

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

2. 导入数据

load data local inpath'/home/hadoop/data/student.txt' into table t_family;

查看每个人的父亲
可以直接 字段名[键] 来查询

select id,name,family_mem["father"],age from t_family;在这里插入图片描述
每个人有哪些亲属关系 (使用map_keys这个内置函数来查看所有的键)

select id ,name,map_keys(family_mem),age from t_family;

在这里插入图片描述
查出每个人的亲人名字

select id,name,map_values(family_mem) as relations,age from t_family;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
查出每个人的亲人数量(使用size方法查看元素的个数)

select id,name,size(family_mem) as relations,age from t_family;

查出所有拥有兄弟的人的id和名字
方案1:

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

在这里插入图片描述
方案2:

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

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

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

小扩展:我是怎么知道map没有contains这个方法的呢?

我们可以使用show functions;来查看我们有哪些内置函数

如果想要查看某个函数的具体用法可以使用

desc function extended 函数名

例3

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!