HiveQL-DML总览

一、LOAD

Hive在将数据加载到表中时不进行任何转换。加载操作目前是纯拷贝/移动操作,将数据文件移动到与配置单元表相对应的位置。

语法:

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

示例:

建表

create table test.user_msg(id string,telno string,visit_url string,status string,visit_time int,visit_num int)
partitioned by (dt string)
row format delimited
fields terminated by ','
stored as textfile ;

制作数据 vi test_user_msg.txt

1,187xxxx6398,baidu.com,200,365,46
2,156xxxx6398,qq.com,200,485,95
3,136xxxx6398,mp.csdn.net,200,9659,184
4,177xxxx6398,cwiki.apache.org,200,112,6
5,166xxxx6398,www.antlr.org,200,30,2
6,185xxxx6398,pan.baidu.com,200,26815,849
7,188xxxx6398,kuaishou.cn,200,695811,9154
8,190xxxx6398,www.cloudera.com,200,75,3
9,144xxxx6398,douyin.com,200,1568492,1026
9,134xxxx6398,weixin.qq.com,200,6941611,2984

执行:

load data local inpath '/root/temp/test_user_msg.txt' into table test.user_msg partition(dt='20240415');
select * from test.user_msg;

Hive3.0之前的加载操作是纯粹的复制/移动操作,将数据文件移动到与配置单元表相对应的位置。

filepath 可以是以下三种情况(filepath可以指一个文件也可以指一个目录,Hive3.0以后可以包含子目录)

        1、相对路径,例如temp/test_user_msg.txt

        2、绝对路径,如/root/temp

        3、HDFS路径:hdfs://namenode:9000/user/hive/temp/test_user_msg.txt

要加载到的目标可以是表或分区

local 表示选择本地文件或目录进行加载数据

如果没有指定local,Hive将使用filepath的完整URI(默认使用使用hadoop配置变量fs.default.name中指定Namenode URI的scheme和authority)如果路径不是绝对路径,Hive将自动添加/user/<username>对其进行解释

overwrite 表示目标表(或分区)的内容将被删除,并由filepath引用的文件替换;否则,filepath引用的文件将被添加到表中

Hive3.0以后版本支持额外的 load 操作,因为Hive在内部将 load 重写为 insert as select。

        1、若表有分区,而load命令并没有分区,则加载将转换为INSERT AS SELECT,并假设最后一组列是分区列

        2、如果表为分桶表,要看Hive当前是否是严格模式

                a、如果是,启动INSERT AS SELECT作业

                b、如果不是,如果文件名符合命名约定(如果文件属于bucket 0,则应命名为000000_0或000000_0_copy_1,或者如果属于bucket 2,则名称应类似于000002_0或000002_0_copy_3等),则它将是纯复制/移动操作,否则它将启动INSERT AS SELECT作业

inputformat 可以是任何Hive输入格式,例如文本、ORC等 (区分大小写)

serde 可以是相关联的Hive serde (区分大小写)

二、INSERT

1、将数据从查询插入表

语法1:

insert overwrite table tablename1 [partition (partcol1=val1, partcol2=val2 ...) [if not exists]] select_statement1 from from_statement;

 insert overwrite将覆盖表或分区中的任何现有数据除非为分区提供了if not exists

自hive2.3.0起,如果表具有tblproperties(“auto.pruge”=“true”),则在进行插入时不会将表的先前数据移动到垃圾桶(如果配置了Trash)。此功能仅适用于托管表。当“auto.purge”属性未设置或设置为false时,此功能将关闭。

insert overwrite table test.user_msg_2 partition(dt='20240417') select id,telno,visit_url,status,visit_time,visit_num from test.user_msg where dt = '20240415' ;

语法2:

insert into table tablename1 [partition (partcol1=val1, partcol2=val2 ...)] select_statement1 from from_statement;

insert into将追加到表或分区,保持现有数据的完整性

从Hive 0.13.0开始,可以通过使用 TBLPROPERTIES ("immutable"="true") 默认为false 将表设置为不可变表,如果不可变表已经存在任何数据,则不允许将insert into行为插入其中,如果不可变表为空,则insert into仍然有效,不可变表对insert overwrite无效

不可变表可以防止意外更新,第一次插入不可变表成功,后续连续插入失败,这样表中就只有一组数据,而不是静默地成功插入表中的多个数据副本

insert into table test.user_msg_2 partition(dt='20240417') select id,telno,visit_url,status,visit_time,visit_num from test.user_msg where dt = '20240415' ;

 语法3:多个插入

from from_statement
insert overwrite table tablename1 [partition (partcol1=val1, partcol2=val2 ...) [if not exists]] select_statement1
[insert overwrite table tablename2 [partition ... [if not exists]] select_statement2]
[insert into table tablename2 [partition ...] select_statement2] ...;

 可以在同一查询中指定多个插入子句(也称为多表插入)。

每个select语句的输出都被写入所选的表(或分区)

from test.user_msg
insert overwrite table test.user_msg_2 partition(dt='20240417') select id,telno,visit_url,status,visit_time,visit_num
insert into table test.user_msg_3 partition(dt='20240417') select id,telno,visit_url,status,visit_time,visit_num ;

语法4:动态分区插入

insert overwrite table tablename partition (partcol1[=val1], partcol2[=val2] ...) select_statement from from_statement;
insert into table tablename partition (partcol1[=val1], partcol2[=val2] ...) select_statement from from_statement;

在动态分区插入中,用户可以给出部分分区规范,比如:只需在partition子句中指定分区列名的列表。列值是可选的。

如果给定了分区列值,我们将其称为静态分区,否则它就是动态分区。

每个动态分区列都有来自select语句的相应输入列。这意味着动态分区的创建是由输入列的值决定的。动态分区列必须在select语句中的列中最后指定,并且指定顺序与它们在partition()子句中的显示顺序相同

从Hive3.0.0起,动态分区列也可以不指定,Hive会自动生成分区规范。

在Hive0.9.0之前,默认情况下禁用动态分区插入,目前默认情况下启用动态分区插入。

以下是动态分区插入的相关配置属性:

配置属性默认值备注
hive.exec.max.dynamic.partitions.pernode100

允许在每个mr节点中创建的最大动态分区数

hive.exec.max.dynamic.partitions1000允许创建的动态分区的最大总数
hive.exec.max.created.files100000

MapReduce作业中所有mr创建的HDFS文件的最大数量

hive.exec.dynamic.partition.modestrict严格模式,该模式下必须至少指定一个静态分区
hive.exec.dynamic.partitiontrue启用动态分区
hive.error.on.empty.partitionfalse

如果动态分区插入空结果,是否引发异常

set hive.exec.dynamic.partition.mode=nonstrict;
insert into table test.user_msg_2 partition(dt) select id,telno,visit_url,status,visit_time,visit_num,dt from test.user_msg where dt = '20240415' ;

2、将数据从查询写入文件系统

语法1:

insert overwrite [local] directory directory1
  [row format row_format] [stored as file_format] 
  select ... from ...

Hive会默认将数据放到HDFS上,且可以从 MR 作业中并行写入HDFS

如果使用  local 关键字,Hive将把数据写入本地文件系统上

写入文件系统的数据被序列化为文本,列用^A(\001)分隔,行用换行符分隔。如果任何列不是基元类型,那么这些列将被序列化为JSON格式

insert overwrite  directory '/data/test/user_msg' select * from test.user_msg ;
dfs -du -h /data/test/user_msg ;

 

语法2:多个插入

from from_statement
insert overwrite [local] directory directory1 select_statement1
[insert overwrite [local] directory directory2 select_statement2] ...

from test.user_msg
insert overwrite  directory '/data/test/user_msg_2' select * 
insert overwrite local directory '/root/temp/user_msg_local' select * ;

语法3:格式化

: delimited [fields terminated by char [escaped by char]] [collection items terminated by char]
        [map keys terminated by char] [lines terminated by char]
        [null defined as char] 

insert overwrite directory '/data/test/user_msg'
row format delimited
fields terminated by '|'
select * from test.user_msg;
dfs -cat /data/test/user_msg/* ;

3、将值从sql插入表

语法:

insert into table tablename [partition (partcol1[=val1], partcol2[=val2] ...)] values values_row [, values_row ...]

values 子句中列出的每一行都插入到表中。

必须为表中的每一列提供值。目前还不支持仅在某些列中插入值的标准SQL语法。但可以将列值设为null。

如果插入的表支持ACID,并且正在使用支持ACID的事务管理器,则此操作将在成功完成后自动提交

Hive不支持复杂类型(数组、映射、结构、联合)的数据通过这种方式插入

insert into table test.user_msg partition (dt = '20240420')
  values ('100', '187xxxx3695', 'sports.com','200',653,74), ('101', '156xxxx3689', 'mail.com','200',94569,368);
select * from test.user_msg where dt = '20240420' ;

三、UPDATE

只能对支持ACID的表执行更新

语法:

update tablename set column = value [, column = value ...] [where expression]

无法更新分区列和分桶列

Hive 0.14中,成功完成,更改将自动提交。

更新时,矢量化将自动关闭,更新后的表仍然可以使用矢量化进行查询(在Hive中,矢量化是一种优化技术,它通过减少I/O操作和CPU计算来提高查询性能)

建议您在进行更新时将hive.optimity.sort.dynamic.partition=false设置为false,因为这会产生更高效的执行计划

 对Hive表启用 ACID(Atomicity, Consistency, Isolation, Durability)功能并将且转变为事务表

#创建事务表
create table test.user_msg_tran (id string,telno string,visit_url string,status string,visit_time int,visit_num int)
partitioned by (dt string)
clustered by (status) into 5 buckets
 stored as orc
tblproperties ("transactional"="true",
  "compactor.mapreduce.map.memory.mb"="2048",
  "compactorthreshold.hive.compactor.delta.num.threshold"="4", 
  "compactorthreshold.hive.compactor.delta.pct.threshold"="0.5" 
);
#环境参数设置
set hive.support.concurrency=true;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
#插入数据
insert into table test.user_msg_tran partition (dt = '20240420')
 values ('100', '187xxxx3695', 'sports.com','200',653,74), ('101', '156xxxx3689', 'mail.com','200',94569,368);
#查询
select id,telno,visit_url,status,visit_time,visit_num from test.user_msg_tran where dt='20240420' ;
修改
update test.user_msg_tran set visit_url = 'www.baidu.com' where dt='20240420' and id = '100' ;
#查询
select id,telno,visit_url,status,visit_time,visit_num from test.user_msg_tran where dt='20240420' ;

 

四、DELETE

只能对支持ACID的表执行删除

语法:

delete from tablename [where expression]

Hive 0.14中,成功完成,更改将自动提交。

删除时,矢量化将自动关闭,删除后的表仍然可以使用矢量化进行查询(在Hive中,矢量化是一种优化技术,它通过减少I/O操作和CPU计算来提高查询性能)

建议您在执行删除操作时将hive.optimity.sort.dynamic.partition=false设置为false,因为这会产生更高效的执行计划。

delete from test.user_msg_tran where id = '101' ;

五、MERGE

只能对支持ACID的表执行合并

语法:

merge into <target table> as t using <source expression/table> as s
on <boolean expression1>
when matched [and <boolean expression2>] then update set <set clause list>
when matched [and <boolean expression3>] then delete
when not matched [and <boolean expression4>] then insert values<value list>

合并允许根据与源表的联接结果对目标表执行操作

从Hive2.2以后才提供该语法,成功完成此操作后,更改将自动提交。

如果ON子句使得源中有1行以上与目标中的行匹配,则 标准sql 要求引发错误。会导致性能下降,可以通过设置参数 hive.merge.cardinatity.check=false禁用检查,但如果禁用了检查,会导致数据质量问题。

set hive.exec.dynamic.partition.mode=nonstrict;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;

create table test.user_msg_tran_merge_source(id string,telno string,visit_url string,status string,visit_time int,visit_num int)
partitioned by (dt string)
stored as orc;

insert into table test.user_msg_tran_merge_source partition (dt = '20240420')
 values ('666', '188xxxx4562', 'blog.csdn.net','200',632594,3894), ('888', '136xxxx5972', 'fanyi.youdao.com','200',7864,945), ('100', '188xxxx4562', 'test_merge.com','200',11111,121);

merge into test.user_msg_tran as t using test.user_msg_tran_merge_source as s
on t.id = s.id and t.status = s.status
when matched and (t.visit_url != s.visit_url and s.visit_url is not null) then update set visit_url = s.visit_url
when matched and s.visit_url is null then delete
when not matched then insert values (s.id,s.telno,'visit_url',s.status,s.visit_time,s.visit_num);
  • 27
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值