第 2 章 基础操作

2.7 命令行界面

2.7.1 CLI 选项

hivesql 定义变量 hive自定义变量_hive

hive --help
-- 查看 cli 服务的使用帮助
hive --service cli --help

hivesql 定义变量 hive自定义变量_hivesql 定义变量_02

2.7.2 变量和属性

hivesql 定义变量 hive自定义变量_ci_03

-- 显示以上所有命名空间中的变量和属性
set;
-- 显示以上所有命名空间中的变量和属性,以及Hadoop中定义的所有属性
set -v;
-- 新建自定义属性
 set foo = bar;
-- 查看自定义属性,等价于 set hiveconf:foo;
set foo;
-- 查看自定义属性
set hiveconf:foo;
-- 引用自定义属性
create table t3(i int, ${hiveconf:foo} string);
-- 新建自定义变量
set hivevar:foo2 = bar2;
-- 查看自定义变量
set hivevar:foo2;
-- 查看自定义变量
set foo2;
-- 引用自定义变量
create table t1(i int, ${foo2} string);
-- 引用自定义变量
create table t2(i int, ${hivevar:foo2} string);
-- 进入hive时就更改了这个配置属性,显示当前所处的数据库,注意=左右不要有空格
hive --hiveconf hive.cli.print.current.db=true;
-- 修改配置属性
set hive.cli.print.current.db= false;
-- 修改配置属性
set hiveconf:hive.cli.print.current.db = true;
-- 查看系统变量(不能省略system:)
set system:user.name;
-- 查看环境变量(不能省略env:)
set env:HOME;

2.7.7 查看操作命令历史

$HOME/.hivehistory

2.7.8 执行shell命令

-- 只能执行简单的shell命令
! /bin/echo ${hiveconf:foo};

2.7.9 在Hive中使用Hadoop的dfs命令

dfs -ls /;

2.7.10 Hive脚本中如何进行注释

-- Hive注释

具体直接看书,随用随查,没必要浪费时间手动做一遍

2.7.3 Hive中的“一次使用”命令
2.7.4 从文件中执行Hive查询
2.7.5 hiverc文件

第 3 章 数据类型和文件格式

3.1 基本数据类型

hivesql 定义变量 hive自定义变量_hivesql 定义变量_04

所有这些类型都是对Java接口的实现,这些类型的具体行为细节和Java中对应的类型是完全一致的。

3.2 集合数据类型

hivesql 定义变量 hive自定义变量_hive_05

hivesql 定义变量 hive自定义变量_ci_06

hivesql 定义变量 hive自定义变量_ci_07

3.3 文本文件数据编码

hivesql 定义变量 hive自定义变量_ci_08

create table employees (
-- 放在hive命令行执行前可以先去除Tab
	name string,
	salary float,
	subordinates array<string>,
	deductions map<string, float>,
	address struct<street:string, city:string, state:string, zip:int>
)
row format delimited
fields terminated by '\001'
collection items terminated by '\002'
map keys terminated by '\003'
lines terminated by '\n'
stored as textfile;

3.4 读时模式

hivesql 定义变量 hive自定义变量_hivesql 定义变量_09

第 4 章 HiveQL:数据定义

4.1 Hive中的数据库

Hive 数据库本质仅仅是一个目录或者命名空间。

-- 如果不存在就创建,如果存在不会报错
create database if not exists mydb; 

-- 如果不存在就创建,如果存在会报错
create database mydb; 

show databases like 'm.*';

use mydb;

show tables like 'e.*';

-- 创建数据库时指定对应的 hdfs 路径(location),添加描述信息(comment),添加属性(dbproperties)
-- 默认数据库 default 的路径是属性 hive.metastore.warehouse.dir 配置的路径
create database d4 comment 'about something' location '/d4' with dbproperties('creator' = 'Tom', 'date' = '2021-04-29');

-- 显示当前数据库
set hive.cli.print.current.db=true;

-- 查看当前数据库
select current_database();

-- extended,展示属性信息
desc database extended d4;

-- 修改或添加属性信息,不可删除
alter database d4 set dbproperties('creator'= 'Jack');

-- 如果 d1 不存在,不会报错;如果 d1 存在且有大于0张表,会报错
drop database if exists d1;

-- 如果 d1 存在,就先把他的所有表删除(cascade),再把 d1 删除
drop database if exists d1 cascade;

4.3 创建表

-- 创建表
create table if not exists d4.employees (
-- 放在hive命令行执行前可以先去除Tab
	name string comment 'Employee name',
	salary float comment 'Employee salary',
	subordinates array<string> comment 'Names of subordinates',
	deductions map<string, float> comment 'Keys are deductions names, values are percentages',
	address struct<street:string, city:string, state:string, zip:int> comment 'Home address'
)
comment 'Description of the table'
tblproperties ('creator'='Tom', 'created_time'='2021-04-29');
-- 查看表信息
describe extended d4.employees;
desc formatted d4.employees;

-- 创建一张和表employees结构一样的新表employees3
create table if not exists d4.employees3 like d4.employees;

4.3.1 内部表

删除内部表,会删除数据。

4.3.2 外部表

删除外部表,不会删除数据,但元数据信息会删除。

-- 创建外部表
create external table if not exists external_t1 (col string) row format delimited fields terminated by ',' location '/data/external_t1';

-- 创建一张结构和external_t1一样的外部表external_t2
create external table if not exists external_t2 like external_t1 location '/path/to/data';

4.4 分区表

create table if not exists d4.employees100 (
-- 放在hive命令行执行前可以先去除Tab
	name string comment 'Employee name',
	salary float comment 'Employee salary',
	subordinates array<string> comment 'Names of subordinates',
	deductions map<string, float> comment 'Keys are deductions names, values are percentages',
	address struct<street:string, city:string, state:string, zip:int> comment 'Home address'
)
partitioned by (country string, state string);
-- 强制要求查询时要指定分区,否则报错
set hive.mapred.mode = strict;

-- 查询时不必指定分区
set hive.mapred.mode = nonstrict;

-- 查看分区
show partitions employees100;
show partitions employees100 partition(country='US');

-- 查看某个分区信息
desc formatted employees100 partition(country='China', state = 'Beijing');

4.5 删除表

drop table if exists external_t1;
<!-- core-site.xml 配置trash机制,删除文件会存入trash,超过1440后删除trash -->
<property>
        <name>fs.trash.interval</name>
        <value>1440</value>
        <description>Number of minutes between trash checkpoints. If zero, the trash feature is disabled.</description>
</property>

4.6 修改表

-- 重命名表
 alter table employees rename to emps;

-- 添加分区,/d4/employees100/country=China/state=Beijing
alter table employees100 add if not exists partition(country = 'China', state = 'Beijing') ;
-- 添加分区,/d4/employees100/jap/d
alter table employees100 add if not exists partition(country = 'JAP', state = 'D') location '/d4/employees100/jap/d'

-- 更改分区路径,不会删除旧路径数据
alter table employees100 partition(country = 'US', state = 'NBA') set location '/d4/employees100/country=US/state=NBA';

-- 删除分区
alter table employees100 drop if exists partition(country = 'US', state = 'NBA');

-- 修改列,本身就在第一个位置的字段把after name语句换成first
alter table employees100 change column salary pay float comment 'salary' after name;

-- 增加列
alter table employees100 add columns(app_name string comment 'apps');

-- 删除并替换列,把原来的所有列(除了分区列)删除,并用这些新列
alter table employees100 replace columns(
	name string comment 'Employee name',
	salary float comment 'Employee salary',
	subordinates array<string> comment 'Names of subordinates',
	deductions map<string, float> comment 'Keys are deductions names, values are percentages',
	address struct<street:string, city:string, state:string, zip:int> comment 'Home address'
)

-- 修改表属性
 alter table employees100 set tblproperties('prop' = 'prop');

-- 修改表的存储属性,如存储文件类型,略

-- 把一个分区打包成一个har包,减少文件数,减轻NameNode压力,但不会节省存储空间
alter table employees100 archive partition (country="China",state="Beijing")
-- 把一个分区har包还原成原来的分区
alter table employees100 unarchive partition (country="China",state="Beijing")
-- 保护分区防止被删除
alter table employees100 partition (country="China",state="Beijing") enable no_drop
-- 保护分区防止被查询
alter table employees100 partition (country="China",state="Beijing") enable offline
-- 允许分区删除和查询
alter table employees100 partition (country="China",state="Beijing") disable no_drop
alter table employees100 partition (country="China",state="Beijing") disable offline

第 5 章 HiveQL:数据操作

-- 创建表
create table mydb.employees (
-- 放在hive命令行执行前可以先去除Tab
	name string comment 'Employee name',
	salary float comment 'Employee salary',
	subordinates array<string> comment 'Names of subordinates',
	deductions map<string, float> comment 'Keys are deductions names, values are percentages',
	address struct<street:string, city:string, state:string, zip:int> comment 'Home address'
)
row format delimited
fields terminated by ','
collection items terminated by '#'
map keys terminated by ':';
-- 数据准备,/home/mi2/env/data/data_type_t1.txt
Tom,5000.0,Tom_sub1#Tom_sub2#Tom_sub3,deduction1:120.0#deduction2:50.0#deduction3:200.0,Tom_street#Tom_city#Tom_state#123456
Jack,6000.0,Jack_sub1#Jack_sub2#Jack_sub3,deduction1:120.0#deduction2:50.0#deduction3:200.0,Jack_street#Jack_city#Jack_state#123456

导入数据

-- 从本地文件导入数据到Hive表
load data local inpath '/home/mi2/env/data/data_type_t1.txt' overwrite into table employees;
-- 说明:
-- 1)local表示加载本地文件,如果加载hdfs文件就不用local
-- 2)overwrite是覆盖写,如果追加写就不用overwrite
-- 3)partition是分区表,如果不是分区表就不用partition
load data local inpath '/home/mi2/env/data/data_type_t1.txt' overwrite into table employees  partition (country = 'US', state = 'CA');
-- 从查询插入数据,覆盖写
insert overwrite table employees select * from employees;

-- 从查询插入数据,追加写
insert into table employees select * from employees;

-- 从查询插入数据,覆盖写入某分区
insert overwrite table employees partition(country = 'US', state = 'CA') select * from employees;
-- 查询不同数据插入到不同分区(静态手写)
from staged_employees select
insert overwrite table employees
	partition(country = 'US', state = 'OR')
	select * where se.country = 'US' and se.state = 'OR'
insert overwrite table employees
	partition(country = 'US', state = 'CA')
	select * where se.country = 'US' and se.state = 'CA'
insert overwrite table employees
	partition(country = 'US', state = 'IL')
	select * where se.country = 'US' and se.state = 'IL'
-- 动态导入分区,country/state的值由select语句最后两列确定,根据位置匹配
insert overwrite table employees partition (country, state)
select ...,se.country,se.state from staged_employees se;

-- 动态和静态方式导入分区结合,静态分区名字必须在动态分区名字前
insert overwrite table employees partition (country = 'US', state)
select ...,se.country,se.state from staged_employees se where se.country = 'US';

hivesql 定义变量 hive自定义变量_hive_10

-- 可以在HiveQL之前设定配置属性值
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.exec.max.dynamic.partitions.pernode=100;

导出数据

-- overwrite/into表示覆盖写/追加写,local表示本地
insert overwrite local directory '/home/mi2/env/data/export_data_1'
select name, salary, address from employees;

第 6 章 HiveQL:查询

6.1 SELECT…FROM

select * from employees limit 1;
-- 查询结果
Tom	5000.0	["Tom_sub1","Tom_sub2","Tom_sub3"]	{"deduction1":120.0,"deduction2":50.0,"deduction3":200.0}	{"street":"Tom_street","city":"Tom_city","state":"Tom_state","zip":123456}

select name, salary, subordinates[0], deductions['deduction1'], address.city from employees;
-- 查询结果
Tom	5000.0	Tom_sub1	120.0	Tom_city
Jack	6000.0	Jack_sub1	120.0	Jack_city

select upper(name), salary, deductions['deduction1'],round(salary - deductions['deduction1']) from employees;
-- 查询结果
TOM	5000.0	120.0	4880.0
JACK	6000.0	120.0	5880.0

算术运算符

Hive遵循的是底层Java中数据类型的规则。

hivesql 定义变量 hive自定义变量_Hive_11

函数

-- 显示Hive所有函数
 show functions;
-- 查看某函数的说明
 desc function when;
-- 查看某函数的详细说明
desc function extended abs;

hivesql 定义变量 hive自定义变量_Hive_12

hivesql 定义变量 hive自定义变量_ci_13

select name, explode(subordinates) from employees;
 -- 报错,只能包含一列explode(subordinates),不能包含其他列
FAILED: SemanticException [Error 10081]: UDTF's are not supported outside the SELECT clause, nor nested in expressions

-- 包含其他列的查法
select name, sub from employees lateral view explode(subordinates) subView as sub;

hivesql 定义变量 hive自定义变量_hive_14


hivesql 定义变量 hive自定义变量_Hive_15


hivesql 定义变量 hive自定义变量_hivesql 定义变量_16


hivesql 定义变量 hive自定义变量_Hive_17


hivesql 定义变量 hive自定义变量_hive_18


hivesql 定义变量 hive自定义变量_hivesql 定义变量_19


说明:用户自定义函数需要写JAVA类并达成JAR包进入(第13章)。

嵌套查询

select t.name from (select * from mydb.employees) t;

CASE…WHEN…THEN

select name, salary,
	case 
		when salary < 3000.0 then 'low'
		when salary >= 3000.0 and salary < 5000.0 then 'middle'
		when salary >= 5000.0 and salary < 7000.0 then 'high'
		else 'very high'
	end as bracket
from employees;

什么情况下Hive可以避免MapReduce

-- 笔者实践发现,不管是否开启本地模式(hive.exec.mode.local.auto),简单查询(无聚合等操作,如count)都不会MapReduce
select name, salary*1.1 from employees where salary < 10000.0;

6.2 WHERE语句

hivesql 定义变量 hive自定义变量_hivesql 定义变量_20

注意
1)浮点比较误差,尽量不要进行浮点比较,若非要比较,得避免float自动转double情况
2)LIKE只有%和_两个匹配字符,RLIKE/REGEXP后是真的正则表达式

6.3 GROUP BY

select name, avg(salary)
from employees
where salary >= cast(5000.0 as float)
group by name
having avg(salary) >= cast(3000.0 as float);

6.4 JOIN

只支持等值连接(且on后多个等值条件不支持or,只能是and),不支持自然连接(要有相同属性的列,连接后去除重复列),不支持非等值连接(on后的条件不是=,而是<等)。

select e1.name, e1.salary
from employees e1 join employees e2
on e1.name = e2.name
where e1.name = 'Tom';
select e1.name, e1.salary
from employees e1 join employees e2
on e1.salary < e2.salary	-- 不支持
where e1.name = 'Tom';
注意
1)三个及以上表join,如果每个on都使用相同的连接键,只会产生一个MapReduce job,Hive假定最后一个表是最大的表,用户要保证连续查询的表从左到右是依次增大的(如果只有一个小表,可以设置hive.auto.convert.join=true,把小表放在内存里,加速!也可也设置小表大小hive.mapjoin.smalltable.filesize)。
2)连接类型
[INNER] JOIN
LEFT [OUTER] JOIN
RIGHT [OUTER] JOIN
FULL [OUTER] JOIN
LEFT SEMI JOIN(查询结果只显示左表的)
笛卡尔积(如:select * from a join b,设置hive.mapred.mode=strict可以禁用笛卡尔积)

6.5 ORDER BY 和 SORT BY

order by:全局排序(可能很耗时)
sort by:只是每个reducer有序
select name, salary from employees order by name asc, salary desc;

6.6 含有SORT BY的DISTRIBUTE BY

默认情况下,MapReduce计算框架会根据map输入的键计算相应的哈希值,然后按照哈希值把键值对均匀地分发到多个reducer。而distribute by col可以把相同的col分布到同一个reducer,然后再sort by排序。

-- 如果distribute by和sort by后的条件一样,就等价于cluster by(不能降序!),可以实现全局排序
select name, salary from employees distribute by name sort by name asc, salary desc;

6.8 类型转换

Hive默认隐式类型转换,底层就是Java,窄类型自动转宽类型。而强制类型转换可以用cast,cast可嵌套使用。

6.9 抽样查询

6.10 UNION ALL

将两个及以上表合并,每个表有相同的列,且列的数据类型一样。

第 7 章 HiveQL:视图

hivesql 定义变量 hive自定义变量_ci_21

-- 视图是只读的
create view view_01 as
select name, salary from employees;
-- 在存放Hive元数据的MySQL数据库hive中查询所有的视图
select TBL_NAME from TBLS where TBL_TYPE = 'VIRTUAL_VIEW';

第 8 章 HiveQL:索引

Hive的索引其实是一张索引表(Hive的物理表),在表里面存储索引列的值,该值对应的HDFS的文件路径,该值在数据文件中的偏移量。

hivesql 定义变量 hive自定义变量_hivesql 定义变量_22

-- 建立分区表 employees10
create table mydb.employees10 (
-- 放在hive命令行执行前可以先去除Tab
	name string comment 'Employee name',
	salary float comment 'Employee salary',
	subordinates array<string> comment 'Names of subordinates',
	deductions map<string, float> comment 'Keys are deductions names, values are percentages',
	address struct<street:string, city:string, state:string, zip:int> comment 'Home address'
)
partitioned by (country string, city string)
row format delimited
fields terminated by ','
collection items terminated by '#'
map keys terminated by ':';

-- 导入数据
load data local inpath '/home/mi2/env/data/data_type_t1.txt' overwrite into table employees10  partition (country = 'US', city = 'CA');

-- 创建索引
create index employees10_index
on table employees10 (name)
as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'
with deferred rebuild
idxproperties ('creator' = 'creator', 'ct' = '2021-04-30')
in table employees10_index_tb
comment 'Employees indexed by name';

-- 查看索引
show formatted index on employees10;

-- 生成索引(书简直是坑死人了,on后多了个table)
alter index employees10_index on employees10 rebuild;

-- 删除索引
drop index employees10_index on employees10;

第 9 章 模式设计

hivesql 定义变量 hive自定义变量_hivesql 定义变量_23


hivesql 定义变量 hive自定义变量_Hive_24


hivesql 定义变量 hive自定义变量_ci_25