1.Load加载数据
- 不管路径在哪里,只有把数据文件移动到对应的表文件夹下面,Hive才能映射解析成功;
- 最原始暴力的方式就是使用
hadoop fs -put/-mv
等方式直接将数据移动到表文件夹下;但Hive推荐使用Load指令 - 将数据文件移动到Hive对应的位置
- 纯粹的移动、纯粹的复制
1.1Load语法
1.1.1 filepath
1.1.2 local
我们把指令打到Hive的服务器上,Hive执行携带LOCAL的指令,filepath就是从Hive的服务器找,而不是从自己电脑本地找
1.1.3overwrite
如果使用了OVERWRITE关键字,则目标表(或者分区)中的已经存在的数据会被删除,然后再将file写入
例如:如果Android和IOS两个日志表都是按day分区,中间表也按day分区,那么需要再针对source进行静态分区,防止二者互相overwrite
1.1.4into
into就是追加,但可能出现“写入中断导致的数据重复”等问题。因此一般都是用overwrite
1.2 Hive3.0新特性
主要是对LOAD加载时,把多余的字段用于匹配分区
本来加载的时候没有指定分区,语句是报错的,但是文件的格式符合表的结构,前两个是col1,col2,最后一个是分区字段col3,则此时会将load语句转换成为insert as select语句。
2.insert加载数据
- 在RDBMS(关系数据库管理系统)中,insert + values的插入数据方式很常用,也很快。但是在Hive中哪怕是只插入一条数据,底层也是走MapReduce,这也是数仓只能用作OLAP(联机分析处理),不能用作OLTP(在线/联机事务处理)的主要原因
- insert操作只看字段按顺序映射,因此在执行insert + select的时候必须把字段顺序确定好,多余的字段也是按顺序进行分区
静态insert:
insert into table da_luna.tmp_withtest partition(day_partition = '2022-11-13') values(123,'2022-11-12')
2.1 官方推荐的数据加载方式load及其优缺点
官方推荐:把数据清洗为结构化文件,然后通过load加载到表中
- 优点:效率高
- 缺点:但这样无法处理以下场景(只需要部分字段、需要对数据进行处理后再插入)
2.2 多重插入multiple insert
- 翻译为多次插入,多重插入,其核心功能是:一次扫描,多次插入。
- 语法目的就是减少扫描的次数,在一次扫描中。完成多次insert操作。
注意区分与“with中间表”的区别
2.3动态分区插入
上面的用load指令加载数据永远都是只能把partition写死(静态分区)
而通过insert + select ,每行的最后多余的字段就 按顺序 动态映射分区
2.3.1 set参数
- 允许动态分区:
set hive.exec.dynamic.partition=true;
- 全字段动态分区:
set hive.mapred.mode=nonstrict;
这里可选strict(严格模式,必须指定至少一个静态分区,防止用户意外覆盖所有分区),也可以选择nonstrict允许所有分区都是动态的
2.4导出数据insert directory
- Hive支持 将select查询的结果导出成文件(select的结果是对象,因此在转化为文件时可以重新指定其存储格式等)
- 导出类似于
hadoop fs -put
,并且是一个overwrite操作,因此需要考虑分区情况(指定到分区上的路径)和覆盖的情况
3.事务表(用于支持update和delete,不是insert)
- 事务表是通过增量表delta+事务id 实现ACID的
- 只有建表时指定了属性参数
TBLPROPERTIES ('transactional' = 'true');
的才能在update、delete操作时产生delta表和delete_delta表 - 如果在创建表时不指定为事务表,那么在update、delete操作时直接报错
Error while compiling statement: FAILED: SemanticException [Error 10294]: Attempt to do update or delete using transaction manager that does not support these operations.
3.1事务表的创建
需要设置set
和TBLPROPERTIES
变量
--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实例上运行多少个压缩程序工作线程。
--事务表的创建
CREATE TABLE emp (id int, name string, salary int)
STORED AS ORC TBLPROPERTIES ('transactional' = 'true');
3.2局限性
3.3为何需要事务表
虽然Hive面向分析,HDFS不支持随机修改文件,但总有一些情况需要对某一行数据进行修改,总不可能每次都重写一遍文件吧,如下场景:
- Flume、KafKa之类的流式传输到现有分区,可能产生脏读
- 某些收集的数据不正确or必须修改(局部修正)
3.4实现原理
3.4.1 delta文件与delete_delta文件
3.4.2 Compator合并器
- 小合并:类似合并多个AOF记录
- 大合并:类似Redis4之后将RDB+AOF合并为新的RDB