大数据技术 Hive的DML操作
沉沙 2018-09-27 来源 : 阅读 1441 评论 0

摘要:本篇教程探讨了大数据技术 Hive的DML操作,希望阅读本篇文章以后大家有所收获,帮助大家对大数据技术的理解更加深入。

本篇教程探讨了大数据技术 Hive的DML操作,希望阅读本篇文章以后大家有所收获,帮助大家对大数据技术的理解更加深入。

<

1. Load
  在将数据加载到表中时,Hive 不会进行任何转换。加载操作是将数据文件移动到与 Hive表对应的位置的纯复制/移动操作。
  语法结构:

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

 
  说明:
  1、 filepath 
    相对路径,例如:project/data1
    绝对路径,例如:/user/hive/project/data1
    完整 URI,例如:hdfs://namenode:9000/user/hive/project/data1
  filepath 可以引用一个文件(在这种情况下,Hive 将文件移动到表中),或者它可以是一个目录(在这种情况下,Hive 将把该目录中的所有文件移动到表中)。
  2、 local
  如果指定了 local, load 命令将在本地文件系统中查找文件路径。
  load 命令会将 filepath 中的文件复制到目标文件系统中。目标文件系统由表的位置属性决定。被复制的数据文件移动到表的数据对应的位置。
  如果没有指定 LOCAL 关键字,如果 filepath 指向的是一个完整的 URI,hive会直接使用这个 URI。 否则:如果没有指定 schema 或者 authority,Hive 会使用在 hadoop 配置文件中定义的schema 和 authority,fs.default.name 指定了Namenode 的 URI。
  3、 overwrite
  如果使用了 overwrite 关键字,则目标表(或者分区)中的内容会被删除,然后再将 filepath 指向的文件/目录中的内容添加到表/分区中。
  如果目标表(分区)已经有一个文件,并且文件名和 filepath 中的文件名冲突,那么现有的文件会被新文件所替代。
2. Insert
  Hive 中 insert 主要是结合 select 查询语句使用,将查询结果插入到表中,例如:
    

insert overwrite table stu_buck select * from student cluster by(Sno);

 
  需要保证查询结果列的数目和需要插入数据表格的列数目一致.
  如果查询出来的数据类型和插入表格对应的列数据类型不一致,将会进行转换,但是不能保证转换一定成功,转换失败的数据将会为 NULL。
  可以将一个表查询出来的数据插入到原表中, 结果相当于自我复制了一份数据。
  
  Multi Inserts  多重插入:  

from source_table
insert overwrite table tablename1 [partition (partcol1=val1,partclo2=val2)]
select_statement1
insert overwrite table tablename2 [partition (partcol1=val1,partclo2=val2)]
select_statement2..

 
 
  Dynamic partition inserts  动态分区插入:

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

 
 
  动态分区是通过位置来对应分区值的。原始表 select 出来的值和输出 partition的值的关系仅仅是通过位置来确定的,和名字并没有关系。
 
  导出表数据
  语法结构

insert overwrite [local] directory directory1 SELECT ... FROM ...
multiple inserts:
FROM from_statement
insert overwrite [local] directory directory1 select_statement1[insert overwrite [local] cirectory directory2 select_statement2] ...

 
 
  数据写入到文件系统时进行文本序列化,且每列用^A 来区分,\n 为换行符。
3. Select
  基本的 Select 操作
  语法结构:

select [all | distinct] select_expr, select_expr, ...
from table_reference
join table_other on expr
[where where_condition]
[group by col_list [having condition]]
[cluster by col_list
| [distribute by col_list] [sort by| order by col_list]
]
[limit number]

 
  说明 :
    1、order by 会对输入做全局排序,因此只有一个 reducer,会导致当输入规模较大时,需要较长的计算时间。
    2、sort by 不是全局排序,其在数据进入 reducer 前完成排序。因此,如果用 sort by 进行排序,并且设置 mapred.reduce.tasks>1,则 sort by 只保证每个 reducer 的输出有序,不保证全局有序。
    3、distribute by(字段)根据指定字段将数据分到不同的 reducer,分发算法是 hash 散列。
    4、Cluster by(字段) 除了具有 Distribute by 的功能外,还会对该字段进行排序。
    如果 distribute 和 sort 的字段是同一个时,此时,cluster by = distribute by + sort by
4. Hive join
  Hive 中除了支持和传统数据库中一样的内关联、左关联、右关联、全关联,还支持 left semi join 和 cross join,但这两种 JOIN 类型也可以用前面的代替。
  Hive  支持等值连接 (a.id = b.id ),  不支持非等值( (a.id>b.id) ) 的连接,因为非等值连接非常难转化到 map/reduce 任务。另外,Hive 支持多 2 个以上表之间的 join。
 
  写 join 查询时,需要注意几个关键点:

  join  时,每次 map/reduce  任务的逻辑

  reducer 会缓存 join 序列中除了最后一个表的所有表的记录,再通过最后一个表将结果序列化到文件系统。这一实现有助于在 reduce 端减少内存的使用量。实践中,应该把最大的那个表写在最后(否则会因为缓存浪费大量内存)。
 

  left , right 和 full outer 关键字用于处理 join 中空记录的情况    


select a.val, b.val from a left outer join b on (a.key=b.key)

 
  对应所有 a 表中的记录都有一条记录输出。输出的结果应该是 a.val, b.val,当a.key=b.key 时,而当 b.key 中找不到等值的 a.key 记录时也会输出:
    a.val, null
  所以 a 表中的所有记录都被保留了;
  “a right outer join b”会保留所有 b 表的记录。
 

  join 发生在 where 子句 之前

  如果你想限制 join 的输出,应该在 where 子句中写过滤条件——或是在 join 子句中写。这里面一个容易混淆的问题是表分区的情况:

select a.val, b.val from a
left outer join b on (a.key=b.key)
where a.ds='2009-07-07' and b.ds='2009-07-07'

 
  这会 join a 表到 b 表(outer join),列出 a.val 和 b.val 的记录。where 从句中可以使用其他列作为过滤条件。但是,如前所述,如果 b 表中找不到对应 a 表的记录,b 表的所有列都会列出null,包括 ds 列。也就是说,join 会过滤 b 表中不能找到匹配 a 表 join key 的所有记录。这样的话,left outer 就使得查询结果与 where 子句无关了。解决的办法是在 outer join 时使用以下语法:

select a.val, b.val from a left outer join b
on (a.key=b.key and
b.ds='2009-07-07' and
a.ds='2009-07-07')

 
  这一查询的结果是预先在 join 阶段过滤过的,所以不会存在上述问题。这一逻辑也可以应用于 right 和 full 类型的 join 中。
 

  join 是不能交换位置的

  无论是 left 还是 right join,都是左连接的。

select a.val1, a.val2, b.val, c.val
from a
join b on (a.key = b.key)
left outer join c on (a.key = c.key)

 
  先 join a 表到 b 表,丢弃掉所有 join key 中不匹配的记录,然后用这一中间结果和 c 表做 join。
 

Insert查询语句
  多重插入:

create table source_table (id int, name string) row format delimited fields terminated by ',';create table test_insert1 (id int) row format delimited fields terminated by ',';create table test_insert2 (name string) row format delimited fields terminated by ',';

 

from source_table                     insert overwrite table test_insert1 select idinsert overwrite table test_insert2select name;


 
  动态分区插入

set hive.exec.dynamic.partition=true;    #是否开启动态分区功能,默认false关闭。set hive.exec.dynamic.partition.mode=nonstrict;   #动态分区的模式,默认strict,表示必须指定至少一个分区为静态分区,nonstrict模式表示允许所有的分区字段都可以使用动态分区。

  需求:    将dynamic_partition_table中的数据按照时间(day),插入到目标表d_p_t的相应分区中。
    原始表:

create table dynamic_partition_table(day string,ip string)row format delimited fields terminated by ","; 
load data local inpath '/root/hivedata/dynamic_partition_table.txt' into table dynamic_partition_table;

 

2015-05-10,ip1
2015-05-10,ip2
2015-06-14,ip3
2015-06-14,ip4
2015-06-15,ip1
2015-06-15,ip2

   目标表:

create table d_p_t(ip string) partitioned by (month string,day string);

  动态插入:

insert overwrite table d_p_t partition (month,day) select ip,substr(day,1,7) as month,day from dynamic_partition_table;


 
  查询结果导出到文件系统
    将查询结果保存到指定的文件目录(可以是本地,也可以是hdfs)

insert overwrite local directory '/root/123456'select * from t_p;

 

insert overwrite directory '/aaa/test'select * from t_p;


 
关于hive中的各种join
  准备数据

1,a2,b3,c4,d7,y8,u
2,bb3,cc7,yy9,pp

 
  建表:

create table a(id int,name string)row format delimited fields terminated by ',';


create table b(id int,name string)row format delimited fields terminated by ',';

  导入数据:

load data local inpath '/root/hivedata/a.txt' into table a;load data local inpath '/root/hivedata/b.txt' into table b;

  实验:    ** inner join

select * from a inner join b on a.id=b.id;
select a.id,a.name from a join b on a.id = b.id;
select a.* from a join b on a.id = b.id;

+-------+---------+-------+---------+--+| a.id  | a.name  | b.id  | b.name  |+-------+---------+-------+---------+--+| 2     | b       | 2     | bb      || 3     | c       | 3     | cc      || 7     | y       | 7     | yy      |+-------+---------+-------+---------+--+
 
 
    **left join

select * from a left join b on a.id=b.id;

+-------+---------+-------+---------+--+| a.id  | a.name  | b.id  | b.name  |+-------+---------+-------+---------+--+| 1     | a       | NULL  | NULL    || 2     | b       | 2     | bb      || 3     | c       | 3     | cc      || 4     | d       | NULL  | NULL    || 7     | y       | 7     | yy      || 8     | u       | NULL  | NULL    |+-------+---------+-------+---------+--+
 
 
    **right join

select * from a right join b on a.id=b.id;
select * from b right join a on b.id=a.id;

+-------+---------+-------+---------+--+| a.id  | a.name  | b.id  | b.name  |+-------+---------+-------+---------+--+| 2     | b       | 2     | bb      || 3     | c       | 3     | cc      || 7     | y       | 7     | yy      || NULL  | NULL    | 9     | pp      |+-------+---------+-------+---------+--+
 
    **full outer join

select * from a full outer join b on a.id=b.id;

+-------+---------+-------+---------+--+| a.id  | a.name  | b.id  | b.name  |+-------+---------+-------+---------+--+| 1     | a       | NULL  | NULL    || 2     | b       | 2     | bb      || 3     | c       | 3     | cc      || 4     | d       | NULL  | NULL    || 7     | y       | 7     | yy      || 8     | u       | NULL  | NULL    || NULL  | NULL    | 9     | pp      |+-------+---------+-------+---------+--+
    **hive中的特别join

select * from a left semi join b on a.id = b.id;

+-------+---------+--+| a.id  | a.name  |+-------+---------+--+| 2     | b       || 3     | c       || 7     | y       |+-------+---------+--+
    相当于

select a.id,a.name from a where a.id in (select b.id from b); 在hive中效率极低
select a.id,a.name from a join b on (a.id = b.id);
select * from a inner join b on a.id=b.id;

    cross join(##慎用)
  返回两个表的笛卡尔积结果,不需要指定关联键。

select a.*,b.* from a cross join b;


 
内置jason函数
select get_json_object(line,'$.movie') as moive,get_json_object(line,'$.rate') as rate from rat_json limit 10;
 

 
transform案例:
    1、先加载rating.json文件到hive的一个原始表 rat_json

create table rat_json(line string) row format delimited;load data local inpath '/root/hivedata/rating.json' into table rat_json;

 
    2、需要解析json数据成四个字段,插入一张新的表 t_rating

drop table if exists t_rating;create table t_rating(movieid string,rate int,timestring string,uid string)row format delimited fields terminated by '\t';

 

insert overwrite table t_ratingselect get_json_object(line,'$.movie') as moive,get_json_object(line,'$.rate') as rate,get_json_object(line,'$.timeStamp') as timestring, get_json_object(line,'$.uid') as uid from rat_json limit 10;

    3、使用transform+python的方式去转换unixtime为weekday      先编辑一个python脚本文件      ########python######代码

vi weekday_mapper.py
#!/bin/python
import sys
import datetime

for line in sys.stdin:
line = line.strip()
movieid, rating, unixtime,userid = line.split('\t')
weekday = datetime.datetime.fromtimestamp(float(unixtime)).isoweekday()
print '\t'.join([movieid, rating, str(weekday),userid])

 
    保存文件    然后,将文件加入hive的classpath:      hive>add FILE /root/hivedata/weekday_mapper.py;

create table u_data_new as select  transform (movieid, rate, timestring,uid)  using 'python weekday_mapper.py'  as (movieid, rate, weekday,uid)from t_rating;


select distinct(weekday) from u_data_new limit 10;


 

desc formatted student;

     

本文由职坐标整理发布,学习更多的大数据技术相关知识,请关注职坐标大技术云计算大技术技术频道!

本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved