Hive数据处理语言DML

1. 将文件加载到列表中

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
 
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)] [INPUTFORMAT 'inputformat' SERDE 'serde'] (3.0 or later)

概要

Hive 3.0之前的加载操作是纯复制/移动操作,可将数据文件移动到与Hive表相对应的位置。

  • 文件路径可以是:
    • 相对路径,例如 project/data1
    • 绝对路径,例如 /user/hive/project/data1
    • 具有scheme和(可选)权限的完整URI,例如 hdfs://namenode:9000/user/hive/project/data1
  • 加载到的目标可以是表或分区。如果表已分区,则必须通过为所有分区列指定值来指定表的特定分区。
  • filepath可以引用一个文件(在这种情况下,Hive会将文件移至表中),也可以是一个目录(在这种情况下,Hive会将目录中的所有文件移至表中)。无论哪种情况,文件路径都会寻址一组文件。
  • 如果指定了关键字LOCAL,则:
    • load命令将在本地文件系统中查找文件路径。如果指定了相对路径,它将相对于用户的当前工作目录进行解释。用户也可以为本地文件指定完整的URI-例如:file:///user/hive/project/data1
    • load命令将尝试将filepath寻址的所有文件复制到目标文件系统。
  • 如果未指定关键字LOCAL ,则Hive将使用filepath的完整URI(如果已指定),或将应用以下规则:
    • 如果未指定方案或权限,则Hive将使用hadoop配置变量fs.default.name中的方案和权限,该变量指定Namenode URI。
    • 如果该路径不是绝对路径,则Hive将相对于 /user/<username>
  • 如果使用OVERWRITE关键字,则目标表(或分区)的内容将被删除,并由filepath引用的文件替换;否则,filepath引用的文件将被添加到表中。

注意事项:

  • 文件路径不能包含子目录(如上所述,Hive 3.0或更高版本除外)
  • 如果未给出关键字LOCAL,则文件路径必须引用与表(或分区)位置相同的文件系统中的文件。

2. 通过查询将数据插入Hive表

//标准语法
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...) [IF NOT EXISTS]] select_statement1 FROM from_statement;
INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement;

//多表插入
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] ...;

//动态分区插入
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;

概要

insert…select 往表中导入数据时,查询的字段个数必须和目标的字段个数相同,不能多,也不能少,否则会报错。但是如果字段的类型不一致的话,则会使用null值填充,不会报错。而使用load data形式往hive表中装载数据时,则不会检查。如果字段多了则会丢弃,少了则会null值填充。同样如果字段类型不一致,也是使用null值填充。

  • ****INSERT OVERWRITE将覆盖表或分区中的任何现有数据
  • INSERT INTO将追加到表或分区,使现有数据保持不变。

介绍一下动态分区插入

往hive分区表中插入数据时,如果需要创建的分区很多,比如以表中某个字段进行分区存储,则需要复制粘贴修改很多sql去执行,效率低。因为hive是批处理系统,所以hive提供了一个动态分区功能,其可以基于查询参数的位置去推断分区的名称,从而建立分区。

举个例子:

1.创建一个单一字段分区表
hive>
   create table dpartition(id int ,name string )
   partitioned by(ct string  );
   
2.往表里装载数据,并且动态建立分区,以city建立动态分区
hive>
 hive.exec.dynamici.partition=true;  #开启动态分区,默认是false
 set hive.exec.dynamic.partition.mode=nonstrict; #开启允许所有分区都是动态的,否则必须要有静态分区才能使用。
 insert overwrite table dpartition
 partition(ct)
 select id ,name,city from  mytest_tmp2_p; 
 
要点:因为dpartition表中只有两个字段,所以当我们查询了三个字段时(多了city字段),所以系统默认以最后一个字段city为分区名,因为分区表的
分区字段默认也是该表中的字段,且依次排在表中字段的最后面。所以分区需要分区的字段只能放在后面,不能把顺序弄错。如果我们查询了四个字段的话,则会报
错,因为该表加上分区字段也才三个。要注意系统是根据查询字段的位置推断分区名的,而不是字段名称。
hive>--查看可知,hive已经完成了以city字段为分区字段,实现了动态分区。
hive (fdm_sor)> show partitions dpartition;
partition
ct=beijing
ct=beijing1

注意事项

  • 多表插入可最大程度地减少所需的数据扫描次数。Hive可以通过只扫描一次输入数据(并应用不同的查询运算符)到输入数据来将数据插入到多个表中。

3. 通过查询将数据写入文件系统

//标准语法
INSERT OVERWRITE [LOCAL] DIRECTORY directory1
  [ROW FORMAT row_format] [STORED AS file_format] (Note: Only available starting with Hive 0.11.0)
  SELECT ... FROM ...
 
多条插入:
FROM from_statement
INSERT OVERWRITE [LOCAL] DIRECTORY directory1 select_statement1
[INSERT OVERWRITE [LOCAL] DIRECTORY directory2 select_statement2] ...

概要

  • 目录可以是完整的URI。如果未指定方案或权限,则Hive将使用hadoop配置变量fs.default.name中的方案和权限,该变量指定Namenode URI。
  • 如果使用LOCAL关键字,则Hive会将数据写入本地文件系统上的目录。
  • 写入文件系统的数据被序列化为文本,列之间用^ A隔开,行之间用换行符隔开。如果任何列都不是原始类型,则将这些列序列化为JSON格式。

注意事项

  • 对目录,本地目录和表(或分区)的INSERT OVERWRITE语句可以在同一查询中一起使用。
  • 对HDFS文件系统目录执行INSERT OVERWRITE语句是从Hive提取大量数据的最佳方法。Hive可以从map-reduce作业中并行写入HDFS目录。
  • 如果指定的路径存在,它将被替换为输出,也就是说原来的文件会被覆盖掉

4. 从SQL向表中插入值

INSERT INTO TABLE tablename [PARTITION (partcol1[=val1], partcol2[=val2] ...)] VALUES values_row [, values_row ...]

举个例子

//创建一张student表
CREATE TABLE students (name VARCHAR(64), age INT, gpa DECIMAL(3, 2))
  CLUSTERED BY (age) INTO 2 BUCKETS STORED AS ORC;
//向student表中插入数据
INSERT INTO TABLE students
  VALUES ('fred flintstone', 35, 1.28), ('barney rubble', 32, 2.32);
  
//创建一张PV表
CREATE TABLE pageviews (userid VARCHAR(64), link STRING, came_from STRING)
  PARTITIONED BY (datestamp STRING) CLUSTERED BY (userid) INTO 256 BUCKETS STORED AS ORC;
  
 //向PV表插入数据
INSERT INTO TABLE pageviews PARTITION (datestamp = '2014-09-23')
  VALUES ('jsmith', 'mail.com', 'sports.com'), ('jdoe', 'mail.com', null);
 
 //动态分区插入(指定分区列)
INSERT INTO TABLE pageviews PARTITION (datestamp)
  VALUES ('tjohnson', 'sports.com', 'finance.com', '2014-09-23'), ('tlee', 'finance.com', null, '2014-09-21');
  
//动态分区插入(不指定分区列)
INSERT INTO TABLE pageviews
  VALUES ('tjohnson', 'sports.com', 'finance.com', '2014-09-23'), ('tlee', 'finance.com', null, '2014-09-21');

概要

  • VALUES子句中列出的每一行都插入到表tablename中。
  • 必须为表中的每一列提供值。尚不支持允许用户仅将值插入某些列的标准SQL语法。为了模仿标准SQL,可以为用户不希望为其分配值的列提供空值。

注意事项

  • Hive不支持复杂类型(array,map,struct,union)的数据类型,因此无法在INSERT INTO … VALUES子句中使用它们。这意味着用户无法使用INSERT INTO … VALUES子句将数据插入到复杂数据类型列中。

5. 更新(UPDATE)

UPDATE tablename SET column = value [, column = value ...] [WHERE expression]

概要

  • 要更新的列必须是已经存在表的列。
  • 仅匹配WHERE子句的行
  • 分区列和桶列无法更新。

6. 删除(DELETE)

DELETE FROM tablename [WHERE expression]

概要

  • 仅匹配WHERE子句的行将被删除。

7. 合并(MERGE)

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>

概要

  • 合并允许基于与源表的联接结果在目标表上执行操作。

注意事项

  • 允许WHEN子句出现;每种类型最多1个:UPDATE / DELETE / INSERT。
  • WHEN NOT MATCHED必须放在最后
  • 如果同时存在UPDATE和DELETE子句,则语句中的第一个子句必须包含[AND <布尔表达式>]

举个例子

//创建库
CREATE DATABASE merge_data;

//创建表merge_data.transactions
CREATE TABLE merge_data.transactions(
 ID int,
 TranValue string,
 last_update_user string)
PARTITIONED BY (tran_date string)
CLUSTERED BY (ID) into 5 buckets 
STORED AS ORC TBLPROPERTIES ('transactional'='true');

//创建表merge_data.merge_source
CREATE TABLE merge_data.merge_source(
 ID int,
 TranValue string,
 tran_date string)
STORED AS ORC;

//向两个表中插入数据
INSERT INTO merge_data.transactions PARTITION (tran_date) VALUES
(1, 'value_01', 'creation', '20170410'),
(2, 'value_02', 'creation', '20170410'),
(3, 'value_03', 'creation', '20170410'),
(4, 'value_04', 'creation', '20170410'),
(5, 'value_05', 'creation', '20170413'),
(6, 'value_06', 'creation', '20170413'),
(7, 'value_07', 'creation', '20170413'),
(8, 'value_08', 'creation', '20170413'),
(9, 'value_09', 'creation', '20170413'),
(10, 'value_10','creation', '20170413');

INSERT INTO merge_data.merge_source VALUES 
(1, 'value_01', '20170410'),
(4, NULL, '20170410'),
(7, 'value_77777', '20170413'),
(8, NULL, '20170413'),
(8, 'value_08', '20170415'),
(11, 'value_11', '20170415');

//合并两个表
MERGE INTO merge_data.transactions AS T 
USING merge_data.merge_source AS S
ON T.ID = S.ID and T.tran_date = S.tran_date
WHEN MATCHED AND (T.TranValue != S.TranValue AND S.TranValue IS NOT NULL) THEN UPDATE SET TranValue = S.TranValue, last_update_user = 'merge_update'
WHEN MATCHED AND S.TranValue IS NULL THEN DELETE
WHEN NOT MATCHED THEN INSERT VALUES (S.ID, S.TranValue, 'merge_insert', S.tran_date);

//查看合并结果
SELECT * FROM merge_data.transactions order by ID;

+----+-----------------------+------------------------------+-----------------------+
| id | transactions.tranvalue| transactions.last_update_user| transactions.tran_date|
+----+-----------------------+------------------------------+-----------------------+
| 1  | value_01              | creation                     | 20170410              |
| 2  | value_02              | creation                     | 20170410              |
| 3  | value_03              | creation                     | 20170410              |
| 5  | value_05              | creation                     | 20170413              |
| 6  | value_06              | creation                     | 20170413              |
| 7  | value_77777           | merge_update                 | 20170413              |
| 8  | value_08              | merge_insert                 | 20170415              |
| 9  | value_09              | creation                     | 20170413              |
| 10 | value_10              | creation                     | 20170413              |
| 11 | value_11              | merge_insert                 | 20170415              |
+----+-----------------------+------------------------------+-----------------------+
发布了17 篇原创文章 · 获赞 0 · 访问量 338

猜你喜欢

转载自blog.csdn.net/qq_37163925/article/details/105700227
今日推荐