Hive简介
Hive基本情况
Hive 是建立在 Hadoop 上的数据仓库基础构架
- 由facebook开源,最初用于解决海量结构化的日志数据统 计问题;
- ETL(Extraction-Transformation-Loading)工具
- 构建在Hadoop之上的数据仓库;
- 数据计算使用MR,数据存储使用HDFS
- 数据库&数据仓库 的区别:
- 概念上
- 数据库:用于管理精细化数据,一般情况下用于存储结果数据,分库分表进行存储
- 数据仓库:存储、查询、分析大规模数据 。更像一个打包的过程,里面存储的数据没有细化区分,粒度较粗
- 用途上:
- 数据库:OLTP,on line Transation Processing 联机事务处理,增删改
- 数据仓库:OLAP,on line analysis Processing 联机事务分析处理,查询,hive不支持删除、修改。 支持插入。
- 使用上:
- 数据库:标准sql, hbase: 非标准sql
- 数据仓库:方言版的sql, HQL
- 模式上:
- 数据库:写模式
- 数据仓库:读模式
- 概念上
- 可以将结构化的数据映射成一张数据库表
- 结构化数据映射成二维表
- 将文本中每一行数据映射为数据库的每一条数据
- 将文本中每一列数据映射为hive的表字段
- 提供HQL 查询功能
- hive query language, 方言版sql
- 底层数据是存储在HDFS上
- hive上建的表仅仅相当于对hdfs上的结构化数据进行映射管理
- hive仅仅是一个管理数据的作用,而不会存储数据
- hive想要管理hdfs上的数据,就要建立一个关联关系,关联hive上的表和hdfs上的数据路径
- 数据是依赖于一个元数据库
- 元数据库采用的是关系型数据库, 真实生产中一般使用mysql为hive的元数据库,hive内置默认的元数据库是 derby
- 元数据: HCalalog
- hive中的表和hdfs的映射关系,以及hive表属性(内部表,外部表,视图)和字段信息
- 元数据一旦修饰,hive的所有映射关系等都没了,就无法使用了
- 可与Pig、Presto等共享
- Hive的是构建在Hadoop之上的数据仓库
- 数据计算使用MR,数据存储使用HDFS
- 通常用于进行离线数据处理(采用MapReduce)
- 可认为是一个HQL—->MR的语言翻译器
Hive优缺点:
优点:
- 简单,容易上手
- 提供了类SQL查询语言HQL
- 为超大数据集设计的计算/扩展能力
- MR作为计算引擎,HDFS作为存储系统
- 统一的元数据管理(HCalalog)
- 可与Pig、Presto等共享
- 简单,容易上手
缺点
不支持 删除 & 修改 delete&update,不支持事务
- 因为是基于HDFS
- hive做的最多的是查询
Hive的HQL表达的能力有限
- 迭代式算法无法表达
- 有些复杂运算用HQL不易表达
Hive效率较低,查询延时高
- Hive自动生成MapReduce作业,通常不够智能
- HQL调优困难,粒度较粗
- 可控性差
Hive与传统关系型数据库(RDBMS)对比
Hive的架构
1) 用户接口
CLI:Command Line Interface,即Shell终端命令行,使用 Hive 命令行与 Hive 进行交互,最常用(学习,调试,生产),包括两种运行方式:
hive命令方式:前提必须在hive安装节点上执行
hiveserver2方式:hive安装节点将hive启动为一个后台进程,客户机进行连接(类似于启动了一个hive服务端)
真实生产中常用!
- 1) 修改配置文件,允许远程连接;
第一:修改 hdfs-site.xml,加入一条配置信息,启用 webhdfs;
第二:修改 core-site.xml,加入两条配置信息,设置 hadoop的代理用户。
- 2) 启动服务进程
- 前台启动:hiveserver2
- 后台启动
- 记录日志:nohup hiveserver2 1>/home/sigeon/hiveserver.log 2>/home/sigeon/hiveserver.err &
0:标准日志输入 1:标准日志输出 2:错误日志输出
如果我没有配置日志的输出路径,日志会生成在当前工作目录,默认的日志名称叫做:
nohup.xxx
- 不记录日志:nohup hiveserver2 1>/dev/null 2>/dev/null &
- [补充:]
- nohup命令:no hang up的缩写,即不挂起,可以在你退出帐户/关闭终端之后继续运行相应的进程。
- 语法:nohup <command> &
- 3) 开启beenline客户端并连接:
- 方法一:
- beenline,开启beenline客户端;
- !connect jdbc:<hive2://master:10000>,回车。然后输入用户名和密码,这个用户名是安装 hadoop 集群的用户名
- 方法二:
- beeline -u jdbc:<hive2://master:10000> -n sigeon
JDBC/ODBC:是 Hive 的基于 JDBC 操作提供的客户端,用户(开发员,运维人员)通过 这连接至 Hive server 服务
Web UI:通过浏览器访问 Hive,基本不会使用
2) 元数据库:保存元数据,一般会选用关系型数据库(如mysql,Hive 和 MySQL 之间通过 MetaStore 服务交互)
3) Thrift服务:Facebook 开发的一个软件框架,可以用来进行可扩展且跨语言的服务的开发, Hive 集成了该服务,能让不同的编程语言调用 Hive 的接口
4) 驱动Driver
- a. 解释器:解释器的作用是将 HiveSQL 语句转换为抽象语法树(AST)
- b. 编译器:编译器是将语法树编译为逻辑执行计划
- c. 优化器:优化器是对逻辑执行计划进行优化
- d. 执行器:执行器是调用底层的运行框架执行逻辑执行计划
Hive的数据组织格式
1)库:database
2) 表
a. 内部表(管理表:managed_table)
b. 外部表(external_table)
内部表和外部表区别:
- 内部表和外部表是两个相对的概念,不可能有一个表同时是内部表又是外部表;
- 内部表删除表的时候会删除原始数据和元数据,而外部表删除表的时候只会删除元数据不会删除原始数据
- 一般情况下存储公共数据的表存放为外部表
- 大多数情况,他们的区别不明显。如果数据的所有处理都在 Hive 中进行,那么倾向于 选择内部表;但是如果 Hive 和其他工具要针对相同的数据集进行处理,外部表更合适。
- 使用外部表访问存储在 HDFS 上的初始数据,然后通过 Hive 转换数据并存到内部表中,使用外部表的场景是针对一个数据集有多个不同的 Schema。
c. 分区表
- 不同于hadoop中的分区,分区表是人为划分的
- hive最终存储海量数据,海量数据查询一定注意避免全表扫描
- 查询的时候为了提升我们的查询性能,出现了分区表
- 将数据按照用户的业务存储到不同的目录下,在进行数据查询时只会对指定分区下的数据进行扫描
一般情况下生产中用日期作为分区字段
d. 分桶表
类似于hadoop中的分区,是由程序决定的,只能指定桶的个数(分区的个数)
根据hash算法将余数不同的输出到不同的文件中
作用:
分区表和分桶表的区别:
- Hive 数据表可以根据某些字段进行分区操作,细化数据管理,可以让部分查询更快。
- 同时表和分区也可以进一步被划分为 Buckets,分桶表的原理和 MapReduce 编程中的 HashPartitioner 的原理类似
- 分区和分桶都是细化数据管理,但是分区表是手动添加区分,由于 Hive 是读模式,所以对添加进分区的数据不做模式校验
- 分桶表中的数据是按照某些分桶字段进行 hash 散列 形成的多个文件,所以数据的准确性也高很多
3)视图:
- hive中的视图仅仅相当于一个sql语句的别名
- 在hive中仅仅存在逻辑视图,不存在物理视图
- 物理视图:讲sql语句的执行结果存在视图中
- 逻辑视图: 仅仅是对查询结果的引用
4)数据存储:
- 原始数据中存在HDFS
- 元数据存在mysql
Hive安装
装hive其实不难,主要是安装mysql,解决mysql的权限问题
MySql安装
RPM 安装MySQl:
检查以前是否装过 MySQL
1
rpm -qa|grep -i mysql
发现有的话就都卸载
1
2rpm -e --nodeps mysql-libs-5.1.73-5.el6_6.x86_64
rpm -e --nodeps ....删除老版本 mysql 的开发头文件和库
1
2rm -rf /usr/lib64/mysql
# 在搜索 my.cnf 文件,有的话就删掉上传mysql 安装包到 Linux中,解压
1
2
3
4
5
6
7
8tar -xvf mysql-5.6.26-1.linux_glibc2.5.x86_64.rpm-bundle.tar
# 解压出来有这些文件
MySQL-devel-5.6.26-1.linux_glibc2.5.x86_64.rpm
MySQL-embedded-5.6.26-1.linux_glibc2.5.x86_64.rpm
MySQL-server-5.6.26-1.linux_glibc2.5.x86_64.rpm
MySQL-shared-5.6.26-1.linux_glibc2.5.x86_64.rpm
MySQL-shared-compat-5.6.26-1.linux_glibc2.5.x86_64.rpm
MySQL-test-5.6.26-1.linux_glibc2.5.x86_64.rpm安装 server & client
1
2
3
4# server
rpm -ivh MySQL-server-5.6.26-1.linux_glibc2.5.x86_64.rpm
# client
rpm -ivh MySQL-client-5.6.26-1.linux_glibc2.5.x86_64.rpm启动Mysql
1
sudo service mysql start
登录Mysql并改密码,等
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66# 初始密码在这个文件中
cat /root/.mysql_sercert
# 登录
mysql -uroot -pxxxxx
# 删除除了`%`之外的其他所有host
use mysql;
select host,user,password from user;
delete from user where host in ('localhost', '127.0.0.1','::1', ...)
# 修改密码
UPDATE user SET Password = PASSWORD('psd') WHERE user = 'root';
# 为`%` 和 `*` 添加远程登录权限
#注意: 前面的 mysql 登录用户名, 123 是登录密码
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'psd' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON *.* TO 'root'@'*' IDENTIFIED BY 'psd' WITH GRANT OPTION;
FLUSH PRIVILEGES;
# 退出登录
exit;
# 此时可以再登录试试
mysql -uroot -ppsd
======================================
# 修改字符集为 utf-8
# 新建一个文件
vi /etc/my.cnf
# 添加以下内容
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
character-set-server=utf8
# 重启mysql
sudo service mysql restart
======================================
# 忘记密码,修改密码的方法
# 停止mysql服务的运行
service mysql stop
# 跳过授权表访问
mysqld_safe --user=mysql --skip-grant-tables --skip-networking &
# 登录mysql
mysql -u root mysql
# 接下来可以修改密码了
##在mysql5.7以下的版本如下:
mysql> UPDATE user SET Password=PASSWORD('newpassword') where USER='root’;
##在mysql5.7版本如下:
update mysql.user set authentication_string=password('newpassword') ;
# 修改完了重启
service mysql restart
======================================
MySql的其它错误
在运行schematool -dbType mysql -initSchema
手动初始化元数据库的时候
报了一个log4j重复加载的问题
- 解决:可以不用理睬
链接mysql 密码过期问题
Your password has expired.
解决:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50mysql -uroot -p123
mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select host,user,password_expired from user;
+-----------+------+------------------+
| host | user | password_expired |
+-----------+------+------------------+
| % | root | N |
| cs1 | root | Y |
| 127.0.0.1 | root | Y |
| ::1 | root | Y |
+-----------+------+------------------+
4 rows in set (0.00 sec)
-------------
mysql> update user set password_expired='N' where host='::1';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> update user set password_expired='N' where host='cs1';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> update user set password_expired='N' where host='127.0.0.1';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
mysql> select host,user,password_expired from user;
+-----------+------+------------------+
| host | user | password_expired |
+-----------+------+------------------+
| % | root | N |
| cs1 | root | N |
| 127.0.0.1 | root | N |
| ::1 | root | N |
+-----------+------+------------------+
4 rows in set (0.00 sec)
mysql> exit
Bye
[ap@cs1]~/apps/hive% sudo service mysql restart
# 再重新初始化就好了
Yum安装 Mysql
因为笔者没装过,所以这部分暂且不表
step2-安装Hive
MySql安装好之后, 安装Hive就很简答了
注意: Hive 是操作 Mysql 的数据库, 一定要记得把 mysql 驱动文件放到 hive 下的 lib 中!!!
启动beeline 前, 要把 hiveserver2开起来, 当然, hdfs, mysql 都要启动起来
1 | # 1.上传到Linux |
登录beeline :bee:
方式1: 直接登录
登录前要开启 RunJar 进程, 也就是 开启hiveserver2
nohup hiveserver2 1>/home/ap/hiveserver.log 2>/home/ap/hiveserver.err &
beeline -u jdbc:hive2://cs2:10000 -n ap
方式2: 输入用户名密码登录
!connect jdbc:hive2://cs2:10000
登录 hive
hive
PS: Linux环境变量失效
1 | # 就是直接把环境变量设置为/bin:/usr/bin,因为常用的命令都在/bin这个文件夹中。 |
Hive – DDL
库的操作
1 | 库的操作 |
表的操作
创建表
建表语法
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] <table_name>
创建内部表;添加EXTERNAL参数会创建外部表(col_name data_type [COMMENT col_comment], ...)
添加字段和字段描述[COMMENT table_comment]
添加表描述[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]
指定分区字段和字段描述,分区字段不能为建表字段![CLUSTERED BY (col_name, col_name, ...)] SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]
- 指定分桶字段,分桶字段必须为建表字段!
- 指定排序字段,此字段也必须为建表字段,指定的是分桶内的排序
- 指定分桶个数(hash后再取模)
[ROW FORMAT row_format]
指定分隔符,row_format 格式:列分隔符:`delimited fields terminated by ‘x'` 行分隔符:`line terminated by ‘x'`
[STORED AS file_format]
指定存储格式textfile:文本格式,默认 rcfile:行列结合格式 parquet:压缩格式
[LOCATION hdfs_path]
指定表在hsfs上的存储路径,不指定的话就按配置的路径存储,如果也没指定就在hive默认的路经/user/hive/warehouse
建表代码
- a. 创建内部表
create table mytable (id int, name string) row format delimited fields terminated by ',' stored as textfile;
- b. 创建外部表
create external table mytable2 (id int, name string) row format delimited fields terminated by ',' location '/user/hive/warehouse/mytable2';
- c. 创建分区表
create table table3(id int, name string) partitioned by(sex string) row format delimited fields terminated by ',' stored as textfile;
- 插入分区数据:
load data local inpath '/root/hivedata/mingxing.txt' overwrite into table mytable3 partition(sex='girl’);
- 查询表分区:
show partitions mytable3
- d. 创建分桶表
create table stu_buck(Sno int,Sname string,Sex string,Sage int,Sdept string) clustered by(Sno) sorted by(Sno DESC) into 4 buckets row format delimited fields terminated by ',’;
- e. 复制表
create [external] table [if not exists] new_table like table_name;
- f. 查询表
create table table_a as select * from teble_b;
查看表
desc <table_name>
:显示表的字段信息desc formatted <table_name>
:格式化显示表的详细信息desc extended <table_name>
:显示表的详细信息
修改表
- 重命名
ALTER TABLE old_name RENAME TO new_name
- 修改属性
ALTER TABLE table_name SET TBLPROPERTIES ('comment' = 'my new students table’);
- 不支持修改表名,和表的数据存储目录
- 增加/修改/替换字段
ALTER TABLE table_name ADD COLUMNS (col_spec [, col_spec ...])
新增的字段位置在所有列后面 ( partition 列前 )ALTER TABLE table_name CHANGE c_name new_c_name new_c_type [FIRST | AFTER c_name]
注意修改字段时,类型只能由小类型转为大类型,不让回报错;(在hive1.2.2中并没有此限制)ALTER TABLE table_name REPLACE COLUMNS (col_spec [, col_spec ...])
REPLACE 表示替换表中所有字段
- 添加/删除分区
- 添加分区:
ALTER TABLE table_name ADD [IF NOT EXISTS] PARTITION (partition_col = col_value1 [ ... ] ) [LOCATION 'location1’]
- 删除分区:
ALTER TABLE table_name DROP [IF EXISTS] PARTITION (partition_col = col_value1 [ ... ] )
- 修改分区路径:
ALTER TABLE student_p PARTITION (part='bb') SET LOCATION '/myhive_bbbbb’;
- [补充:]
- 1、 防止分区被删除:alter table student_p partition (part=’aa’) enable no_drop;
- 2、 防止分区被查询:alter table student_p partition (part=’aa’) enable offline;
enable 和 disable 是反向操作
- 添加分区:
删除表
drop table if exists <table_name>;
清空表
会保留表结构
truncate table table_name;
truncate table table_name partition(city='beijing’);
其他辅助命令
- a. 查看数据库列表
show databases;
show databases like 'my*';
- b. 查看数据表
show tables;
show tables in db_name;
- c. 查看数据表的建表语句
show create table table_name;
- d. 查看 hive 函数列表
show functions;
- e. 查看 hive 表的分区
show partitions table_name;
show partitions table_name partition(city='beijing')
- f. 查看表的详细信息(元数据信息)
desc table_name;
desc extended table_name;
- g. 查看数据库的详细属性信息
desc formatted table_name;
desc database db_name; desc database extended db_name;
- h. 清空数据表
truncate table table_name;
Hive – DML
装载数据
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE table_name [PARTITION (partcol1=val1, partcol2=val2 ...)]
- 注意:
- LOAD 操作只是单纯的 复制(本地文件)或者 移动(hdfs文件,一般是公共数据,需要建立外部表)操作,将数据文件移动到 Hive 表对应的位置
- 如果指定了 LOCAL 就去本地文件系统中查找,否则按 inpath 中的 uri 在 hdfs 上查找
- inpath 子句中的文件路径下,不能再有文件夹
- 如果使用了 OVERWRITE 关键字,则目标表(或者分区)中的内容会被删除,然后再将 filepath 指向的文件/目录中的内容添加到表/分区中。
- 如果目标表(分区)已经有一个文件,并且文件名和 filepath 中的文件名冲突,那么现有的文件会被新文件所替代。???不是自动重命名为xxx_copy_1
插入数据
a. 单条插入
INSERT INTO TABLE table_name VALUES(value1, value2, ...);
b. 单重插入
INSERT INTO TABLE table_name [PARTITION (partcol1=val1, ...)] <select_statement1 FROM from_statement>
c. 多重插入
- FROM from_statement
从基表中按不同的字段查询得到的结果分别插入不同的 hive 表
只会扫描一次基表,提高查询性能 INSERT INTO TABLE table_name1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 [WHERE where_statement]
INSERT INTO TABLE table_name2 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement2 [WHERE where_statement]
- [ … ];
- FROM from_statement
d. 分区插入
分区插入有两种:一种是静态分区,另一种是动态分区。
如果混合使用静态分区和动态分区, 则静态分区必须出现在动态分区之前。
静态分区
- A)、创建静态分区表
- B)、从查询结果中导入数据(单重插入)
记得加载数据前要添加分区,然后指定要加载到那个分区 - C)、查看插入结果
动态分区
静态分区添加数据前需要指定分区,当分区个数不确定的时候就很不方便了,这个时候可以使用动态分区
重要且常用,尤其是按照日期分区时!
A)、创建分区表
B)、参数设置
hive-1.2版本
- set hive.exec.dynamic.partition=true; //动态分区开启状态,默认开启
- set hive.exec.dynamic.partition.mode=nonstrict; //动态分区执行模式,默认"strict",在这种模式 下要求至少有一列分区字段是静态的,这有助于阻止因设计错误导致查询产生大量的分区
- \# 可选设置项
如果这些参数被更改了又想还原,则执行一次 reset 命令即可
- set hive.exec.max.dynamic.partitions.pernode=100; //每个节点生成动态分区最大个数
- set hive.exec.max.dynamic.partitions=1000; //生成动态分区最大个数,如果自动分区数大于这个参数,将会报错
- set hive.exec.max.created.files=100000; //一个任务最多可以创建的文件数目
- set dfs.datanode.max.xcievers=4096; //限定一次最多打开的文件数 set
- hive.error.on.empty.partition=false; //表示当有空分区产生时,是否抛出异常
- C)、动态数据插入
- 单个分区字段
- insert into table test2 partition (age) select name,address,school,age from students;
- 多个分区字段
多重分区中目录结构是按照分区字段顺序进行划分的
- insert into table student_ptn2 partition(department, age) select id, name, sex, department,age from students;
分区字段都是动态的
- insert into table student_ptn2 partition(city='sa', zipcode) select id, name, sex, age, department, department as zipcode from students;
第一个分区字段时静态的,第二字department字段动态的,重命名为zipcode?
- [注意:]
- 查询语句 select 查询出来的动态分区 age 和 zipcode 必须放在 最后,和分区字段对应,不然结果会出错
- D)、查看插入结果
- select * from student_ptn2 where city='sa' and zipcode='MA';
e. 分桶插入
- A)、创建分桶表
- B)、从查询结果中导入数据
只能使用insert方式 - C)、查看插入结果
- # 几个命令
- set hive.exec.reducers.bytes.per.reducer=
// 设置每个reducer的吞吐量,单位byte,默认256M - set hive.exec.reducers.max=
//reduceTask最多执行个数,默认1009 - set mapreduce.job.reduces=
//设置reducetask实际运行数,默认-1,代表没有设置,即reducetask默认数为1 - set hive.exec.mode.local.auto=true //设置hive本地模式
- set hive.exec.reducers.bytes.per.reducer=
导出数据(了解)
- 单模式导出
INSERT OVERWRITE [LOCAL] DIRECTORY directory1 <select_statement>;
- 多模式导出
FROM from_statement
INSERT OVERWRITE [LOCAL] DIRECTORY directory1 <select_statement1>
[INSERT OVERWRITE [LOCAL] DIRECTORY directory2 <select_statement2>] ...
查询数据
- Hive 中的 SELECT 基础语法和标准 SQL 语法基本一致,支持 WHERE、DISTINCT、GROUP BY、 ORDER BY、HAVING、LIMIT、子查询等;
- 1、
select * from db.table1
虽然可以,但是要尽量避免 select * 这样的全表扫描操作,效率太低又费时 - 2、
select count(distinct uid) from db.table1
- 3、支持 select、union all、join(left、right、full join)、like、where、having、各种聚合函数、 支持 json 解析
- 4、UDF/ UDAF/UDTF
- UDF:User Defined Function,自定义函数,一对一
- UDAF:User Defined Aggregate Function,自定义聚合函数,多对一,如sum(),count()
- UDTF :User Defined Table Function,自定义表函数,一对多,如explode()
- 5、不支持 update 和 delete
- 6、hive 虽然支持 in/exists(老版本是不支持的),但是 hive 推荐使用 semi join 的方式来代替 实现,而且效率更高。
- 半连接
- 左半连接:left semi join,以左表为基表,右表有的,只显示左表相应记录(即一半)
- 右半连接:right semi join,与左半连接相反
- 内连接:inner join,两表中都有的才会连接
- 外连接
- 左外连接:left outer join,坐标为基表,右表有的会关联,右表没有的以null表示;左表没有右表有的不会关联
- 右外连接:right outer join,与左外连接相反
- 全外连接:full outer join,两表合并
- 半连接
- 7、支持 case … when …
- 1、
- 语法结构
SELECT [ALL | DISTINCT] select_ condition, select_ condition, ...
- FROM table_name a
- [JOIN table_other b ON a.id = b.id]
表连接 - [WHERE where_condition]
过滤条件 - [GROUP BY col_list [HAVING condition]]
分组条件 - [CLUSTER BY col_list | [DISTRIBUTE BY col_list] [SORT BY col_list | ORDER BY col_list] [DESC]]
排序条件:
\1. order by:全局排序,默认升序,DESC表示降序。只有一个 reduce task 的结果,比如文
件名是 000000_0,会导致当输入规模较大时,需要较长的计算时间。
\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;
如果分桶字段和排序字段不一样,那么就不能使用 clustered by - [LIMIT number]
显示结果的前几个记录