数据类型

decimal 类型:
decimal(11,2) 代表最多有 11 位数字,其中后 2 位是小数,整数部分是 9 位;如果整数部分超过 9 位,则这个字段就会变成 null;如果小数部分不足 2 位, 则后面用 0 补齐两位,如果小数部分超过两位,则超出部分四舍五入。也可直接写 decimal,后面不指定位数,默认是 decimal(10,0) 整数 10 位,没有小数 map 类型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21zhangsan chinese:90,math:87,english:63,nature:76 lisi chinese:60,math:30,english:78,nature:0 wangwu chinese:89,math:25 create table if not exists map1( name string, score map<string,int>) row format delimited fields terminated by '\t' collection items terminated by ',' map keys terminated by ':'; load data local inpath './data/map1.txt' into table map1; #查询数学⼤于35分的学⽣的英语和⾃然成绩: select m.name,m.score['english'] ,m.score['nature'] from map1 m where m.score['math'] > 35; #查看每个⼈的前两科的成绩总和 select m.name,m.score['chinese']+m.score['math'] from map1 m;
struct 类型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18zhangsan 90,87,63,76 lisi 60,30,78,0 wangwu 89,25,81,9 create table if not exists struct1( name string, score struct<chinese:int,math:int,english:int,natrue:int> ) row format delimited fields terminated by '\t' collection items terminated by ','; 导⼊数据: load data local inpath './data/arr1.txt' into table struct1; select name,score.english,score.chinese from str2 where score.math > 35;
array 类型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25zhangsan 78,89,92,96 lisi 67,75,83,94 王五 23,12 create table if not exists arr1( name string, scores array<string> ) row format delimited fields terminated by '\t' collection items terminated by ','; load data local inpath '/data/arr1.txt' into table arr1; select * from arr1; #结果 +--------+---------------+ |name |scores | +--------+---------------+ |zhangsan|["78,89,92,96"]| |lisi |["67,75,83,94"]| |王五 |["23,12"] | +--------+---------------+
库操作
创建库
1 2 3 4CREATE DATABASE [IF NOT EXISTS] database_name [COMMENT database_comment] [LOCATION hdfs_path] [WITH DBPROPERTIES (property_name=property_value, ...)];
查询库
1 2 3SHOW DATABASES [LIKE 'identifier_with_wildcards']; #注:like通配表达式说明:*表示任意个任意字符,|表示或的关系。
查看数据库信息
1DESCRIBE DATABASE [EXTENDED] db_name;
修改数据库
1 2 3 4 5 6 7 8 9 10 11 12 13用户可以使用alter database命令修改数据库某些信息,其中能够修改的信息包括dbproperties、location、owner user。需要注意的是:修改数据库location,不会改变当前已有表的路径信息,而只是改变后续创建的新表的默认的父目录。 --修改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;
删除数据库
1 2 3 4 5DROP DATABASE [IF EXISTS] database_name [RESTRICT|CASCADE]; RESTRICT:严格模式,若数据库不为空,则会删除失败,默认为该模式。 CASCADE:级联模式,若数据库不为空,则会将库中的表一并删除。
切换当前数据库
1USE database_name;
表操作
表有临时表、外部表、内部表(管理表)、分区表,分桶表

Linux 上传文件到 hdfs 上
hdfs dfs -put student.txt 基于其他表的结构建表
create table teacher2 like teacher;
数据导入导出
导入文件到 hive 表
LOAD DATA [LOCAL] INPATH ‘filepath’ [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 …)];
关键字说明:
1)local:表示从本地加载数据到 Hive 表;否则从 HDFS 加载数据到 Hive 表。
2)overwrite:表示覆盖表中已有数据,否则表示追加。
3)partition:表示上传到指定分区,若目标是分区表,需指定分区。
注意!分桶表不能 load data,可以先 load data 到临时表,再从临时表 insert from 到分桶表导入表到表
1)create table tbname as select * from tbname;
2)insert overwrite table tbname select * from tbname;
数据导出
INSERT (INTO | OVERWRITE) TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 …)] select_statement;
关键字说明:
1)INTO:将结果追加到目标表
2)OVERWRITE:用结果覆盖原有数据
|
|
Export&Import
Export 导出语句可将表的数据和元数据信息一并到处的 HDFS 路径,Import 可将 Export 导出的内容导入 Hive,表的数据和元数据信息都会恢复。Export 和 Import 可用于两个 Hive 实例之间的数据迁移。
EXPORT TABLE tablename TO ’export_target_path’
IMPORT TABLE new_or_original_tablename FROM ‘source_path’ [LOCATION ‘import_target_path’]
ROW FORMAT DELIMITED 参数
[FIELDS TERMINATED BY char]
#列分隔符
[COLLECTION ITEMS TERMINATED BY char]
#map、struct、array 元素间的分隔符
[MAP KEYS TERMINATED BY char]
#map 中 key 和 value 的分隔符
[LINES TERMINATED BY char]
#行分隔符
STORED AS 参数
指定文件格式,常用的文件格式有,textfile(默认值),sequence file,orc file、parquet file 等等。
创建表
临时表
|
|
内部表
|
|
外部表
|
|
内外部表转换
|
|
分区表
|
|
|
|
|
|
|
|
注意!
修改分区只会在元数据中修改,不会同步修改 HDFS 路径,如:
1)原分区路径为: /user/hive/warehouse/test.db/test_table/month=201910 ,分区名: month=‘201910’
2)将分区名修改为:201911 后,分区所在路径不变,依旧 是:/user/hive/warehouse/test.db/test_table/month=201910
如果希望修改分区名后,同步修改 HDFS 的路径,并保证正常可用,需要:
1)在元数据库中: 找到 SDS 表 -> 找到 LOCATION 列 -> 找到对应分区的路径记录进行修改 如将记录的: /user/hive/warehouse/test.db/test_table/month=201910 修改 为: /user/hive/warehouse/test.db/test_table/month=201911
2)在 HDFS 中,同步修改文件夹名
如将文件夹: /user/hive/warehouse/test.db/test_table/month=201910 修改为: /user/hive/warehouse/test.db/test_table/month=201911
分桶表

分桶表不能使用 load data !!!只能 insert .. select ..from
原因:分桶表是要把数据划分成 n 份,划分规则就是基于分桶列的值进行 hash 取模来决定,由于 load data 不会触发 mapreduce,没有计算过程,也就是无法执行 hash 算法,只是简单的移动数据。
Hash 取模算法:
同样的值在 hash 加密后的结果是一致的,不论计算多少次都不会改变。基于这个特征,
**假如规定把表划分成 3 个桶,那么对表的分桶列的字段名进行 hash 计算,产生的值再%3 取模,取模的结果必然是 0 或 1 或 2,基于取模的结果,把取模结果相同的放到同一个桶中。**取模相同的一定在同一文件,同一文件的未必取模都相同。
|
|
查询表
|
|
limit
select * from emp limit 2,3; – 表示从第 2 行开始,向下抓取 3 行
JOIN

由图可知,**左外连接(left join)**就是以左表为主 ,左表多少行,连接的结果表就多少行,**右外连接(right join)**同理。**满外连接(full outer join)**就是左表中有,右表没有的,右表补为 NULL,右表中有,左表没有,左表补为 NULL,类似于求并集。**内连接(inner join)**就是求交集,找两张表都有的
修改表
重命名表
ALTER TABLE table_name RENAME TO new_table_name
增加列
该语句允许用户增加新的列,新增列的位置位于末尾。
ALTER TABLE table_name ADD COLUMNS (col_name data_type [COMMENT col_comment], …)
更新列
该语句允许用户修改指定列的列名、数据类型、注释信息以及在表中的位置。
ALTER TABLE table_name CHANGE COLUMN 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], …)
删除表
DROP TABLE [IF EXISTS] table_name;
清空表
TRUNCATE [TABLE] table_name
注意:truncate 只能清空管理表,不能删除外部表中数据。
特例-update 和 delete
更新和删除的语法比较简单,和关系型数据库一致。需要注意的是这两个操作都只能在支持 ACID 的表,也就是事务表上才能执行。
-- 更新
UPDATE tablename SET column = value [, column = value …] [WHERE expression]
--删除
DELETE FROM tablename [WHERE expression]
需要配置 hive-site.xml,开启事务支持,配置完成后重启 hive。
|
|
视图
Hive 中的视图和 RDBMS 中视图的概念一致,都是一组数据的逻辑表示,本质上就是一条 SELECT 语句 的结果集。视图是纯粹的逻辑对象,没有关联的存储 (Hive 3.0.0 引入的物化视图除外),当查询引用视 图时,Hive 可以将视图的定义与查询结合起来,例如将查询中的过滤器推送到视图中。
在 Hive 中可以使用 CREATE VIEW 创建视图,如果已存在具有相同名称的表或视图,则会抛出异常, 建议使用 IF NOT EXISTS 预做判断。在使用视图时候需要注意以下事项:
- 视图是只读的,不能用作 LOAD / INSERT / ALTER 的目标;
- 在创建视图时候视图就已经固定,对基表的后续更改(如添加列)将不会反映在视图;
- 删除基表并不会删除视图,需要手动删除视图;
- 视图可能包含 ORDER BY 和 LIMIT 子句。如果引用视图的查询语句也包含这类子句,其执行优先 级低于视图对应字句。例如,视图 custom_view 指定 LIMIT 5,查询语句为 select * from custom_view LIMIT 10 ,此时结果最多返回 5 行。
- 创建视图时,如果未提供列名,则将从 SELECT 语句中自动派生列名;
视图增删改
|
|
索引
Hive 在 0.7.0 引入了索引的功能,索引的设计目标是提高表某些列的查询速度。如果没有索引,带有谓 词的查询(如’WHERE table1.column = 10’)会加载整个表或分区并处理所有行。但是如果 column 存在索引,则只需要加载和处理文件的一部分。
索引原理
在指定列上建立索引,会产生一张索引表(表结构如下),里面的字段包括:索引列的值、该值对应的 HDFS 文件路径、该值在文件中的偏移量。在查询涉及到索引字段时,首先到索引表查找索引列值对应 的 HDFS 文件路径及偏移量,这样就避免了全表扫描。

索引增删改
|
|
设置自动使用索引
默认情况下,虽然建立了索引,但是 Hive 在查询时候是不会自动去使用索引的,需要开启相关配置。 开启配置后,涉及到索引列的查询就会使用索引功能去优化查询。
SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
SET hive.optimize.index.filter=true;
SET hive.optimize.index.filter.compact.minsize=0;
索引缺陷
索引表最主要的一个缺陷在于:索引表无法自动 rebuild,这也就意味着如果表中有数据新增或删除, 则必须手动 rebuild,重新执行 MapReduce 作业,生成索引表数据。 同时按照官方文档 的说明,Hive 会从 3.0 开始移除索引功能,主要基于以下两个原因:
具有自动重写的物化视图 (Materialized View) 可以产生与索引相似的效果(Hive 2.3.0 增加了对 物化视图的支持,在 3.0 之后正式引入)。
使用列式存储文件格式(Parquet,ORC)进行存储时,这些格式支持选择性扫描,可以跳过不需 要的文件或块。