Hive 建立在Hadoop文件系统上的数据仓库架构,并对存储在HDFS中的数据进行分析与管理
Hive架构的核心/本质 --将数据通过SQL语句转换成MapReduce操作/转成hdfs操作
数据仓库 --主要用来分析和管理数据,一般是查询操作,需要定期加载和刷新数据
元数据Metastore(表字段定义,属性,存放位置等除本身数据之外的信息)存储在关系型数据库(自建的mysql)中
优点:
1) 操作接口采用类SQL语法,提供快速开发的能力(简单、容易上手)。
2) 避免了去写MapReduce,减少开发人员的学习成本。
3) Hive的执行延迟比较高,因此Hive常用于数据分析,对实时性要求不高的场合。
4) Hive优势在于处理大数据,对于处理小数据没有优势,因为Hive的执行延迟比较高。
5) Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数。
缺点:
1).Hive的HQL表达能力有限
迭代式算法无法表达 因为本质是MR处理数据,因此很难做到多个MR串连
数据挖掘方面不擅长 更多的是迭代运算
2).Hive的效率比较低
Hive自动生成的MapReduce作业,通常情况下不够智能化
Hive调优比较困难,粒度较粗
[外链图片转存失败(img-uzJ99ATD-1566997166054)(C:\Users\86158\AppData\Roaming\Typora\typora-user-images\1566355212915.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。
Hive通过给用户提供的一系列交互接口,接收到用户的指令(SQL),使用自己的Driver,结合元数据(MetaStore),将这些指令翻译成MapReduce,提交到Hadoop中执行,最后,将执行返回的结果输出到用户交互接口
同一时间只能启用一个hive,默认情况下hive原数据信息放在自己单独的derby数据库中,可以配置存放mysql
个人理解简而言之:
Hive是存储大数据的并行计算类似于存储年份,省份等有跨度的数据;Hive只查索引位置,没有具体数据
数据库存储小量数据类似于天、小时等数据;存放具体数据
细节方面的比较汇总如下:
查询语句相似 Hive是hql || 数据库是sql
数据库存储位置 Hive存储在HDFS上 || 数据库是本地存储
数据更新 Hive数仓读多写少,不建议对数据进行修改 || 数据库中的数据需要经常修改
索引 Hive暴力扫描整个数据,延迟高,无索引但可并行访问数据 || 数据库通常会建立索引
执行 Hive大多数查询是基于MR || 数据库通常有自己的执行引擎
执行延迟 Hive延迟有2(本身数据大;MR执行) || 数据库在数据规模小前提下,执行延迟低
可扩展性 Hive基于Hadoop || 数据库由于受到ACID语义限制,扩展有限
数据规模 Hive并行处理大规模数据 || 数据库支持的数据规模小
数据格式 Hive可以自定义数据格式 || 数据库系统定义格式
Hive数据类型 | Java数据类型 | 长度 | 例子 |
---|---|---|---|
TINYINT | byte | 1byte有符号整数 | 20 |
SMALINT | short | 2byte有符号整数 | 20 |
INT | int | 4byte有符号整数 | 20 |
BIGINT | long | 8byte有符号整数 | 20 |
BOOLEAN | boolean | 布尔类型,true或者false | TRUE FALSE |
FLOAT | float | 单精度浮点数 | 3.14159 |
DOUBLE | double | 双精度浮点数 | 3.14159 |
STRING | string | 字符系列。可以指定字符集。可以使用单引号或者双引号。 | ‘now is the time’ “for all good men” |
TIMESTAMP | 时间类型 | ||
BINARY | 字节数组 |
Tips:
对于Hive的String类型相当于数据库的varchar类型,该类型是一个可变的字符串,不过它不能声明其中最多能存储多少个字符,理论上它可以存储2GB的字符数
数据类型 | 描述 | 语法示例 |
---|---|---|
STRUCT | 和c语言中的struct类似,都可以通过“点”符号访问元素内容。例如,如果某个列的数据类型是STRUCT{first STRING, last STRING},那么第1个元素可以通过字段.first来引用。 | struct() |
MAP | MAP是一组键-值对元组集合,使用数组表示法可以访问数据。例如,如果某个列的数据类型是MAP,其中键->值对是’first’->’John’和’last’->’Doe’,那么可以通过字段名[‘last’]获取最后一个元素 | map() |
ARRAY | 数组是一组具有相同类型和名称的变量的集合。这些变量称为数组的元素,每个数组元素都有一个编号,编号从零开始。例如,数组值为[‘John’, ‘Doe’],那么第2个元素可以通过数组名[1]进行引用。 | Array() |
Tips:
Hive有三种复杂数据类型ARRAY、MAP 和 STRUCT。ARRAY和MAP与Java中的Array和Map类似,而STRUCT与C语言中的Struct类似,它封装了一个命名字段集合,复杂数据类型允许任意层次的嵌套
类似于 省份市区电话号等数据类型较多的封装
Tips:
在使用STRUCT复杂函数时:
STRUCT可以包含不同数据类型的元素。这些元素可以通过”点语法”的方式来得到所需要的元素,比如user是一个STRUCT类型,那么可以通过user.address得到这个用户的地址。
eg:
1、创建表
create table student_test(id int,info struct< name:string,age:int >)
row format delimited fields terminated by ‘,’
collection items terminated by ‘:’;
2、准备文件内容
[root@hello110 data]# vi student_test
1001,zhangsan:24
1002,lisi:25
1003,xiaoming:26
1004,dongdong:27
3、文件导入表
load data local inpath “/data/student_test” into table student_test;
4、查看表内容
hive (default)> select * from student_test;
OK
student_test.id student_test.info
1001 {“name”:“zhangsan”,“age”:24}
1002 {“name”:“lisi”,“age”:25}
1003 {“name”:“xiaoming”,“age”:26}
1004 {“name”:“dongdong”,“age”:27}
5、查询结果
hive (default)> select info.name,info.age from student_test;
OK
name age
zhangsan 24
lisi 25
xiaoming 26
dongdong 27
Hive的原子数据类型是可以进行隐式转换的,类似于Java的类型转换,例如某表达式使用INT类型,TINYINT会自动转换为INT类型,但是Hive不会进行反向转化,例如,某表达式使用TINYINT类型,INT不会自动转换为TINYINT类型,它会返回错误,除非使用CAST操作
1.隐式类型转换规则如下
(1)任何整数类型都可以隐式地转换为一个范围更广的类型,如TINYINT可以转换成INT,INT可以转换成BIGINT
(2)所有整数类型、FLOAT和STRING类型都可以隐式地转换成DOUBLE
(3)TINYINT、SMALLINT、INT都可以转换为FLOAT
(4)BOOLEAN类型不可以转换为任何其它的类型
2.可以使用CAST操作显示进行数据类型转换
例如CAST(‘1’ AS INT)将把字符串’1’ 转换成整数1;如果强制类型转换失败,如执行CAST(‘X’ AS INT),表达式返回空值 NULL
DDL:表、数据库的创建 操作的是mysql数据库中的内容
DML:数据的增删改查操作 操作的是HDFS上的内容
Tips:
create database if not exists xxx;
可以进行模糊查询数据库 show databases like ‘xxx*’;
查询某一数据库信息 desc database xxx;
查询某一数据库详细扩展信息 desc database extended xxx;
修改数据库属性(键值对) alter database xxx set dbproperties(“xoxo”=“xxxxxxxx”);
删除空数据库 drop database xxx;
删除不为空的数据库 drop database xxx cascade;
查看表结构化数据 desc fromatted dept;
set hive.support.sql11.reserved.keywords=false; 关闭关键字影响
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name 创建表【外部表】
[(col_name data_type [COMMENT col_comment], …)] 字段名,数据类型[列的注释]
[COMMENT table_comment] 表注释
[PARTITIONED BY (col_name data_type [COMMENT col_comment], …)] 分区(列 列的类型)
[CLUSTERED BY (col_name, col_name, …) 分桶(列)
[SORTED BY (col_name [ASC|DESC], …)] INTO num_buckets BUCKETS] 排序
[ROW FORMAT row_format] 各种格式分隔符
[STORED AS file_format] 存储的文件格式
[LOCATION hdfs_path] 指定表存储路径
相关操作的数据信息
人员表
id,姓名,爱好,住址
1,小明1,lol-book-movie,beijing:xisanqi-shanghai:pudong
2,小明2,lol-book-movie,beijing:xisanqi-shanghai:pudong
3,小明3,lol-book-movie,beijing:xisanqi-shanghai:pudong
4,小明4,lol-book-movie,beijing:xisanqi-shanghai:pudong
5,小明5,lol-movie,beijing:xisanqi-shanghai:pudong
6,小明6,lol-book-movie,beijing:xisanqi-shanghai:pudong
7,小明7,lol-book,beijing:xisanqi-shanghai:pudong
8,小明8,lol-book,beijing:xisanqi-shanghai:pudong
9,小明9,lol-book-movie,beijing:xisanqi-shanghai:pudong
set hive.support.sql11.reserved.keywords=false; 关闭关键字影响
–创建内部表、设置分割符、导入数据
CREATE TABLE psn0(
id int,
name string,
likes ARRAY < string >,
address MAP < string,string >
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ‘,’
COLLECTION ITEMS TERMINATED BY ‘-’
MAP KEYS TERMINATED BY ‘:’;
#LOAD DATA [LOCAL] INPATH ‘filepath’ [OVERWRITE] INTO TABLE tablename;
LOAD DATA LOCAL INPATH ‘/root/data1’ INTO TABLE psn8;
–序列化与反序列化
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ‘’ 字段与字段间的分割符
COLLECTION ITEMS TERMINATED BY ‘’ 集合元素间的分割符
MAP KEYS TERMINATED BY ‘’ map中k,v之间的分割符
LINES TERMINATED BY ‘’ 行数据间的分割符 默认/n
–创建外部表、设置分割符+设置外部目录、导入数据
设置外部目录放在字符分割之后
#外部表数据删除不会丢失
#内部表数据自己管理,外部表是指定一个目录,是对目录的一个引用,数据本身并不会去管理
CREATE EXTERNAL TABLE psn1(
id int,
name string,
likes ARRAY < string >,
address MAP < string,string >
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ‘,’
COLLECTION ITEMS TERMINATED BY ‘-’
MAP KEYS TERMINATED BY ‘:’
LOCATION ‘/psn1’;
只会删除元数据,不会删除文件
ALTER TABLE xxx SET TBLPROPERTIES(‘EXTERNAL’=‘False’);
drop table xxx;
ALTER TABLE psn6 SET TBLPROPERTIES(‘EXTERNAL’=‘False’);
drop table psn6;
注意:Truncate只能删除管理表/内部表,不能删除外部表中数据
truncate table student;
内是FALSE 外是TRUE
(1)查询表的类型
hive (default)> desc formatted student2;
Table Type: MANAGED_TABLE
(2)修改内部表student2为外部表(‘EXTERNAL’=‘TRUE’)
alter table student2 set tblproperties(‘EXTERNAL’=‘TRUE’);
(3)查询表的类型
hive (default)> desc formatted student2;
Table Type: EXTERNAL_TABLE
(4)修改外部表student2为内部表(‘EXTERNAL’=‘FALSE’);
alter table student2 set tblproperties(‘EXTERNAL’=‘FALSE’);
(5)查询表的类型
hive (default)> desc formatted student2;
Table Type: MANAGED_TABLE
Tips:
(‘EXTERNAL’=‘TRUE’) 和 (‘EXTERNAL’=‘FALSE’) 为固定写法,区分大小写!
分区表现在HDFS上是分文件夹
分区字段和表中的字段是不重复的,不使用表结构
想要分区先要在创建表的时候添加一个或多个分区的分区数据和类型(age int),然后在导入数据时要在表名后添加分区条件partition (age=10);
PARTITIONED BY(age int) PARTITIONED BY(xx=“oo”,yy=zz)(放在字符分割之前)
在添加分区时,如果分区字段有多个,多个分区字段必须全部指定(内部表)
创建分区的字段不能在原有的数据字段中出现,换句话说,分区(xxx)中的字段表中不能出现(xxx)的列
查询的时候可以根据分区 xxx=ooo 进行数据查询,效率更高 分层管理
如果设置多个分区(xx=“oo”,yy=zz),再导入数据的时候也要有多个分区(xx=“oo”,yy=rr)
多个分区字段,靠前的是上级目录,靠后的是子集目录,在WED页面进行hdfs查询的时候是先按照第一个分区字段进入后,显示第二个分区字段目录内容
添加多个分区是空格,删除多个分区是逗号
alter table tablename add partition(xxx=“ooo”) (ooo=“xxx”);
alter table tablename drop partition(xxx=“ooo”) ,(ooo=“xxx”);
CREATE TABLE psn2(
id int,
name string,
likes ARRAY < string >,
address MAP < string,string >
)
PARTITIONED BY(age int)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ‘,’
COLLECTION ITEMS TERMINATED BY ‘-’
MAP KEYS TERMINATED BY ‘:’;
alter table tablename add partition(xxx=“ooo”);
alter table tablename add partition(xxx=“ooo”) (ooo=“xxx”);
创建的表中含有分区信息才能在后续进行分区具体操作
#在导入数据时添加分区
LOAD DATA LOCAL INPATH ‘/root/data1’ INTO TABLE tablename partition (age=10);
LOAD DATA LOCAL INPATH ‘/root/data1’ INTO TABLE psn8 partition (sex=“boy”,age=10);
#直接在表上添加分区,可以先不导入数据
ALTER TABLE tablename ADD PARTITION(sex=“boy”,age=10);
select * from tablename where age=10;
select * from tablename where age=10 or sex=boy;
select * from tablename where age=10 union select * from tablename where sex=boy;
Tips:
or 是sql常规查询,速度快,无排序
union 方法是使用的MR,相对慢很多,查询结果是有序的
alter table tablename drop partition(xxx=“ooo”);
alter table tablename drop partition(xxx=“ooo”) ,(ooo=“xxx”);
在删除分区时,可以只指定多个分区的一部分,相关连的分区也被删除
内部表删除分区 数据丢失
外部表珊瑚分区 数据不会丢失
ALTER TABLE tablename DROP PARTITION(xx=“oo”,yy=zz);
ALTER TABLE psn8 DROP PARTITION(sex=“boy”,age=10);
1.创建二级分区表
create table dept_partition2(
deptno int, dname string, loc string)
partitioned by (month string, day string)
row format delimited fields terminated by ‘\t’;
2.正常的加载数据
(1)加载数据到二级分区表中
load data local inpath '/opt/module/datas/dept.txt' into table
default.dept_partition2 partition(month=‘201709’, day=‘13’);
(2)查询分区数据
select * from dept_partition2 where month=‘201709’ and day=‘13’;
3.把数据直接上传到分区目录上,让分区表和数据产生关联的三种方式
方式一:上传数据后修复
上传数据
dfs -mkdir -p /user/hive/warehouse/dept_partition2/month=201709/day=12;
dfs -put /opt/module/datas/dept.txt /user/hive/warehouse/dept_partition2/month=201709/day=12;
查询数据(查询不到刚上传的数据)
select * from dept_partition2 where month=‘201709’ and day=‘12’;
执行修复命令
msck repair table dept_partition2;
再次查询数据
select * from dept_partition2 where month=‘201709’ and day=‘12’;
方式二:上传数据后添加分区
上传数据
dfs -mkdir -p /user/hive/warehouse/dept_partition2/month=201709/day=11;
dfs -put /opt/module/datas/dept.txt /user/hive/warehouse/dept_partition2/month=201709/day=11;
执行添加分区
alter table dept_partition2 add partition(month=‘201709’, day=‘11’);
查询数据
select * from dept_partition2 where month=‘201709’ and day=‘11’;
方式三:创建文件夹后load数据到分区
创建目录
dfs -mkdir -p /user/hive/warehouse/dept_partition2/month=201709/day=10;
上传数据
load data local inpath ‘/opt/module/datas/dept.txt’ into table dept_partition2 partition(month=‘201709’,day=‘10’);
查询数据
hive (default)> select * from dept_partition2 where month=‘201709’ and day=‘10’;
CREATE TABLE tablename(
id int,
name string,
likes ARRAY < string >,
address MAP < string,string >
)
CREATE TABLE TABLENAME2 LIKE TABLENAME1 --只有表结构没有表数据
create tablepsn3 like psn2;
–适用于数据复杂一次性得不到最终需求 除了原表结构也复制原表中数据到新表
CREATE TABLE TABLENAME2
AS
SELECT 字段1,字段2,。。。
FROM TABLENAME1;
–适用于数据简单统计
FROM tablename1 pvs
INSERT OVERWRITE TABLE tablename2
SELECT pvs.viewTime, pvs.userid, pvs.sex;
先创建一个结果表,不包含原表的全部字段,再根据所需写操作命令
eg:统计条数,创建存放结果的表psnjg,再将psn0数据写入psnjg
create table psnjg (ct int);
local 加载数据是cp的,数据存在在本地,overwrite into是复写操作–删除原有的加载当下的 into是追加操作
无local 加载数据是mv的,是从HDFS上移动到表的目录下的
本地需要加LOCAL,hdfs不需要加LOCAL
实质上是将本地文件先移动到hdfs上再移动到tablename的目录下
LOAD DATA [LOCAL] INPATH ‘filepath’ INTO TABLE tablename;
--假设data1在根目录下
实质上是从hdfs上导入数据实质上是将hdfs上被导入的文件移动到tablename的目录下
LOAD DATA INPATH ‘/data1’ INTO TABLE tablename;
--可以显示表以及表数据
hdfs dfs -put 文件 WEB表路径
eg:hdfs dfs -put data1 /user/hive/warehouse/psn3
会执行MR操作,压缩文件
1.创建一张分区表
create table student(id int, name string)
partitioned by (month string)
row format delimited fields terminated by ‘\t’;
2.基本插入数据
insert into table student partition(month=‘201709’) values(1,‘wangwu’);
3.基本模式插入(根据单张表查询结果)
insert overwrite table student
partition(month=‘201708’)
select id, name from student where month=‘201709’;
4.多插入模式(根据多张表查询结果)
from student
insert overwrite table student partition(month=‘201707’)
select id, name where month=‘201709’
insert overwrite table student partition(month=‘201706’)
select id, name where month=‘201709’;
1.创建表时直接指定在hdfs上的位置
create table if not exists student5
(id int, name string)
row format delimited fields terminated by ‘\t’
location ‘/user/hive/warehouse/student5’;
2.上传数据到hdfs上
dfs -put /opt/module/datas/student.txt /user/hive/warehouse/student5;
不常用,需要建目录,目录下一个存放的是元文件,一个存放的是原文件数据
1.将查询的结果导出到本地
insert overwrite local directory ‘/opt/module/datas/export/student’
select * from student;
2.将查询的结果格式化导出到本地
insert overwrite local directory ‘/opt/module/datas/export/student1’
ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘\t’
select * from student;
3.将查询的结果导出到HDFS上(没有local)
insert overwrite directory ‘/user/atguigu/student2’
ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘\t’
select * from student;
dfs -get /user/hive/warehouse/student/month=201709/000000_0
/opt/module/datas/export/student3.txt;
基本语法:(hive -f/-e 执行语句或者脚本 > file)
[atguigu@hadoop102 hive]$ bin/hive -e ‘select * from default.student;’ >
/opt/module/datas/export/student4.txt;
export table default.student to ‘/user/hive/warehouse/export/student’;
后续课程专门讲。
–读时检查 --写时检查
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ‘’ 字段与字段间的分割符
COLLECTION ITEMS TERMINATED BY ‘’ 集合元素间的分割符
MAP KEYS TERMINATED BY ‘’ map中k,v之间的分割符
LINES TERMINATED BY ‘’ 行数据间的分割符 默认/n
构建在数据存储和执行引擎之间,对两者实现解耦,换而言之,SERDE是将在hdfs上的文件解耦分析
主要实现数据清洗工作,消减掉特殊符号
eg:
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] “GET / HTTP/1.1” 200 11217
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] “GET /tomcat.css HTTP/1.1” 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] “GET /tomcat.png HTTP/1.1” 304 -
[外链图片转存失败(img-TzH0b5Tv-1566997166056)(C:\Users\86158\AppData\Roaming\Typora\typora-user-images\1561640155994.png)]
CREATE TABLE logtbl (
host STRING,
identity STRING,
t_user STRING,
time STRING,
request STRING,
referer STRING,
agent STRING)
ROW FORMAT SERDE ‘org.apache.hadoop.hive.serde2.RegexSerDe’
WITH SERDEPROPERTIES (
“input.regex” = "([^ ]) ([^ ]) ([^ ]) \[(.)\] “(.)" (-|[0-9]) (-|[0-9]*)”
)
STORED AS TEXTFILE;
另一种服务端(命令)和客户端(写sql)搭配的方法 !quit
hiveserver2 beeline 搭配使用
服务端(sxt003) hiveserver2
a客户端(sxt004) beeline -u jdbc:hive2://localhost:10000/default -n root
beeline -u jdbc:hive2://sxt003:10000/ root
b客户端(sxt004) beeline
!connect jdbc:hive2://sxt003:10000/ root 123
结合hiveserver2使用
参上
zH0b5Tv-1566997166056)]
CREATE TABLE logtbl (
host STRING,
identity STRING,
t_user STRING,
time STRING,
request STRING,
referer STRING,
agent STRING)
ROW FORMAT SERDE ‘org.apache.hadoop.hive.serde2.RegexSerDe’
WITH SERDEPROPERTIES (
“input.regex” = "([^ ]) ([^ ]) ([^ ]) \[(.)\] “(.)" (-|[0-9]) (-|[0-9]*)”
)
STORED AS TEXTFILE;
另一种服务端(命令)和客户端(写sql)搭配的方法 !quit
hiveserver2 beeline 搭配使用
服务端(sxt003) hiveserver2
a客户端(sxt004) beeline -u jdbc:hive2://localhost:10000/default -n root
beeline -u jdbc:hive2://sxt003:10000/ root
b客户端(sxt004) beeline
!connect jdbc:hive2://sxt003:10000/ root 123
结合hiveserver2使用
参上