本文参考:黑泽君相关博客

本文是我总结日常工作中遇到的坑,结合黑泽君相关博客,选取、补充了部分内容。

上传数据

  1. 上传数据后执行修复 msck 命令
上传数据
hive> dfs -mkdir -p /user/hive/warehouse/dept_partition2/month=201904/day=14;
hive> dfs -put /opt/module/datas/dept.txt /user/hive/warehouse/dept_partition2/month=201904/day=14; 查询数据(查询不到刚上传的数据)
hive> select * from dept_partition2 where month='201904' and day='14';
OK 执行修复命令
hive> msck repair table dept_partition2; 再次查询数据
hive> select * from dept_partition2 where month='201904' and day='14';
OK
dept_partition2.deptno dept_partition2.dname dept_partition2.loc dept_partition2.month dept_partition2.day
10 ACCOUNTING 1700 201904 14
20 RESEARCH 1800 201904 14
30 SALES 1900 201904 14
40 OPERATIONS 1700 201904 14 注:数据如果一开始就放到指定路径下,再通过load data 命令好像会失败,以前遇到过,这里就不测试了,依稀记得有这么个坑
  1. 上传数据后添加分区
上传数据
hive> dfs -mkdir -p /user/hive/warehouse/dept_partition2/month=201905/day=15;
hive> dfs -put /opt/module/datas/dept.txt /user/hive/warehouse/dept_partition2/month=201905/day=15; 执行添加分区
hive> alter table dept_partition2 add partition(month='201905', day='15'); 查询数据
hive> select * from dept_partition2 where month='201905' and day='15';
  1. 创建文件夹后load数据到分区(最常用)
创建目录
hive> dfs -mkdir -p /user/hive/warehouse/dept_partition2/month=201906/day=16; 上传数据
hive> load data local inpath '/opt/module/datas/dept.txt' into table dept_partition2 partition(month='201906',day='16'); 查询数据
hive> select * from dept_partition2 where month='201906' and day='16';

Export导出数据

将查询的结果导出到本地
hive> insert overwrite local directory '/opt/module/datas/export/student'
select * from student;
将查询的结果格式化导出到本地
hive> insert overwrite local directory '/opt/module/datas/export/student1'
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
select * from student;
将查询的结果导出到HDFS上(没有local)
hive> insert overwrite directory '/user/atguigu/student2'
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
select * from student;
Hadoop命令导出到本地
hive> dfs -get /user/hive/warehouse/student/month=201909/000000_0 /opt/module/datas/export/student3.txt;
相当于直接拿文件了
Hive Shell 命令导出
bin/hive -e 'select * from default.student;' > /opt/module/datas/export/student4.txt;
Export导出到HDFS上
hive> export table default.student to '/user/hive/warehouse/export/student';

like和rlike

1)使用LIKE运算选择类似的值;

2)选择条件可以包含字符或数字:

  %代表零个或多个字符(任意个字符)。

  _ 代表一个字符。

3)RLIKE子句是Hive中这个功能的一个扩展,其可以通过Java的正则表达式这个更强大的语言来指定匹配条件。

查找以2开头薪水的员工信息
hive> select * from emp where sal LIKE '2%';
7698 BLAKE MANAGER 7839 1981-5-1 2850.0 NULL 30
7782 CLARK MANAGER 7839 1981-6-9 2450.0 NULL 10
查找第二个数值为2的薪水的员工信息
hive> select * from emp where sal LIKE '_2%';
7521 WARD SALESMAN 7698 1981-2-22 1250.0 500.0 30
7654 MARTIN SALESMAN 7698 1981-9-28 1250.0 1400.0 30
查找薪水中含有2的员工信息
hive> select sal from emp where sal RLIKE '[2]';
1250.0
1250.0
2850.0
2450.0

having语句

having与where不同点

(1)where针对表中的列发挥作用,查询数据;having针对查询结果中的列发挥作用,筛选数据。

(2)where后面不能写分组函数,而having后面可以使用分组函数。

(3)having只用于group by分组统计语句。

求emp表中每个部门的平均工资
hive> select deptno, avg(sal) avg_sal from emp
group by deptno;
10 2916.6666666666665
20 1975.0
30 1566.6666666666667
求emp表中平均薪水大于2000的部门
hive> select deptno, avg(sal) avg_sal from emp
group by deptno
having avg_sal>2000;
10 2916.6666666666665

表的别名

使用别名好处

  (1)使用别名可以简化查询。

  (2)使用表名前缀可以提高执行效率。

如果你自己实现解析器,如果是模糊字段名*,或者不带表名前缀,得有不少预处理动作,判断字段名来源于哪个表。而直接指定时,则不用这些判断,省了不少时间。

数据库的sql解析也不过是程序,可以从实现的角度去想想这类问题。


排序

  • 全局排序(order by)
查询员工信息按工资降序排列
hive> select * from emp order by sal desc; 按照员工薪水的2倍排序(按照别名排序)
hive> select ename, sal*2 twosal from emp order by twosal; 按照部门和工资升序排序
hive> select ename, deptno, sal from emp order by deptno, sal;
  • 每个MapReduce内部排序(sort by)

    sort by:对于每个Reducer内部进行排序,对全局结果集来说不是排序,有多个Reducer。
设置reduce个数
hive> set mapreduce.job.reduces=3; 查看设置reduce个数
hive> set mapreduce.job.reduces;
mapreduce.job.reduces=3 根据部门编号降序查看员工信息
hive> select * from emp sort by deptno desc;
  • 分区排序(distribute by)

distribute by:类似MR中partition,作用是进行分区,需要结合sort by使用。

注意:Hive要求DISTRIBUTE BY语句要写在SORT BY语句之前。

对于distributeby进行测试,一定要分配多reduce进行处理,否则无法看到distribute by的效果。

先按照部门编号分区,再按照员工编号降序排序。
hive> set mapreduce.job.reduces=3;
hive> insert overwrite local directory '/opt/module/datas/distributeby-result'
select * from emp distribute by deptno sort by empno desc; cluster by
当distribute by和sorts by的字段相同时,可以使用cluster by方式。
cluster by除了具有distribute by的功能外还兼具sort by的功能。但是排序只能是升序排序,不能指定排序规则为ASC或者DESC。
1)以下两种写法等价
hive> select * from emp cluster by deptno;

分桶

分区针对的是数据的存储路径(文件夹);分桶针对的是数据文件(文件)。

分区提供一个隔离数据和优化查询的便利方式。

不过,并非所有的数据集都可形成合理的分区,要确定合适的划分大小这个问题。

分桶是将数据集分解成更容易管理的若干部分的另一个技术。适合单个文件很大的情况。

创建分桶表
hive> create table stu_buck(id int, name string)
clustered by(id)
into 4 buckets
row format delimited
fields terminated by '\t'; 查看表结构
hive> desc formatted stu_buck;
Num Buckets: 4 导入数据到分桶表中
hive> load data local inpath '/opt/module/datas/stu_buck.txt' into table stu_buck; 上述操作后 发现并没有分成4个桶
因为桶表不能通过load的方式直接加载数据,只能从另一张表中插入数据。
其实仔细想一下就知道了,load只是把文件移动了一个位置,并没有对文件切割。
先建一个普通的stu表
hive>create table stu(id int, name string)
row format delimited fields terminated by '\t'; 向普通的stu表中导入数据
hive>load data local inpath '/opt/module/datas/stu_buck.txt' into table stu; 清空stu_buck表中数据
hive> truncate table stu_buck; 导入数据到分桶表,通过子查询的方式
hive> insert into table stu_buck select id, name from stu; 上述操作后 发现还是没有分成4个桶
因为有些属性没有设置
hive> set hive.enforce.bucketing=true;
hive> set mapreduce.job.reduces=-1; -- -1表示reduce的个数不是预先设置好了,而是在执行HQL语句的时候自动分析出来需要几个reduce。
hive> truncate table stu_buck;
hive> insert into table stu_buck
select id, name from stu; 上述操作后 表被分成4个桶 修改桶表中bueket数量
hive>alter table stu_buck clustered by(id,name) sorted by(id) into 10 buckets;
完整语法
hive>create table bkt(name string,id string,phone string,card_num bigint,email string,addr string) clustered by(card_num) into 30 buckets;
hive>create table bak(name string,id string,phone string,card_num bigint,email string,addr string) row format delimited fields terminated by ','
hive>load data local inpath '/home/xfvm/bak' into table bak;
hive>insert into table bkt select * from bak;

分桶抽样查询

tablesample是抽样语句,语法:TABLESAMPLE(BUCKET x OUT OF y) 。

X表示从哪个桶中开始抽取,

Y表示相隔多少个桶再次抽取。

hive> select * from bkt tablesample(bucket 2 out of 6 on card_num)
表示从桶中抽取5(30/6)个bucket数据,从第2个bucket开始抽取,抽取的个数由每个桶中的数据量决定。
相隔6个桶再次抽取,因此,依次抽取的桶为:2,8,14,20,26 注意:x的值必须小于等于y的值,否则报错如下:
FAILED: SemanticException [Error 10061]: Numerator should not be bigger than denominator in sample clause for table bkt

最新文章

  1. Struts2 Interceptor学习
  2. Oracle EBS的BIP报表中显示特殊字体
  3. 使用jQuery POST提交数据返回的JSON是字符串不能解析为JSON对象
  4. android AudioRecord 与 AudioTrack的录音加回放的使用
  5. seo小技巧(转载)
  6. jQuery中的$("#my_id").html()中一点要注意的
  7. wireshark 过滤条件汇总
  8. JavaScript中,关于new的那些事
  9. 一文教你迅速解决分布式事务 XA 一致性问题
  10. 20145237 实验一 逆向与Bof基础
  11. React Native在特赞的应用与实践
  12. Java高并发--CPU多级缓存与Java内存模型
  13. 【转载】failed to initialize nvml driver/library version mismatch ubuntu
  14. 使用git将项目上传到github
  15. 基于tensorflow的逻辑分类
  16. poi实现百万级数据导出
  17. ML平台_小米深度学习平台的架构与实践
  18. 【机器学习算法】AdaBoost自适应提升算法
  19. MQTT-SN协议乱翻之实现要点
  20. idea IDE 导入的项目没有显示目录结构

热门文章

  1. Java用集合实现斗地主发牌
  2. SQL Server 获取所有库名
  3. MLE极大似然估计和EM最大期望算法
  4. dcoker安装redis
  5. hdu多校第一场1005(hdu6582)Path 最短路/网络流
  6. JVM内核-原理、诊断与优化学习笔记(三):常用JVM配置参数
  7. WebStorm+Node.js开发环境的配置
  8. spring boot 结合jsp简单示例
  9. Vue项目中同级组件传值的例子
  10. 生产环境Docker部署ELK跨区访问kafka不通问题的解决