1,Hive 导出数据有几种方式? 如何导出数据
(1)insert
导出本地:
insert overwrite local directory '本地路径' select * from 表名;
导出到 HDFS:
insert overwrite directory 'hdfs 路径' select * from 表名;
(2)hadoop 命令
- hdfs dfs -get /user/hive/warehouse/student/student/txt /opt/bigdata/data
- (3)Bash shell
- $bin/hive -e "select * from b"
(4)export 导出 hdfs
export table default.student to 'hdfs 路径'
2, 将一个表的数据按照指定的分隔符 (@) 导出一各文件
insert overwrite local directory '本地路径' rom format delimited fields terminated by '@' select * from 表名;
3, 分区和分桶的区别
分区:
是指按照数据表的某列或这某些列分为多个区, 区从形式来讲可以理解为文件夹, 比如我们要收集某个大型网站的日志数据, 一个网站每天的日志数据存在同一张表上, 由于每天回生成大量的数据, 导数数据表的内容过于巨大, 在查询的时候权标扫描耗费的资源非常多. 可以按照日期对数据进行分区, 不同日期的数据存放在不同的分区在, 查询时只要指定分区字段的值就可以直接从该分区进行查找.
分桶:
分桶是相对于分区进行更细粒度的划分, 分桶将整个数据内容按照某列属性 hash 值进行划分, 如果按照 name 属性分为 3 个桶, 就是对 name 属性值进行 hash 值对 3 取模, 按照取模结果对数据进行分桶. 取模结果为 0 的数据记录存放在到一个文件..... 取模为 2 的数据存放在一个文件.
总结:
分区就是在 HDFS 上进行分目录, 分桶就是分文件.
4, 将数据直接上传到分区目录 (hdfs) 上, 让分区表和数据产生骨关联有些方式
方案一: 上传数据后修复
dfs -mkdir -p 分区目录
dfs -put 分区目录
msck repair table 表名
方案二: 上传数据后添加分区
dfs -mkdir -p 分区目录
dfs -put 分区目录
alter table 表名 add partition();
提示:
这里我们如果将分新的分区上传到 hdfs 上, 因为 hive 没有对应的元数据所示是无法查询的, 所以我们要进行表的修复或者新添加分区.
5, 桶表是否可以通过直接 load 将数据导入
不可以, 因为 load 数据的话 hdfs 只会有一个文件无法完成分桶的小效果, 分桶和 mapreduce 分区是一样的道理, 所以我们要借助中间表进行导入数据.
6,Hive 分区是否越多越好
(1)如果有过多的分区, 由于底层是存储在 hdfs 上, HDFS 只用于存储大文件, 而非小文件, 疑问过多的分区会增加 namenode 的负担
(2)hive 会转化为 mapreduce,mapreduce 会转化为多个 task, 过多的小文件的话, 每个文件一个 task, 每个 task 一个 JVM 实例, JVM 的开启会降低系统的效率
7, 什么情况下 Hive 可以避免进行 MapReduce
hive 为了执行效率, 简单的查询, 就是知识 select, 不带 count,sum,group by, 都不走 map/reduce 直接读取 hdfs 目录中的文件进行过滤, 也就是本地模式.
(1)直接查询数据不会进行 MapReduce
select * from employee;
(2)查询语句中的过滤条件只是区分字段的情况下不会进行 MapReduce
select * from order_partition where month = '2019-03'
(3)设置属性 set.hive.exec.model.local.auto = true;hive 还是会尝试使用本地模式
8,order by,sort by,distribute by ,cluster by 区别
(1)order by 会对给定的数据进行全局排序不管来多少数据, 都启动一个 reducer 来处理
(2)sort by 是局部排序, sort by 会根据数据量的大小启动一个到多个 reducer 工作, 会在进行 reduce 之前为每个 reducer 都产生一个排序文件
(3)distribute by 控制 map 结果的分发, 将具有相同字段的 map 输出分发到 reduce 节点上去.
9, 聚合函数是否可以写在 order by 后面?
不可以
原因是执行顺序, order by 的执行顺序在 select 之后, 所一需要使用重新定义的列名进行排序.
提示: 理解 sql 的执行顺序更加有利于写 sql
- (1)from
- (2)join
- (3)on
- (4)where
- (5)select
- (6)group by
- (7)having
- (8)order by
- (9)limit
10, 级联求和
1, 需求
访客 | 月份 | 访问次数 |
---|---|---|
A | 2015-01 | 5 |
A | 2015-01 | 15 |
B | 2015-01 | 5 |
A | 2015-01 | 8 |
B | 2015-01 | 12 |
A | 2015-01 | 2 |
A | 2015-01 | 12 |
A | 2015-02 | 13 |
B | 2015-02 | 6 |
B | 2015-02 | 5 |
B | 2015-02 | 7 |
2, 需要输出报表
访客 | 月份 | 月访问统计 | 累计访问统计 |
---|---|---|---|
A | 2015-01 | 33 | 33 |
A | 2015-02 | 10 | 43 |
B | 2015-01 | 15 | 15 |
B | 2015-02 | 20 | 35 |
3, 实现步骤
(1)创建一个表
- create table t_access_time(
- username string,
- month string,
- salary int
- )
- row format delimited fields by ','
(2)准备数据
- A,2015-01,5
- A,2015-01,15
- B,2015-01,5
- B,2015-01,25
- A,2015-01,5
- A,2015-02,12
- A,2015-02,5
- B,2015-02,5
- B,2015-02,5
- B,2015-02,5
(3)导入数据
load data local inpath '/opt/bigdata2.7/access.log' into table t_access_time
(4)第一步, 先求个用户月总金额
select username,sum(salary) as salary from t_access_time group by username,month;
(5)第二步, 将月总金额表 自己和自己 join(自 join)
- select A.,B. from
- (select username,month,sum(salary) as salary from t_access_time group by username,month) A
- iner join
- (select username,month,sum(salary) as salary from t_access_time group by username,month) B
- on A.username=B.username
- where B.month<=A.month;
(6)第三步, 从上一步的结果尽心分组查询, 分组的字段是 a.username,a.month, 求月累计值, 将 b.month<=b.month 的所有 b.salary 求和既可.
- select A.username,A.month,max(A.salary) as salary,sum(B.salary) as accumulate
- from
- (select username,month,sum(salary) as salary from t_access_time group by username,month) A
- iner join
- (select username,month,sum(salary) as salary from t_access_time group by username,month) B
- on A.username=B.username
- where B.month<=A.month
- group by A.username,A.month
- order by A.username,A.month;
来源: http://www.bubuko.com/infodetail-3415725.html