美文网首页
Hive开发--Hive--DML(五)

Hive开发--Hive--DML(五)

作者: 无剑_君 | 来源:发表于2019-12-18 14:09 被阅读0次

一、DML 操作

操作手册:https://cwiki.apache.org/confluence/display/Hive/LanguageManual

# 启动服务
hive --service metastore &
hive --service hiveserver2 &
# 使用beeline
beeline -u jdbc:hive2://192.168.71.130:10000

(一) LOAD DATA

1. 默认记录和字段分隔符

最熟悉的应该是以逗号或制表符分隔的文本格式CSV、TSV,当然在Hive中,这些文本格式都是被支持的。
那么Hive中还会支持其他什么控制字符的文本格式呢?
默认:
\n 换行符是可以支持的,因为每一行都可以被认为是一条记录
^A(Ctrl+A) 分隔字段,在 CREATE TABLE 语句中可以使用八进制编码(\001)表示
^B 分隔 ARRAY 、MAP或者 STRUCT 中的元素,键值对之间的分隔,使用八进制编码(\002)表示
^C 用于 MAP 中键和值之间的分隔,使用八进制编码(\003)表示

2. 加载复合数据类型

1)数组

创建数据库表,以array作为数据类型

create table 
person(name string,work_locations   array<string>)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY'\t'
COLLECTION ITEMS TERMINATED BY ',';

数据

biansutao    beijing,shanghai,tianjin,hangzhou
linan changchu,chengdu,wuhan

入库数据

LOAD DATA LOCAL INPATH '/root/person.txt' OVERWRITE INTO TABLE person;

查询

hive>select * from person;
hive>select name from  person;
hive>select work_locations[0] from person;
hive>select work_locations from person;  
hive>select work_locations[3] from person;
hive>select work_locations[4] from person;

2)Map

创建数据库表

create table
score(name string, score map<string,int>)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY'\t'
COLLECTION ITEMS TERMINATED BY','
MAP KEYS TERMINATED BY':';

数据

biansutao   '数学':80,'语文':89,'英语':95
jobs'语文':60,'数学':80,'英语':99

入库数据

LOAD DATA LOCAL INPATH '/home/hadoop/score.txt' OVERWRITE INTO TABLE score;

查询

hive>select * from score;
hive>select name from  score;
hive>select t.score from score t;
hive>select t.score['语文'] from score t;
hive>select t.score['英语'] from score t;

3)Struct

创建数据表

CREATE TABLE
test(id int,course struct<course:string,score:int>)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY'\t'
COLLECTION ITEMS TERMINATED BY ',';

数据

1 english,80
2 math,89
3 chinese,95

入库

LOADDATA LOCALINPATH '/home/hadoop/test.txt'OVERWRITE INTOTABLE test;

查询

hive>select* from test;
hive>select course from test;
hive>select t.course.course from test t;
hive>select t.course.score from test t;

2. 本地导入

将插入下列数据到表中。在/home/user目录中名为sample.txt的文件。

1201    Gpal    45000   Technica lmanager
1202    Manisha 45000    Proof reader
1203    Masthanvali     40000   Technical writer
1204    Kiran   40000   Hr Admin
1205    Kranthi 30000   Op Admin

加载本地文件:

hive> load data local inpath '/root/sample.txt' overwrite into table employee;

3. HDFS导入

如果不加local则为加载HDFS文件。
Hive的数据导入只是复制或移动文件,并不对数据的模式进行检查,对数据模式的检查要等到查询时才进行,这就是Hive采用的“schema on read”加载方式。这种方式可以大大提高加载数据的效率。
要先上传数据到HDFS中。

hive> dfs -put data.txt /hive_input_data  

查看文件:

hive> dfs -ls /;

(二) 插入

1. insert into

Insert into语句,它的作用是在一个表格里面追加数据。
语法:

INSERT INTO TABLE tablename [PARTITION (partcol1[=val1], partcol2[=val2] ...)] VALUES values_row [, values_row ...]
  
Where values_row is:
( value [, value ...] )
where a value is either null or any valid SQL literal

1) 普通记录

创建表:

CREATE TABLE students (name VARCHAR(64), age INT, gpa DECIMAL(3, 2))
  CLUSTERED BY (age) INTO 2 BUCKETS STORED AS ORC;

插入记录:

INSERT INTO TABLE students
  VALUES ('fred flintstone', 35, 1.28), ('barney rubble', 32, 2.32);

2) 分区记录

创建表:

CREATE TABLE pageviews (userid VARCHAR(64), link STRING, came_from STRING)
  PARTITIONED BY (datestamp STRING) CLUSTERED BY (userid) INTO 256 BUCKETS STORED AS ORC;

插入带分区的记录:

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');

2. insert overwrite

1)加载数据

hive> insert into table list1 partition (gender='male') select name, birthday from list where gender='male';
hive> insert into table list1 partition (gender='female') select name, birthday from list where gender='female';

在insert的时候需要注意,如果目标表有分区,那么需要指定当前插入的是哪个分区的数据;
在进行插入的时候,分区字段是不需要在后续的select中的,其会自动存储为partition后的字段指定的值,而后续的select语句也只需要包含其余的字段即可,如这里的select语句只包含了name和birthday字段。

2)导出数据

insert overwrite directory '/user/eg2/' select * from list;

这里overwrite不能省略;
overwrite后可接local关键字,如果有该关键字,那么后面的路径则表示本地路径,否则表示HDFS文件系统上的路径。

3. 多表插入

创建表,intable:
表结构:

eid                     int
ename                   string
salary              decimal(10,2)
desc                    string

表数据:

1       刘帽    10000.12        我是北京人
2       王这    5000.00 我是天津人
3       李想    7000.00 我是河北人

将intable表数据插入到:mutil1与mutil2中。
插入多表记录:

from intable1 
insert overwrite table mutil1 select eid,ename,salary,desc
insert overwrite table mutil2 select eid,ename,salary,desc;
  1. insert导出数据
    HDFS导出
insert overwrite directory '/user/eg2/' select * from list;

本地导出

hive> insert overwrite local directory '/testdata/data' select * from intable1;

这里overwrite不能省略;
overwrite后可接local关键字,如果有该关键字,那么后面的路径则表示本地路径,否则表示HDFS文件系统上的路径。

(三)事务配置

需设置:

set hive.support.concurrency=true;
set hive.enforce.bucketing=true;
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.txn.manager= org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.compactor.initiator.on= true;
set hive.compactor.worker.threads= 1;

修改:

2278行
<property>  
    <name>hive.support.concurrency</name>
    <value>true</value>
</property>
 2882行 
<property>
  <name>hive.txn.manager</name>
 <value>org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager</value>
</property>
为
<property>   
  <name>hive.txn.manager</name>  
  <value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value>
</property>
2966 行
<property>      
  <name>hive.compactor.initiator.on</name>
  <value>true</value>
</property>
2976行
<property>  
    <name>hive.compactor.worker.threads</name>
    <value>1</value>
</property>

1. 创建表

只有ORCFileformat支持AcidOutputFormat,建表时必须指定参数('transactional' = true)
必须添加桶。

hive> create table test(id int ,name string ) clustered by (id) into 2 buckets stored as orc TBLPROPERTIES('transactional'='true');

插入数据:

hive>insert into table test values (1,'row1'),(2,'row2'),(3,'row3'); 

2. 临时设置

# 设置为nonstrict模式:
set hive.exec.dynamic.partition.mode=nonstrict;

# 启用桶:
hive> set hive.enforce.bucketing=true;

(四)更新

必须配置事务

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

示例:
要修改的列不能是桶定义列。

hive> update test set name='abc' where id=2;

(五)合并

语法:

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>

应用于数据清洗。
表1:

CREATE TABLE 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');

# 批量插入
INSERT INTO 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');

表2

CREATE TABLE merge_source(
ID int,
TranValue string,
tran_date string)
STORED AS ORC;

INSERT INTO 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 
transactions AS T 
USING merge_source AS S
ON T.ID = S.ID and T.tran_date = S.tran_date
WHEN NOT MATCHED THEN INSERT VALUES (S.ID, S.TranValue, 'merge_insert', 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;

(六)删除

必须配置事务

delete:用于删除特定行条件,你可以从给定表中删除所有的行.

删除指定记录:

DELETE FROM tablename [WHERE expression]
hive> delete from test where id = 1;

(七)数据导入

导入到新表(也可以是EXTERNAL表)

 hive> IMPORT TABLE employee_imported FROM '/apps/ca/yanh/data'; 

分区表导入

 hive> IMPORT TABLE employee_partitioned_imported FROM '/apps/ca/yanh/data1'; 

二、常见问题:

  1. Attempt to do update or delete on table default.test that does not use an AcidOutputFormat or is not bucketed
    创建表时必须:
    使用orc格式,必须填加桶。
clustered by (id) into 2 buckets stored as orc
  1. Execution failed with exit status 2
    mapred-site.xml
    设置更大的堆大小
<property>         
<name>mapreduce.map.java.opts</name>
<value>-Xmx2014M</value>
 <description>maps中对jvm child设置更大的堆大小</description>
</property>
  1. Container killed on request. Exit code is 143
    问题原因: hadoop运行时使用的虚拟内存不足, hadoop物理内存默认与主机的内存一致,hadoop虚拟内存l默认是hadoop物理内存的2.1倍。
    解决问题:
    修改hadoop物理内存的大小可以在mapred-site.xml设置:
<property>
 <name>mapreduce.map.memory.mb</name>
    <value>2048</value>
 </property>
  <property>   <name>mapreduce.reduce.memory.mb</name>
    <value>2048</value>
 </property>

修改以上配置,完成了合并insert.或修改hadoop虚拟内存与hadoop物理内存的比率值可以在yarn-site.xml设置:

<property>
    <name>yarn.nodemanager.vmem-pmem-ratio</name>
    <value>3</value>
</property>

相关文章

网友评论

      本文标题:Hive开发--Hive--DML(五)

      本文链接:https://www.haomeiwen.com/subject/gphgwctx.html