1. 数据定义语言概述
1.1 常见的开发方式
(1) Hive CLI、Beeline CLI
Hive自带的命令行客户端
优点:不需要额外安装
缺点:编写SQL环境恶劣,无有效提示,无语法高亮,误操作率高
(2) 文本编辑器
Sublime、Emacs、EditPlus等
有些不支持作为客户端连接Hive服务,但支持SQL语法环境,那就在编辑器中开发SQL,复制到Hive CLI执行;有些支持安装插件作为客户端直连Hive服务;
(3) Hive可视化工具
IntelliJ IDEA、DataGrip、Dbeaver、SQuirrel SQL Client等
可以在Windows、MAC平台中通过JDBC连接HiveServer2的图像界面工具
Hive可视化工具IntelliJ IDEA
-
配置Hive数据源
在IDEA的任意工程中,选择Database标配前配置Hive Driver驱动
配置Driver
-
配置数据源
配置Hive数据源,连接HS2
配置数据源
-
Hive可视化使用
编写代码,选择需要执行的代码,右键执行
1.2 DDL概述
SQL中DDL语法的作用
数据定义语言是SQL语言集中对数据库内部的对象结构进行创建,删除,修改等的草是做语言。DDL核心语法由CREATE、ALTER与DROP三个组成,DDL并不涉及表内部数据的操作。
Hive中DDL语法的使用
Hive SQL与标准SQL的语法大同小异,基本相通
基于Hive的设计、使用特点,HQL中create语法(尤其create table)将是学习掌握Hive DDL语法的重中之重
重点:完整语法树
HIVE DDL CREATE TABLE
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[ASC|DESC], ...)] INTO num_buckets BUCKETS]
[ROW FORMAT DELIMITED|SERDE serde_name WITH SERDEPROPERTIES (property_name=property_value, ...)]
[STORED AS file_format]
[LOCATION hdfs_path]
[TBLPROPERTIES (property_name=property_value, ...)]
1.3 Hive数据类型详解
Hive数据类型指的是表中列的字段类型
整体分为两类:原生数据类型和复杂数据类型
原生数据类型:数值类型、时间日期类型、字符串类型、杂项数据类型
复杂数据类型:array数组、map映射、struct结构、union联合体
注意事项
- Hive SQL中,数据类型英文字母与大小写不明干
- 除SQL数据类型外,还支持Java数据类型,比如字符串string
- 复杂数据类型的使用通常需要和分隔符指定语法配合使用
- 如果定义的数据类型和文件不一致,Hive会尝试隐式转化、但是不保证成功
显示类型转换使用CAST函数,比如 CAST(‘100’ as INT),但是转换失败会返回null
1.4 Hive读写文件机制
SerDe
- SerDe是Serializer、Deserializer的简称,目的是用于序列化和反序列化
- 序列化时对象转化为字节码的过程;而反序列化时字节码转换为对象的过程
- Hive使用SerDe(包括FileFormat)读取和写入表行都西昂。需要注意的时,“key”部分在读取时会被忽略,而在写入时key始终是常数。基本上行对象存储在“value”中。
Read:
HDFS files -> InputFileFormat -> <key,value> -> Deserializer -> Deserializer(反序列化) -> Row object
Write:
Row object -> Serializer(序列化) -> <key,value> -> OutputFileFormat -> HDFS files
SerDe相关语法
ROW FORMAT这一行所代表的是读写文件、序列化SerDe相关的语法,功能有两个:
1.使用哪个SerDe类进行序列化; 2.如何指定分隔符
[ROW FORMAT DELIMITED|SERDE serde_name WITH SERDEPROPERTIES (property_name=property_value, ...)]
DELIMITED和SERDE选其一,如果使用delimited表示使用默认的LazySimpleSerDe类来处理数据;如果数据文件格式比较特殊可以使用ROW FORMAT SERDE serde_name指定其他的Serde类来处理数据,甚至支持用户自定义SerDe类
LazySimpleSerDe分隔符指定
LazySimpleSerDe是Hive默认的序列化类,包含4中子语法,分别用于指定字段之间、集合元素之间、map映射kv之间、换行的分隔符号。在建表时可以根据数据的特点灵活搭配使用
ROW FORMAT DELIMITED
[FIELDS TERMINATED BY char] ——> 字段之间分隔符
[COLLECTION ITEMS TERMINATED BY char] ——> 集合元素之间分隔符
[MAP KEYS TERMINATED BY char] ——> Map映射kv之间分隔符
[LINES TERMINATED BY char] ——> 行数据之间分隔符
Hive默认分隔符:默认分隔符是’\001’,使用的是ASCII编码的值,键盘打不出。
在vim编辑器中连续输入ctrl+v/ctrl+a即可输入’\001’,显示^A
在一些文本编辑器中将亿SOH的形式显示
指定存储路径
- Hive建表的时候,可以通过localtion语法来更改数据在HDFS上的存储路径,使得建表加载数据更加灵活
- 语法:LOCATION ‘<hdfs_location>’
- 对于已经生成好的数据文件,使用location指定路径将会很方便
[LOCATION hdfs_path]
2.Hive SQL建表基础语法
2.1 Hive建表语法练习
2.1.1 原生数据类型使用
文件名archer.txt,记录了王者荣耀射手的相关信息,包括生命、物防等,其中字段之间分隔符为制表符\t,要求在Hive中建表映射成功该文件
数据示例:
1 马可波罗 5584 200 362 remotely archer
show database;
-- 切换数据库
use testdb;
-- 建表
create table t_archer(
id int comment "ID",
name string comment "英雄名称",
hp_max int comment "最大生命",
mp_max int comment "最大法力",
attack_max int comment "最高物攻",
defense_max int comment "最高物防",
attack_range string comment "攻击范围",
role_main string comment "主要定位",
role_assist string comment "次要定位"
) comment "王者荣耀射手信息"
row format delimited
fields terminated by "\t";
-- 删除表
drop table t_archer;
2.1.2 复杂数据类型使用
文件名hot_hero_skin_price.txt中记录了手游王者荣耀热门的相关皮肤价格信息,要求在Hive中建表映射成功该文件。
数据示例:字段:id、name(英雄名称)、win_rate(胜率)、skin_price(皮肤及价格)
2,鲁班七号,54,木偶奇遇记:288-福禄兄弟:288-兄控梦想:0
3,铠,52,龙域领主:288-曙光守护者:1776
分析:前三个字段原生数据类型,最后一个字段复杂类型map
-- 复杂数据类型建表
create table t_hot_hero_skin_price(
id int,
name string,
win_rate int,
skin_price map<string,int> -- 注意这个map复杂类型
) row format delimited
fields terminated by ',' -- 指定字段之间的分隔符
collection items terminated by '-' -- 指定元素集合之间的分隔符
map keys terminated by ':'; -- 指定map元素kv之间的分隔符
2.1.3 默认分隔符使用
文件名team_ace_player.txt,记录了主要战队内最受欢迎的王牌选手信息,字段之间使用的是\001作为分隔符,要求在Hive中建表映射成功该文件
数据示例:
1^A成都AG超会玩^A一诺
分析:数据都是原生数据类型,且字段之间分隔符是\001,因此建表的是偶可以省去row format语句
create table t_team_ace_player(
id int,
team_name string,
ace_player_name string
); -- 没有指定row format语句,此时采用的是默认的\001作为字段的分隔符
2.1.4 指定数据存储路径
文件名team_ace_player.txt,记录了主要战队内最受欢迎的王牌选手信息,字段之间使用的是\001作为分隔符,要求把文件上传到HDFS任意路径下,不能移动复制,并在Hive中建表映射成功该文件
create table t_team_ace_player(
id int,
team_name string,
ace_player_name string
) location '/date'; -- 使用location关键字指定本张表在hdfs上的存储路径
2.Hive 内、外部表
内部表
内部表也称为Hive拥有和管理的托管表
默认情况下创建的表都是内部表,Hive拥有该表的结构和文件(Hive 完全管理表的生命周期),删除时会删除数据及表的元数据
可以使用DESCRIBE FORMATTED tablename,来获取表的元数据描述信息,从中可以看出表的类型
外部表
外部表中的数据不是Hive拥有或管理的,只管理表元数据的生命周期
使用EXTERNAL关键字创建外部表
删除外部表只会删除元数据,而不会删除实际数据
外部表搭配location语法指定数据的路径更安全
-- 创建外部表 需要关键字external
-- 外部表数据存储路径不指定 默认规则和内部表一致
-- 也可以使用location关键字指定HDFS任意路径
create external table student_ext(
num int,
name string,
sex string,
age int,
dept string
)row format delimited
fields terminated by ','
location '/stu';
如何选择内、外部表
当需要通过Hive完全管理控制表的整个生命周期时,请使用内部表
当数据来之不易,防止误删,请使用外部表,因为即使删除表,文件也会被保留
location关键字的作用
- 在创建外部表的时候,可以使用location指定存储位置路径,如果不指定会如何?
- 如果不指定location,外部表的默认路径也是位于/usr/hive/warehouse,由默认参数控制
- 创建内部表的时候,是否可以使用location指定?
- 内部表可以使用location指定位置
- 是否意味着Hive表的数据在HDFS上的位置不是一定要在/usr/hive/warehouse下?
- 不一定,Hive中表数据存储位置,不管内部表还是外部表,默认都是在/usr/hive/warehouse,当然可以在建表的时候通过location关键字指定存储位置在HDFS的任意位置
3.分区表
3.1 分区表产生背景
现有6章结构化数据文件,分别记录王者荣耀中6中位置的英雄信息,现要求通过建立一张表t_all_hero,把6份文件同时映射加载
只需创建t_all_hero表,然后将6张表拷贝到指定路径即可。
现要求查询role_main主要定位时射手并且hp_max最大生命大于6000的几个,sql语句如下
select count(*) from t_all_hero where role_main="archer" and hp_max>6000;
存在的问题:
- where语句的背后需要进行全表扫描才能过滤出结果,对于hive来说需要扫描每一个文件。如果数据文件特表多的话,扫描效率很慢也没有必要
- 本需求中,只需扫描archer.txt文件即可
- 指定文件扫描和全表扫描,效率存在差异
分区表概念
当Hive表对应的数据量大、文件个数多时,为了避免查询时全表扫描数据,Hive支持根据指定的字段对表进行分区,分区的字段可以时日期、地域、种类等具有标识意义的字段
-- 注意分区表创建语法规则
create table t_all_hero_part(
id int,
name string,
hp_max int,
mp_max int,
attack_max int,
defense_max int,
role_main string,
role_assist string
) partitioned by (role string) -- 分区字段
row format delimited
fields terminated by "\t";
注意:分区字段不能是表中已经存在的字段,因为分区字段最终也会以虚拟字段的形式显示在表结构上。
3.2 分区表数据加载——静态分区
静态分区
所谓静态分区是指分区的属性值由用户在加载数据的时候手动指定的
语法如下
load data [local] inpath 'filepath' into table tablename partition(分区字段='分区值'...);
Local参数用于指定待加载的数据是位于本地文件系统还是HDFS文件系统。
-- 静态加载分区表数据
load data local inpath '/root/hivedata/archer.txt' into table t_all_hero_part partition(role='sheshou');
load data local inpath '/root/hivedata/assassin.txt' into table t_all_hero_part partition(role='cike');
...
本质
- 分区的概念提供了一种将Hive表数据分离为多个文件/目录的方法
- 不同分区对应着不同的文件夹,同一分区的数据存储在同一个文件夹下
- 查询过滤的时候只需要根据分区值找到对应的文件夹,扫描文件夹下本分区下的文件即可,避免全表数据扫描
- 这种指定分区查询的方式叫做分区裁剪
3.3 多重分区表
通过建表语句中关于分区的相关语法可以发现,Hive支持多个分区字段:
PARTITIONED BY (partition1 data_type, partition2 data_type,…)
多重分区下,分区之间时一种递进关系,可以理解为在前一个分区的基础上继续分区
从HDFS的角度来看就是文件夹下继续瓜分子文件夹。
-- 单分区表,按身份分区
create table t_user_province (id int, name string, age int) partitiond by (province string);
-- 双分区表,按省份和市分区
-- 分区字段之间时一种递进的关系,因此要注意分区字段的顺序
create table t_user_province_city (id int, name string, age int) partitiond by (province string, city string);
-- 双分区表的数据加载 静态分区加载数据
load data local inpath '/root/hivedata/user.txt' into table t_user_province_city partition(province='zhejiang', city='hangzhou');
...
-- 双分区表的使用,使用分区进行过滤 减少全表扫描 提高效率
select * from t_user_province_city where province='zhejiang' and city='hangzhou';
3.4 分区表数据加载——动态分区
动态分区
动态分区就是分区的字段值是基于查询结果(参数位置)自动推断出来的。
核心语法:insert+select
启用hive动态分区,需要在hive绘画中设置两个参数:
# 是否启用动态分区功能
set hive.exec.dynamic.partition=true;
# 指定动态分区模式,分别为nonstrict非严格模式和strict严格模式
# strict严格模式要求至少由一个分区为静态分区
set hive.exec.dynamic.partition.mode=nonstrict;
-- 从一张已有的表中执行动态分区插入
insert into table t_all_hero_part_dynamic partition(role) -- 注意:分区值并没有手动写死指定
select tmp.*, tmp.role_main from t_all_hero tmp;
4.分桶表
概念
分桶表也叫桶表,是一种用于优化查询而设计的表类型
分桶表对应的数据文件在底层会被分解为若干个部分,通俗来说就是被拆分分成若干个独立的小文件。
在分桶时,要指定根据哪个字段将数据分为几桶。
规则
分桶规则如下:桶编号相同的数据会被分到同一个桶当中
Bucket number=hash_function(bucketing_column) mod num_buckets
分桶编号 =哈希方法 (分桶字段) 取模 分桶个数
hash_function取决于分桶字段bucketing_column的类型:
- 如果是int类型,hash_function(int) == int;
- 如果是其他比如bigint,string或者复杂数据类型,hash_function比较棘手,将是从该类型派生的某个数字,比如hashcode值
语法
-- 分桶表建表语句
CREATE [EXTERNAL] TABLE [db_name.]table_name
[(col_name data_type,...)]
CLUSTERED BY (col_name)
INTO N BUCKETS;
CLUSTERED BY (col_name) 表示根据哪个字段分;
INTO N BUCKETS表示分为几个桶
注意:分桶的字段必须是表中已有字段
分桶表的创建
现有美国2021-1-28号,各县county的新馆疫情累计案例信息,包括确证病例和死亡病例
数据示例:包含字段count_date(统计日期),county(县),fips(县编码code),cases(累计确诊病例),deaths(累计死亡病例)
2021-01-28,Jefferson,Alabama,01073,65992,1101
...
根据state州把数据分为5桶,建表语句如下:
CREATE TABLE itheima.t_usa_covid19(
count_date string,
county string,
state string,
fips int,
cases int,
deaths int
) CLUSTERED BY(state) INTO 5 BUCKETS;
在创建分桶表时,还可以指定分桶内的数据排序规则:
-- 根据state州分为5桶,每个桶内根据cases确诊病例数倒序排序
CREATE TABLE itheima.t_usa_covid19(
count_date string,
county string,
state string,
fips int,
cases int,
deaths int
) CLUSTERED BY(state)
sorted by (cases desc) INTO 5 BUCKETS;
分桶表数据加载
-- step1:开启分桶的功能 从Hive2.0开始不再需要设置
set hive.enforce.bucketing=true;
-- step2:把数据加载到普通hive表
drop table if exists t_usa_covid19(
count_date string,
county string,
state string,
fips int,
cases int,
deaths int
) row format delimited fields terminated by ",";
-- 将源数据上传到HDFS,t_usa_covid19表对应的路径下
hadoop fs -put 源数据 目标路径
-- step3:使用insert+select语法将数据加载到分桶表中
insert into t_usa_covid19_bucket select * from t_usa_covid19;
好处
- 基于分桶字段查询时,减少全表扫描
-- 基于分桶字段state查询来自于New York州的数据
-- 不再需要进行全表扫描过滤
-- 根据分桶的规则hash_function(New York) mod 5 计算出分桶编号
-- 查询指定分桶里面的数据
select * from t_usa_covid19_bucket where state="New York";
-
JOIN时可以提高MR程序效率,减少笛卡尔积数量
根据join的字段对表进行分桶操作 -
分桶表数据进行高效抽样
当数据量特别大时,对全体数据进行处理存在困难时,抽样就显得尤其重要了。抽样可以从被抽取的数据中估计和推断出整体的特性。
5.事务表
局限性
- 尚不支持BEGIN,COMMIT和ROLLBACK。所有语言操作都是自动提交的
- 仅支持ORC文件格式(STORED AS ORC)
- 默认情况下事务配置为关闭。需要配置参数开启使用
- 表必须是分桶表才可以使用事务功能
- 表参数transactional必须为true
- 外部表不能成为ACID表,不允许从非ACID会话读取/写入ACID表
创建使用Hive事务表
在Hive中创建一张具备事务功能的表,并尝试进行增删改操作
-- Hive 事务表
-- step1,创建普通的表
drop table if exists student;
create table student(
num int,
name string,
sex string,
age int,
dept string
) row format delimited
fields terminated by ',';
-- step2:加载数据到普通表中
load data local inpath '/root/hivedata/student.txt' into table student;
select * from student;
-- Hive中事务表的创建使用
-- 1.开启事务配置(可以使用set设置当前session生效 也可以配置在hive-site.xml中)
set hive.support.concurrency = true; -- Hive是否支持并发
set hive.enforce.bucketing = true; -- 从Hive2.0开始就不再需要 是否开启分桶功能
set hive.exec.dynamic.partition.mode = nonstrict; -- 动态分区模式 非严格
set hive.txn.manager = org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.compactor.initiator.on = true; -- 是否在Metastore实例上运行启动线程和清理线程
set hive.compactor.worker.threads = 1; -- 在此metastore实例上运行多个压缩程序工作线程
-- 2.创建Hive事务表
create table trans_student(
id int,
name string,
age int
) clustered by (id) into 2 buckets stored as orc TBLPROPERTIES('transactional'='true');
--注意:事务表创建几个要素:开启参数、分桶、存储格式orc、表属性
-- 3.针对事务表进行insert update delete操作
insert into trans_student values(1,"allen",18);
6.视图
概念
- Hive中的试图是一种虚拟表,只保存定义,不实际存储数据
- 通常从真实的物理表查询中创建生成视图,也可以从已经存在的视图上创建新视图
- 创建视图时,将冻结视图的架构,如果删除或更改基础表,则视图将失效
- 视图是用来简化操作的,不缓冲记录,也没有提高查询性能
-- Hive View 视图相关语法
-- hive中有一张真实的基础表t_usa_covid19
select * from t_usa_covid19;
-- 1.创建视图
create view v_usa_covid19 as select count_date, county, state, deaths from t_usa_covid19 limit 5;
-- 能否从已有的视图中创建视图 可以的
create view v_usa_covid19_from_view as select * from v_usa_covid19 limit 2;
-- 2.显示当前已有的视图
show tables;
show views; -- hive v2.2.0之后支持
-- 3.视图的查询使用
select * from v_usa_covid19;
-- 注意:视图不支持插入数据
-- 4.查看视图定义
show create table v_usa_covid19;
-- 5.删除视图
drop view v_usa_covid19_from_view;
-- 6.更改视图属性
alter view v_usa_covid19 set TBLPROPERTIES ('comment' = 'This is a view');
-- 7.更改视图定义
alter view v_usa_covid19 as select county, deaths from t_usa_covid19 limit 2;
视图的好处
- 将真实表中特定的列数据提供给用户,保护数据隐私
-- 通过视图来限制数据访问可以用来保护信息不被随意查询
create table userinfo(firstname string, lastname string, ssn string, password string);
create view safer_user_info as select firstname,lastname from userinfo;
-- 可以通过where子句限制数据访问,比如,提供一个员工表视图,只暴露来自特定部门的员工信息
create table employee(firstname string, lastname string, ssn string, password string, department string);
create view techops_employee as select firstname, lastname, ssn from userinfo where department='java';
- 降低查询的复杂度,优化查询语句
-- 使用视图优化嵌套查询
from(
select * from people join cart
on(cart.people_id = people.id) where firstname = 'join'
) a select a.lastname where a.id = 3;
-- 把嵌套子查询变成一个视图
create view shorter_join as
select * from people join cart
on(cart.people_id = people.id) where firstname = 'join';
-- 基于视图查询
select lastname from shorter_join where id = 3;
7.Hive3.0新特性:物化视图
概念
- 物化视图是一个包括查询结果的数据库对象,可以用于预先计算并保存表连接或聚集等耗时较多的操作结果。在执行查询时,就可以避免进行这些耗时的操作,从而快速得到的结果
- 使用物化视图的目的就是通过预计算,提高查询性能,当然需要占用一定的存储空间
- Hive3.0开始尝试引入物化视图,并提供对于物化视图的查询自动重写机制(基于Apache Calcite实现)
- Hive的物化视图还提供了物化视图存储选择机制,可以本地存储在Hive,也可以通过用户自定义storage handlers存储在其他系统
- Hive引入物化视图的目的就是为了优化数据查询访问的效率,相当于从数据预处理的角度优化数据访问
- Hive从3.0丢弃了index索引的语法支持,推荐使用物化视图和列式存储文件格式来加快查询的速度
物化视图、视图的区别
- 视图是虚拟的,逻辑存在的,只有定义没有存储数据
- 物化视图是真实存在的,物理存储的,里面存储着与计算的数据
- 视图的目的是简化降低查询的复杂度,而物化视图的目的是提高查询性能
语法
-- 物化视图的创建语法
CREATE MATERIALIZED VIEW [IF NOT EXISTS] [db_name.]materialized_view_name
[DISABLE REWRITE]
[COMMENT materialized_view_comment]
[PARTITIONED ON (col_name, ...)]
[CLUSTERED ON (col_name, ...) | DISTRIBUTED ON (col_name, ...) SORTED ON (col_name, ...)]
[
[ROW FORMATE row_format]
[STORED AS file_format]
| STORED BY 'storage.handler.class.name' [WITH SERDEPROPERTIES (...)]
]
[LOCATION hdfs_path]
[TBLPROPERTIES(property_name=property_value, ...)]
AS SELECT ...;
(1) 物化视图创建后,select拆线呢执行数据自动落地,“自动”也即在query的执行期间,任何用户对该物化视图是不可见的,执行完毕之后物化视图可用;
(2) 默认情况下,创建好的物化视图可被用于查询优化器optimizer查询重写,在物化视图创建期间可以通过DISABLE PEWRITE参数设置禁止使用
(3) 默认SerDe和storage format为hive。materializedview.serde、hive.materializedview.fileformat;
(4) 物化视图支持将数据存储在外部系统(如druid),语法如下所示:
CREATE MATERIALIZED VIEW druid_wiki_mv
STORED AS 'org.apache.hadoop.hive.druid.DruidStorageHandler'
AS
SELECT __time,page.user,c_added,c_removed
FROM src;
(5) 目前支持物化视图的drop和show操作,后续会增加其他操作
-- Drops a materialized view
DROP MATERIALIZED VIEW [db_name.]materialized_view_name;
-- Shows materialized views (with optional filters)
SHOW MATERIALIZED VIEW [IN database_name];
-- Shows information about a specific materialized view
DESCRIBE [EXTENDED | FORMATTED] [db_name.]materialized_view_name;
(6) 当数据源变更(新数据插入inserted、数据修改modified),物化视图也需要更新以保持数据一致性,目前需要用户主动触发rebuild重构
ALTER MATERIALIZED VIEW [db_name.]materialized_view_name REBUILD;
基于物化视图的查询重写
- 物化视图创建后即可用于相关查询的加速,即:用户提交查询query,若该query经过重写后可以命中已经存在的物化视图,则直接通过物化视图查询数据返回结果,以实现查询加速
- 是否重写查询使用物化视图可以通过全局参数控制,默认为true:hive.materializedview.rewriting=true;
- 用户可选择性的控制指定的物化视图查询重写机制,语法如下
ALTER MATERIALIZED VIEW [db_name.]materialized_view_name ENABLE|DISABLE REWRITE;
案例:基于物化视图的查询重写
-- 1.新建一张事务表 student_trans
set hive.support.concurrency = true; -- Hive是否支持并发
set hive.enforce.bucketing = true; -- 从Hive2.0开始就不再需要 是否开启分桶功能
set hive.exec.dynamic.partition.mode = nonstrict; -- 动态分区模式 非严格
set hive.txn.manager = org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.compactor.initiator.on = true; --是否在Metastore实例上运行启动线程和清理线程
set hive.compactor.worker.threads= 1 -- 在此metastore实例上运行多少个压缩程序工作线程
drop table if exists student_trans;
CREATE TABLE student_trans(
sno int,
sname string,
sdept string
) clustered by (sno) into 2 buckets stored as orc TBLPROPERTIES('transactional'='true');
-- 2.导入数据到student_trans中
insert overwrite table student_trans
select num,name,dept
from student;
select *
from student_trans;
-- 3.对student_trans建立聚合物化视图
CREATE MATERIALIZED VIEW student_trans_agg
AS SELECT sdept, count(*) as sdept_cnt from student_trans group by sdept;
-- 注意:这里当执行CREATE MATERIALIZED VIEW,会启动一个MR对物化视图进行构建
-- 可以发现当下数据库中有一个物化视图
show tables;
show materialized views;
-- 4.对于原始表student_trans拆线呢
-- 由于会命中物化视图,重写query查询物化视图,查询速度会加快(没有启动MR,只是普通的table scan)
SELECT sdept,count(*) as sdept_cnt from student_trans group by sdept;
-- 5.查询执行计划可以发现 查询被自动重写为 TableScan alias
-- 转化成了物化视图的查询 提高了查询效率
explain SELECT sdept,count(*) as sdept_cnt from student_trans group by sdept;
-- 验证禁用物化视图自动重写
ALTER MATERIALIZED VIEW student_trans_agg DISABLE REWRITE;
-- 删除物化视图
drop materialized view student_trans_agg;
8.Hive Database|Schema(数据库)DDL操作
整体概述
- 在Hive中,DATABASE的概念和RDBMS中类似,称为数据库,DATABASE和SCHEMA是可互换的,都可以使用
- 默认的数据库叫做default,存储数据位于/user/hive/warehouse下
- 用户自己创建的数据库存储位置是/user/hive/warehouse/database_name.db下
create database
用于创建新的数据库
COMMENT:数据库的注释说明语句
LOCATION:指定数据库在HDFS存储位置,默认/user/hive/warehouse/dbname.db
WITH DBPROPERTIES:用于指定一些数据库的属性配置
CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name
[COMMENT database_comment]
[LOCATION hdfs_path]
[WITH DBPROPERTIES (property_name = property_value, ...)];
describe database
显示Hive中数据库的名称,注释(如果已设置)及其在文件系统上的位置等信息
EXTENDED关键字用于显示更多信息。可以将关键字describe简写成desc使用
语法:
DESCRIBE DATABASE|SCHEMA [EXTENDED] db_name;
use database
选择特定的数据库
切换当前会话使用哪个数据库进行操作
drop database
删除数据库
默认行为是RESTRICT,这意味着仅在数据库为空时才删除它。
要删除带有表的数据库(不为空的数据库),我们可以使用CASCADE
DROP (DATABASE|SCHEMA) [IF EXISTS] database_name [RESTRICT|CASCADE];
alter database
更改与Hive中的数据库关联的元数据
-- 更改数据库属性
ALTER (DATABASE|SCHEMA) database_name SET DBPROPERTIES (property_name = property_value, ...);
-- 更改数据库所有者
ALTER (DATABASE|SCHEMA) database_name SET OWNER USER user;
-- 更改数据库位置
ALTER (DATABASE|SCHEMA) database_name SET LOCATION hdfs_path;
-- 创建数据库
create database if not exists test
comment "this is test db"
with dbproperties('createdBy'='Allen');
-- 描述数据库信息
describe database test;
describe database extended test;
desc database extended test;
-- 切换数据库
use default;
use test;
-- 删除数据库
-- 注意:CASCADE关键字谨慎使用
drop database test;
9.Hive Table(表) DDL操作
整体概述
- Hive中针对表的DDL操作可以说时DDL中的核心操作,包括建表、修改表、删除表、描述表元数据信息
- 其中以建表语句为核心中的核心,详见Hive DDL建表语句
- 可以说表的定义是否成功直接影响数据能够成功映射,进而影响是否可以孙俪的使用Hive开展数据分析
- 由于Hive建表之后加载映射数据很快,实际中如果建表有问题,可以不用修改,直接删除重建
describe table
显示Hive中表的元数据信息
如果指定了EXTENDED关键字,则它将以Thrift序列化形式显示表的所有元数据
如果指定了FORMATTED关键字,则它将以表格格式显示元数据
drop table
删除该表的元数据和数据
如果已配置垃圾桶且未指定PURGE,则该表对应的数据实际上将移动到HDFS垃圾桶,而元数据完全丢
删除EXTERNAL表时,该表中的数据不会从文件系统中删除,只删除元数据
如果指定了PURGE,则表数据跳过HDFS垃圾桶直接被删除。因此如果DROP失败,则无法挽回该表数据
DROP TABLE [IF EXISTS] table_name [PURGE];
truncate table
从表中删除所有行
可以简单理解为清空表的所有数据但是保留表的元数据结构
如果HDFS启用了垃圾桶,数据将被丢进垃圾桶,否则将被删除
TRUNCATE [TABLE] table_name;
alter table
-- 1.更改表名
ALTER TABLE table_name RENAME TO new_table_name;
-- 2.更改表属性
ALTER TABLE table_name SET TBLPROPERTIES (property_name = property_value, ...);
-- 更改表注释
ALTER TABLE student SET TBLPROPERTIES ('comment' = "new comment for student table");
-- 3.更改SerDE属性
ALTER TABLE table_name SET SERDE serde_class_name [WITH SERDEPROPERTIES (property_name = property_value, ...)];
ALTER TABLE table_name [PARTITION partition_spec] SET SERDEPROPERTIES serde_properties;
ALTER TABLE table_name SET SERDEPROPERTIES ('field.delim'=',');
-- 移出SerDe属性
ALTER TABLE table_name [PARTITION partition_spec] UNSET SERDEPROPERTIES (property_name, ...);
-- 4.更改表的文件存储格式 该操作仅更改表元数据,校友数据的人格转换都必须在Hive之外进行
-- 5.更改表的存储位置路径
ALTER TABLE table_name SET LOCATION "new location";
-- 6.更改列名称/类型/位置/注释
CREATE TABLE test_change (a int, b int, c int);
ALTER TABLE test_change CHANGE a a1 INT;
ALTER TABLE test_change CHANGE a1 a2 STRING AFTER b;
ALTER TABLE test_change CHANGE c c1 INT FIRST;
ALTER TABLE test_change CHANGE a1 a1 INT COMMENT 'this is column a1';
-- 7.添加/替换列
-- 使用 ADD COLUMNS,可以将新列添加到现有列的末尾但在分区列之前
-- REPLACE COLUMNS,将删除所有现有列,并添加新的列集
ALTER table_name ADD|REPLACE COLUMNS (col_name data_type,...);
10.add partition(分区) DDL操作
- ADD PARTITION会更改表元数据,但不会加载数据。如果分区位置中不存在数据,查询时将不会返回结果
- 因此需要保证增加的分区位置路径下,数据已经存在,或者增加完粪污之后导入分区数据。
-- 1.增加分区
ALTER TABLE table_name ADD PARTITION (df='20170101') location '/user/hadoop/warehouse/table_name/dt=20170101'
-- 一次添加一个分区
ALTER TABLE table_name ADD PARTITION (dt='2008-08-08',county='us') location '/path/to/us/part080808' PARTITION (df='2008-08-09', country='us') location '/path/to/us/part080809';
-- 一次添加多个分区
rename partition
-- 2.重命名分区
ALTER TABLE table_name PARTITION partition_spec RENAME TO PARTITION partition_spec;
ALTER TABLE table_name PARTITION (dt='2008-08-09') RENAME TO PARTITION (dt='20080809')
delete partition
删除表的分区,将删除该分区的数据和元数据
-- 3.删除分区
ALTER TABLE table_name DROP [IF EXISTS] PARTITION (dt='2008-08-08', country='us');
ALTER TABLE table_name DROP [IF EXISTS] PARTITION (dt='2008-08-08', country='us') PURGE; -- 直接删除数据 不进垃圾桶
alter partition
-- 5.修改分区
-- 更改分区文件存储格式
ALTER TABLE table_name PARTITION (dt='2008-08-09') SET FILEFORMAT file_format;
-- 更改分区位置
ALTER TABLE table_name PARTITION (df='2008-08-09') SET LOCATION "new location";
MSCK partition
MSCK是metastore check的缩写,表示元数据检查操作,可用于元数据修复
- MSCK 默认行为ADD PARTITIONS,它把HDFS上存在但元存储中不存在的所有分区添加到metastore
- DROP PARTITIONS选项将从已经从HDFS中删除的metastore中删除分区信息
- SYNC PARTITIONS选项等效于调用ADD和DROP PARTITIONS
- 如果存在大量未跟踪的分区,则可以批量运行MSCK PEPAIR TABLE,以避免OOME(内存不足错误)
-- 分区修复
MSCK [PEPAIR] TABLE table_name [ADD/DROP/SYNC PARTITIONS];
11.Hive show 语法
-- 1.显示所有数据库 SCHEMAS和DATABASES的用法 功能一样
show database;
show schemas;
-- 2.显示当前数据库所有表/视图/物化视图/分区/索引
show tables;
SHOW TABLES [IN database_name]; -- 指定某个数据库
-- 3.显示当前数据库下所有视图
show views;
show views 'test_*';
show views from test1;
SHOW VIEWS [IN/FROM database_name];
-- 4.显示当前数据库下所有物化视图
SHOW MATERIALIZED VIEW [IN/FROM database_name];
-- 5.显示分区信息,分区按字母顺序列出,不是分区表执行该语句会报错
show partitions table_name;
-- 6.显示表/分区的扩展信息
SHOW TABLE EXTENDED [IN|FROM database_name] LIKE table_name;
show table extended like student;
-- 7.显示表的属性信息
SHOW TBLPROPERTIES table_name;
show tblproperties student;
-- 8.显示表、视图的创建语句
SHOW CREATE TABLE ([db_name.]table_name|view_name)
show create table student;
-- 9.显示表的所有列,包括分区列
SHOW COLUMNS (FORM|IN) table_name [(FROM|IN) db_name];
show columns in student;
-- 10.显示当前支持的所有自定义和内置的函数
show functions;
-- 11.Describe desc
-- 查询表信息
desc extended table_name;
-- 查看表信息(格式化美观)
desc formatted table_name;
-- 查看数据库相关信息
describe database database_name;