大数据技术之Hive(二)Hive入门

一、Hive入门

1.1 Hive简介

1.1.1 hive出现的原因

FaceBook网站每天产生海量的结构化日志数据,为了对这些数据进行管理,并且因为机器学习的需求,产生了hive这门技术,并继续发展成为一个成功的Apache项目。

1.1.2 什么是hive

hive是一个构建在Hadoop上的数据仓库工具(框架),可以将hdfs上的结构化的数据文件映射成一张数据表,并可以使用类SQL语句来对这样的数据文件进行查询统计的功能。hive是一个Hadoop客户端,本质是将SQL语句转化成MapReduce程序

所以Hive不存储数据,也没有任何计算功能,只是相当于类SQL语句与Hadoop文件之间的一个解释器。其本质是一个对HDFS上的文件进行索引并计算的工具。需要依赖Hadoop的yarn来进行资源分配,也需要Hadoop的MapReduce来提供计算支持。

总结:

  1. Hive中每张表的数据存储在HDFS

  1. Hive分析数据底层的实现是MapReduce(也可以配置为Spark或者Tez)

  1. 执行程序运行在Yarn上

1.1.3 为什么使用hive

Hive底层的实现是MapReduce,但是直接使用MapReduce,需要面临以下问题:

- 人员学习成本高
- 项目周期要求太短
- MapReduce实现复杂查询逻辑开发难度大

1.2 Hive的架构原理

1、用户接口:client
CLI:是指Shell命令行
JDBC/ODBC:是指Hive的java实现,与传统数据库JDBC类似。
WebUI:是指可通过浏览器访问Hive。
JDBC和ODBC的区别:
1. JDBC的移植性比ODBC好
2. 两者使用的语言不同,JDBC在Java编程时使用,ODBC一般在C/C++使用

2、元数据:Meta store
元数据包括:数据库(默认是default)、表名、表的拥有者、列/分区字段、表的类型(是否是外部表)、表的数据所在目录等。
默认存储在 自带的derby数据库中,由于derby数据库只支持但客户端访问,生产环境中为了多人开发,推荐使用MySQL存储Metastore。

3、驱动器:Driver
- 解析器(SQLParser):
将HQL字符串转换成抽象语法树AST,这一步一般都用第三方工具库完成,比如antlr;对AST进行语法分析,比如表是否存在、字段是否存在、SQL语义是否有误。
- 编译器(Compiler):
对hql语句进行词法、语法、语义的编译(需要跟元数据关联),编译完成后会生成一个执行计划。hive上就是编译成mapreduce的job。
- 优化器(Optimizer):
将执行计划进行优化,减少不必要的列、使用分区、使用索引等。优化job。
- 执行器(Executer):
将优化后的执行计划提交给hadoop的yarn上执行。提交job。

4、Hadoop
使用HDFS进行存储,使用MapReduce进行计算。

1.3 Hive的优缺点

优点:

1.学习成本低:提供了类SQL查询语言HQL(简单,容易上手),避免了直接写MapReduce,上手快,减少开发人员的学习成本。
2.可扩展性好:为超大数据集设计了计算/扩展能力(MR作为计算引擎,HDFS作为存储系统),Hive可以自由的扩展集群的规模,一般情况下不需要重启服务。
3.适合做离线分析处理(OLAP):Hive的执行 延迟比较高,因此Hive常用于数据分析,对实时性要求不高的场合。
4.延展性好:Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数。

缺点:

1. hive的HQL表达能力有限
- 基于模板实现,所以不够智能化,很多复杂的计算无法支持。如迭代式计算
- 数据挖掘方面,由于MapReduce数据处理流程的限制,效率更高的算法却无法实现
2. hive的效率比较低
- hive自动生成的mapreduce作业,需要消耗非常多的资源
- hive调优比较困难,粒度较粗,对小数据量没有优势

所以hive通常适用于大数据的OLAP(On-Line Analytical Processing联机分析处理)场景,做一些面向分析,允许有延迟的数据挖掘工作。并且结合其他组件也可以用来做一些数据清洗之类的简单数据处理工作。

1.4 Hive和关系型数据库比较

hive是基于Hadoop的,所以hive的可扩展性与Hadoop的可扩展性是一致的。而Hadoop相比于传统数据库:

扩展能力强。Hadoop支持将不同配置的机器一起组成庞大的集群,而关系型数据库做不到这一点。

数据处理能力强。当数据量非常大时,关系型数据库虽然可以用分库分表等方式进行扩展,但数据承载能力相当有限,并且数据量大了之后,性能下降明显。而基于Hadoop的大数据体系承载海量数据就轻松很多。数据量增大对整体性能的影响十分有限。

MySQL

Hive

查询语言

SQL

HQL

存储

存储在自己的系统中

HDFS

数据格式

系统定义格式

可自定义

数据更新

可以CRUD

不支持数据的改写和添加

执行/索引

excutor执行引擎

MapReduce

使用环境

无限制

Hadoop

延迟性

低延迟

高延迟

数据规模

小数据量

大数据量

可扩展性

二、DDL数据定义语言

2.1 数据库database

2.1.1 创建数据库

  • 语法:

create database [if not exists] database_name
[comment database_comment] // 注释
[location hdfs_path] // 指定数据库在hdfs上存储的路径
[with dbproperties (property_name=property_valus , ...)]; // 给数据库添加<K,V>键值对参数

注:若不指定路径,默认在/opt/soft/hive312/warehouse

  • 案例:

create database db_hive;
create database db_hive2 with dbproperties ('create_Date'='2023-02-21');

2.1.2 查询数据库

展示所有数据库
  • 语法:

show database [like 'identifier_with_wildcards'];
  • 案例:

hive (default)> show databases like 'db_hive*';
OK
database_name
db_hive1
db_hive2
Time taken: 0.527 seconds, Fetched: 2 row(s)
查看数据库信息
  • 语法:

describe database [extended] db_name;
  • 案例:

① 查看基本信息

hive (default)> describe database db_hive2;
OK
db_name    comment    location    owner_name    owner_type    parameters
db_hive2        hdfs://hadoop02:9000/opt/soft/hive312/warehouse/db_hive2.db    root    USER
Time taken: 0.454 seconds, Fetched: 1 row(s)

② 查看更多信息

hive (default)> describe database db_hive2;
OK
db_name    comment    location    owner_name    owner_type    parameters
db_hive2        hdfs://hadoop02:9000/opt/soft/hive312/warehouse/db_hive2.db    root    USER
Time taken: 0.454 seconds, Fetched: 1 row(s)
hive (default)> describe database extended db_hive2;
OK
db_name    comment    location    owner_name    owner_type    parameters
db_hive2        hdfs://hadoop02:9000/opt/soft/hive312/warehouse/db_hive2.db    root    USE{create_Date=2023-02-21}
Time taken: 0.094 seconds, Fetched: 1 row(s)

2.1.3 修改数据库

  • 语法:

——修改dbproperties
alter database database_name set dbproperties (property_name=property_value, ...);

——修改location
alter database database_name set location hdfs_path;

——修改owner user
alter database database_name set owner user user_name;
  • 案例:

① 修改dbproperties

hive (default)> alter database db_hive2 set dbproperties('create_Date'='2022-02-22');
OK
Time taken: 0.458 seconds

2.1.4 删除数据库

  • 语法:

drop database [if exists] database_name [restrict | cascade];

注:restrict严格模式,若数据库不为空,则会删除失败,默认为该模式。

cascade级联模式,若数据库不为空,则会将数据库中的表一并删除。

  • 案例:

① 删除空数据库

hive (default)> drop database db_hive2;

② 删除非空数据库

hive (default)> drop database db_hive2 cascade;

2.1.5 切换当前数据库

  • 语法:

use database_name;

2.2 表table

2.2.1 创建表

1)普通建表
  • 语法:

create [ temporary] [ external] table [ if not exists]
[db_name.]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, col_name, ...)]
[ row format row_format]
[ stored as file_format]
[ location hdfs_path]
[ tblproperties (proeprty_name=property_value, ...)]

  • 关键字说明:

① temporary

临时表,该表只在当前会话可见,会话结束,表会被删除。

external

外部表,与之对应的时内部表。内部表一位置hive会完全接管该表,包括元数据和HDFS中的数据。而外部表意味着hive只接管元数据,而不完全接管HDFS中的数据。

data_type

hive中的字段类型可以分为基本数据类型复杂数据类型

基本数据类型

Hive

说明

定义

tinyint

1byte 有符号整数

smallint

2byte 有符号整数

int

4byte 有符号整数

bigint

8byte 有符号整数

boolean

float

单精度浮点数

double

双精度浮点数

decimal

十进制精确数字类型

decimal(16,2)

varchar

字符序列,需指定最大长度

最大长度范围 [1,65535]

varchar(32)

string

字符串,无需指定最大长度

timestamp

时间类型

binary

二进制数据

复杂数据类型

类型

说明

定义

取值

array

数组是一组相同类型的值的集合

array<string>

arr[0]

map

map时一组相同类型的键-值对集合

map<string, int>

map['key']

struct

结构体由多个属性组成,每个属性都有自己的属性名和数组类型

struct<id:int, name:string>

struct.id

partitioned by

创建分区表

clustered by ... sorted by ... into ...buckets

创建分桶表

row format

delimited
fields terminated by:列分隔符
collection items terminated by:map、struct和array中每个元素之间的分隔符
map keys terminated by:map中的key和value的分隔符
lines terminated by:行分隔符

stored as

指定文件格式,常用的文件格式由,textfile,sequence file,orc file,parquet file等待

⑧ location

指定表所对应的HDFS路径。默认值为${hive.metastore.warehouse.dir}/db_name.db/table_name

⑨ tblproperties

用于配置表的一些KV键值对参数

  • 案例:

-- 1,xiaoming1,lol-book-movie,beijing:bdqn-nanjing:zhongbo
-- 2,xiaoming2,lol-book-movie,beijing:bdqn-nanjing:zhongbo
-- 3,xiaoming3,lol-book-movie,beijing:bdqn-nanjing:zhongbo
-- 4,xiaoming4,lol-book-movie,beijing:bdqn-nanjing:zhongbo
-- 5,xiaoming5,lol-movie,beijing:bdqn-nanjing:zhongbo
-- 6,xiaoming6,book-movie,beijing:bdqn-nanjing:zhongbo
-- 7,xiaoming7,lol-book,beijing:bdqn-nanjing:zhongbo
-- 8,xiaoming8,lol-book,beijing:bdqn-nanjing:zhongbo
-- 9,xiaoming9,lol-book-movie,beijing:bdqn-nanjing:zhongbo
-- 10,xiaoming10,lol,beijing:bdqn
create table if not exists student(
    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 ":"
lines terminated by "\n";
# 查询数据
select likes[0],address["beijing"] from student;

# KV查询
select address["beijing"] from student;        // 根据key查询value
select map_keys[address] from student;         // 查询所有的key值 
select map_keys[address][0] from student;
select map_values[address] from student;       // 查询所有的value值
select map_values[address][0] from student;

2)CTAS(Create Table As Select)建表

该语法允许用户利用select查询语句返回的结果,直接建表。表的结构和查询语句的结构保持一致,且保证包含select查询语句返回的内容。

create [temporary] [external] table [if not exists] table_name
[comment table_comment]
[row format row_format]
[stored as file_format]
[location hdfs_path]
[tblproperties (proeprty_name=property_value, ...)]
[ as select_statement]
CREATE TABLE ctas_employee as SELECT * FROM employee;

3)CTE(CTAS with Common Table Expression)建表
CREATE TABLE cte_employee AS
WITH 
r1 AS  (SELECT name FROM r2 WHERE name = 'Michael'),
r2 AS  (SELECT name FROM employee WHERE sex_age.sex= 'Male'),
r3 AS  (SELECT name FROM employee  WHERE sex_age.sex= 'Female')
SELECT * FROM r1 UNION ALL SELECT * FROM r3;

4)Create Table Like语法

允许用户复刻一张已经存在的表结构。与CTAS不同,该语法创建出来的表不包含数据

create [temporary] [external] table [if not exists] table_name
[db_name.]table_name
[ like exist_table_name]
[row format row_format]
[stored as file_format]
[location hdfs_path]
[tblproperties (proeprty_name=property_value, ...)]
CREATE TABLE employee_like LIKE employee;

2.2.2 查看表

1)展示所有表
  • 语法:

show tables [ in database_name ] like [ 'iderntifier_with_wildcards' ];
  • 案例:

show tables like 'stu*';
2)查看表信息
  • 语法:

describe [ extended | formatted ] [ db_name ].table_name

extended:展示详细信息

formatted:对详细信息进行格式化的展示

  • 案例:

desc student;            // 查看基本信息
desc formatted student;  // 查看更多信息

2.2.3 修改表

1)重命名表
  • 语法:

alter table table_name rename to new_table_name
  • 案例:

alter table student rename to stu;
2)修改列信息
  • 语法:

① 增加列:允许用户增加新的列,新增列位于末尾
alter table table_name add columns (col_name data_type [ comment col_comment ], ... )

② 更新列:允许用户修改指定列的列名、数据类型、注释信息、在表中的位置
alter table table_name change [ columns ] col_old_name col_new_name column_type [ comment col_comment ] [ first | after column_name ]

③ 替换列:允许用户用新的列集替换原有的全部列
alter table table_name replace columns (col_name data_type [ comment col_comment ], ... )
  • 案例:

alter table student add columns(age int);                    // 添加列
alter table student change column age ages double;           // 更新列
alter table student replace columns(id int, name string);    // 替换列

2.2.4 删除表

  • 语法:

drop table [ if exists ] table_name;
  • 案例:

drop table stu;

2.2.5 清空表

  • 语法:

truncate [ table ] table_name

注意:truncate只能清空管理表,不能删除外部表中数据。

  • 案例:

truncate table stu;

三、DML数据操作语言

3.1 Load

  • 语法:

load data [ local ] inpath 'filepath' [ overwrite ] into table tablename [ patrition ( partcol1=val1, partcol2=val2 ...) ]

local:从本地加载数据到hive表。否则从HDFS加载数据到hive表

overwrite:覆盖表中已有数据,否则表示追加

partition:上传到指定分区

  • 案例:

# 上传本地数据到指定分区,覆盖表中原有数据
load data local inpath '/opt/stufile/student.txt' overwrite into table student2 partition (age=20)

3.2 Insert

3.2.1 将查询结果插入到表中

  • 语法:

insert ( into | overwrite ) table tablename [ partition ( partcol1=val1 , partcol2=val2 ...) ]
select_statement;
  • 案例:

# 将student表中的数据插入到stu_new中
insert into table stu_new 
    select * from student;

3.2.2 将给定values插入表中

  • 语法:

insert ( into | overwrite ) table tablename [ partition ( partcol1=val1 , partcol2=val2 ...) ]
values values_row [ , values_row ... ]
  • 案例:

insert into table stu_new 
    values(1,'zhangsan'),(2,'zhaosi');

3.2.3 将查询结果写入目标路径

  • 语法:

insert overwrite [ local ] directory 'directory' [ row format row_format ] [ stored as file_format ] select_statement;
  • 案例:

insert overwrite local directory '/opt/stufile/student_new.txt' 
    select * from student;

数据会导出到本地的目录文件下。

3.3 Export & Import

export和import可用于两个hive实例之间的数据迁移。

export将表的数据和元数据信息一并导出到HDFS路径。

import将export导出的内容导入到hive。

  • 语法:

——导出
export table tablename to 'export_target_path'
——导入
import [ external ] table new_or_origunal_tablename from 'source_path' [ location 'import_target_path' ]
  • 案例:

# 导出
export table student to '/new';
# 导入,默认路径在hive(default)下
import table student02 from '/new';

四、查询

4.1 基础语法

select [ all | distinct] select_expr, select_expr, ...
from table_reference
[ where where_condition ]
[ group by col_list ]
[ having col_list ]
[ order by col_list ]
[ cluster by col_list | [ distribute by col_list ] [ sort by col_list ] ]
[ limit number ]

4.2 基本查询select...from...

基本查询语句与SQL语句类似。

4.2.1关系运算函数

No

运算关系

符号

举例

返回值

1

等值

=

select 1 from stu where 1=1;

1

2

不等值

<>

select 1 from stu where 1 <> 2;

1

3

小于

<

select 1 from stu where 1 < 2;

1

4

小于等于

<=

select 1 from stu where 1 <= 2;

1

5

大于

>

select 1 from stul where 2 > 1;

1

6

大于等于

>=

select 1 from stul where 2 >= 1;

1

7

空值判断

is null

select 1 from stu where null is null;

1

8

非空判断

is not null

select 1 from stu where 1 is not null;

1

9

like比较

like

select 1 from stu where zs like 'z%' | 'z_';

1

10

正则表达式

regexp

4.2.2 聚合函数

函数

释义

count(*)

统计所有行数,包括null值

count(某列)

该列一共右多少行,不包括null值

max()

求最大值,不包含null

min()

求最小值,不包含null

sum()

求和,不包含null

avg()

求平均值,不包含null

4.3 分组

4.3.1 group by 语句

group by语句通常和聚合函数一起使用。按照一个或多个队列结果进行分组,然后对每个组执行聚合操作。

# 查询分组字段有几个值
select count(*) from emp group by job;

4.3.2 having 语句

where是在group by之前执行的,分组函数是在group by以后执行的,分组函数无法用在where后面。所以需要使用having语句对分组之后的数据进行再次过滤。

select count(*) from emp group by job having job like '人事%';

4.4 join 语句

4.4.1 等值join

hive支持通常的sql join语句。但是有些版本只支持等值连接,不支持非等值连接

# 等值连接
select * from emp join dept on emp.deptno=dept.deptno;

# 不等值连接
select * from emp join dept on emp.deptno>dept.deptno;

4.4.2 内连接

只有进行连接的两个表中都存在与连接条件相匹配的数据才会被保留下来。

select 
    e.empno,e.ename,d.deptno 
from emp e 
join dept d 
on e.deptno=d.deptno;

4.4.3 左外连接

join操作符左边表中符合where子句的所有记录将会被返回。

select 
    e.empno,e.ename,d.deptno 
from emp e 
left join dept d 
on e.deptno=d.deptno;

4.4.4 右外连接

join操作符右边表中符合where子句的所有记录将会被返回。

select 
    e.empno,e.ename,d.deptno 
from emp e 
right join dept d 
on e.deptno=d.deptno;

4.4.5 满外连接

返回表中符合where语句条件的所有记录。如果任一表的指定字段没有符合条件的值的话,那么就使用null值替代。

select 
    e.empno,e.ename,d.deptno 
from emp e 
full join dept d 
on e.deptno=d.deptno;

4.4.6 多表连接

连接n个表,至少需要n-1个连接条件。如连接三个表,至少需要两个连接条件。

select 
    e.ename,d.dname,l.loc_name
from emp e 
join dept d 
on e.deptno=d.deptno
join location l
on d.loc=l.loc;

4.4.7 笛卡尔集

笛卡尔积会在下面条件下产生:

  1. 省略连接条件

  1. 连接条件无效

  1. 所有表中的所有行互相连接

4.4.8 联合union & union all

union和union all都是上下拼接sql的结果。join是左右关联,union和union all是上下拼接,union去重,union all不去重。

union和union all在上下拼接sql结果时右两个要求:

  1. 两个sql的结果,列的个数必须相同

  1. 两个sql的结果,上下所对应列的类型必须一致

select
    empno,ename,job,sal,deptno
from emp
where deptno=30

union

select
    empno,ename,job,sal,deptno
from emp
where deptno=40

总结

4.5 排序

4.5.1 全局排序(order by)

order by 全局排序,只有一个reduce。

# 升序排序。默认为升序排序
select * from emp order by sal asc;
# 降序排序
select * from emp order by sal desc;

hive sql执行过程:

通过一个mapreduce来完成计算,map可能会有多个。如果文件过大,mr在读取文件的时候可能会对文件进行切片。由于order by是全局排序,即对表里所有的数据进行排序,所以在我们使用的时候,指定reduce的个数是没有用的,必须把所有的数据都放到一个reduce里面才能保障全局有序。

而如果指定reduce个数大于一个,我们只能保证每一个reduce里的数据是有序的,无法做到全局有序。而如果数据量非常大,使用order by进行排序,所有语句都会进入到一个reduce中,影响运行效率。

一般会配合limit语句进行优化。使用limit语句优化的reduce端同样只有一个,但是在map端会进行优化。如:有10,000条数据,使用limit 100之后,两个map端只会返回前100行的数据。而reduce只需要在两个map各自的100条数据里筛选出前100条数据,不用再处理全部数据。

4.5.2 每个reduce内部排序(sort by)

对于大规模数据集,order by的效率非常低下(只有一个reduce)。在很多情况下不需要全局排序,此时可以使用sort by。

sort by为每一个reduce产生一个排序文件。每个reduce内部进行排序,对全局结果集来说不是排序。

设置reduce个数

set mapreduce.job.reduces=3;

查看设置reduce个数

set mapreduce.job.reduces;

根据编号查询学生信息

select * from student sort by id;

4.5.3 分区(distribute by)

指定mapreduce的分区字段。map到reduce端需要进行shuffle,即根据指定字段进行hash分区,distribude by就是指定分区字段。

distribute by类似mapreduce中partition(自定义分区)进行分区,结合sort by使用。对于distribute by一定要分配多reduce进行处理,否则无法看到效果。

select * from student
distribute by name
sort by id desc;

4.5.4 分区排序(cluster by)

当distribude by 和sort by 字段相同时,可以使用cluster by 字段。同时具有distrubude by+sort by功能,但是只能升序排序,不能指定排序规则为asc或desc

总结

order by 是全局排序,无论设置reduce的个数为多少,都只有一个reduce,效率较低。

sort by是区内排序。单独使用sort by的时候,随机划分数据所在区,往往和distribute by连用。

distribute by使用字段来帮助分区,通过sort by来排序。

distribute by和sort by字段相同,且都是升序是,可以用cluster by来代替。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值