Hadoop(三):Hive
本文为学习笔记,对应视频教程来自黑马程序员Hive教程
Hive部署
Mysql 安装
卸载Centos7自带mariadb和mysql
1 | [root@hadoop102 ~]# rpm -qa | grep mariadb |
mysql安装介质下载
官网下载地址:MySQL Product Archives
Product Version | Operating System | OS Version |
---|---|---|
5.7.20 | Linux - Generic | Linux - Generic(glibc 2.12)(x86,64-bit) |
解压安装介质
1 | [root@hadoop102 ~]# cd /opt/software/ |
建立用户和组并创建相关目录
1 | [root@hadoop102 mysql-5.7.20]# groupadd mysql |
配置环境变量
1 | [root@hadoop102 ~]# vim /etc/profile.d/my_env.sh |
安装依赖包
1 | [root@hadoop102 ~]# yum install libaio |
初始化MySQL
初始化创建mysql数据库
1
2
3
4
5
6
7[root@hadoop102 ~]# mysqld --initialize --user=mysql --basedir=/opt/module/mysql-5.7.20/ --datadir=/data/mysql/
2022-05-11T10:50:24.777743Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2022-05-11T10:50:25.027412Z 0 [Warning] InnoDB: New log files created, LSN=45790
2022-05-11T10:50:25.068499Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
2022-05-11T10:50:25.139430Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: 29be3489-d118-11ec-ba45-000c2900c11d.
2022-05-11T10:50:25.140670Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
2022-05-11T10:50:25.141518Z 1 [Note] A temporary password is generated for root@localhost: L2)cw18vE8lw配置mysql.cnf文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16找到配置文件所在位置
[root@hadoop102 ~]# mysql --help | grep cnf
order of preference, my.cnf, $MYSQL_TCP_PORT,
/etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf /opt/module/mysql-5.7.20/my.cnf ~/.my.cnf
编辑配置文件
[root@hadoop102 ~]# vim /etc/my.cnf
[mysqld]
user=mysql
port=3306
basedir=/opt/module/mysql-5.7.20
datadir=/data/mysql
server_id=1
socket=/tmp/mysql.sock
[mysql]
socket=/tmp/mysql.sock配置mysql服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15[root@hadoop102 ~]# vim /usr/lib/systemd/system/mysqld.service
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/opt/module/mysql-5.7.20/bin/mysqld --defaults-file=/etc/my.cnf
LimitNOFILE = 5000启动服务并修改密码
1
2
3
4
5[root@hadoop102 ~]# systemctl start mysqld
[root@hadoop102 ~]# mysql -uroot -p
修改密码
ALTER USER USER() IDENTIFIED BY 'root';授权允许远程访问
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16查看MySQL当前远程访问权限配置
use mysql;
SELECT User,authentication_string,Host FROM user;
+---------------+-------------------------------------------+-----------+
| User | authentication_string | Host |
+---------------+-------------------------------------------+-----------+
| root | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B | localhost |
| mysql.session | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | localhost |
| mysql.sys | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | localhost |
+---------------+-------------------------------------------+-----------+
修改权限,password 为密码
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;
从mysql数据库的grant表中重新加载权限数据
FLUSH PRIVILEGES;
Hive 安装 - 远程模式
Hive安装介质的下载与解压
官网下载地址:Apache Hive Downloads
1 | [root@hadoop102 ~]# cd /opt/software/ |
解决hadoop、hive之间guava版本差异
1 | 删除 hive 中低版本的 jar 包 |
添加mysql jdbc驱动
官网下载地址:MySQL Community Downloads
1 |
|
Connector/J version | JDBC version | MySQL Server version | JRE Required | JDK Required for Compilation | Status |
---|---|---|---|---|---|
5.1 | 3.0, 4.0, 4.1, 4.2 | 5.61, 5.71, 8.01 | JRE 5 or higher1 | JDK 5.0 AND JDK 8.0 or higher2, 3 | General availability |
8.0 | 4.2 | 5.6, 5.7, 8.0 | JRE 8 or higher | JDK 8.0 or higher2 | General availability. Recommended version. |
说明:mysql jdbc 的java驱动只有两个版本,且两个版本都支持mysql-5.7。官方推荐使用8.0版本。
修改hive环境变量文件
1 | [root@hadoop102 ~]# cd /opt/module/apache-hive-3.1.3/conf/ |
新增hive-site.xml
1 | [root@hadoop102 conf]# vim hive-site.xml |
初始化metadata
1 | [root@hadoop102 ~]# cd /opt/module/apache-hive-3.1.3/ |
校验是否成功:MySQL中创建hive数据库并持有74张表
启动 hive
1 | 启动 hadoop 集群,hadoop 集群启动脚本在 Hadoop(一):集群搭建.md |
使用 Hive Beeline Client 连接
Hive服务和客户端关系梳理
HiveServer2通过Metastore服务读写元数据。所以在远程模式下,启动HiveServer2之前必须先首先启动metastore服务。远程模式下,Beeline客户端只能通过HiveServer2服务访问Hive。而Hive Client是通过Metastore服务访问的。具体关系如下:
Hive服务规划部署
hadoop102 | hadoop103 | hadoop104 |
---|---|---|
Metastore Mysql |
HiveServer2 | Beeline Client |
修改配置文件
Metastore需要知道HiveServer2运行位置
1
2
3
4
5
6
7[eitan@hadoop102 ~]$ sudo vim /opt/module/apache-hive-3.1.3/conf/hive-site.xml
修改<value>为hadoop103
<!-- Bind host on which to run the HiveServer2 Thrift interface -->
<property>
<name>hive.server2.thrift.bind.host</name>
<value>hadoop103</value>
</property>HiveServer2需要知道Metastore运行位置
1
2
3
4
5
6
7[eitan@hadoop102 ~]$ sudo vim /opt/module/apache-hive-3.1.3/conf/hive-site.xml
# 确认 metastore 启动在 hadoop102 并监听9083接口
<!-- 远程模式部署metastore服务地址 -->
<property>
<name>hive.metastore.uris</name>
<value>thrift://hadoop102:9083</value>
</property>开启各项服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18启动MySQL
[eitan@hadoop102 ~]$ systemctl start mysqld
启动Hadoop集群
[eitan@hadoop102 ~]$ myhadoop.sh start
启动metastore服务,只需先启动了MySQL就行与Hadoop无关
[eitan@hadoop102 ~]$ /opt/module/apache-hive-3.1.3/bin/hive --service metastore
启动hiveserver2,需要提前启动Hadoop
[eitan@hadoop103 ~]$ /opt/module/apache-hive-3.1.3/bin/hiveserver2
启动beeline,并连接hiveserver2
[eitan@hadoop104 ~]$ /opt/module/apache-hive-3.1.3/bin/beeline
! connect jdbc:hive2://hadoop103:10000
Connecting to jdbc:hive2://hadoop103:10000
Enter username for jdbc:hive2://hadoop103:10000: eitan
Enter password for jdbc:hive2://hadoop103:10000:
Connected to: Apache Hive (version 3.1.3)
Driver: Hive JDBC (version 3.1.3)
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://hadoop103:10000>
编写hive启动停止脚本
1 | [eitan@hadoop102 ~]$ vim bin/myhive.sh |
Hive 的数据定义语言(DDL)
完整建表语法树
蓝色字体是建表语法的关键字,用于指定某些功能。
**[]**中括号的语法表示可选。
**|**表示使用的时候,左右语法二选一。
建表语句中的语法顺序要和上述语法规则保持一致。
Hive数据类型
Hive中的数据类型指的是Hive表中的列字段类型。Hive数据类型整体分为两个类别:原生数据类型(primitive data type)和复杂数据类型(complex data type)。
原生数据类型包括:数值类型、时间类型、字符串类型、杂项数据类型;
复杂数据类型包括:array数组、map映射、struct结构、union联合体。
官方文档链接:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types
Hive读写文件机制
Hive读写文件流程
Hive读取文件机制:首先调用InputFormat(默认TextInputFormat),返回一条一条kv键值对记录(默认是一行对应一条记录)。然后调用SerDe(默认LazySimpleSerDe)的Deserializer,将一条记录中的value根据分隔符切分为各个字段。
Hive写文件机制:将Row写入文件时,首先调用SerDe(默认LazySimpleSerDe)的Serializer将对象转换成字节序列,然后调用OutputFormat将数据写入HDFS文件中。
SerDe概念及相关语法
SerDe是Serializer、Deserializer的简称,目的是用于序列化和反序列化。序列化是对象转化为字节码的过程;而反序列化是字节码转换为对象的过程。
在Hive的建表语句中,和SerDe相关的语法为:
其中ROW FORMAT是语法关键字,DELIMITED和SERDE二选其一。
如果使用DELIMITED表示使用默认的LazySimpleSerDe类来处理数据。如果数据文件格式比较特殊可以使用ROW FORMAT SERDE serde_name指定其他的Serde类来处理数据,甚至支持用户自定义SerDe类。
LazySimpleSerDe是Hive默认的序列化类,包含4种子语法,分别用于指定字段之间、集合元素之间、map映射 kv之间、换行的分隔符号:
默认分隔符为 ‘\001’
二进制 十进制 十六进制 缩写 0000 0001 1 01 SOH
Hive数据存储路径
默认存储路径
Hive表默认存储路径是由${HIVE_HOME}/conf/hive-site.xml配置文件的hive.metastore.warehouse.dir属性指定。默认值是:/user/hive/warehouse。
指定存储路径
在Hive建表的时候,可以通过LOCATION语法来更改数据在HDFS上的存储路径,使得建表加载数据更加灵活方便。
语法:LOCATION ‘
练习
原生数据类型建表练习
需求:文件archer.txt中记录了手游《王者荣耀》射手的相关信息,内容如下所示,其中字段之间分隔符为制表符\t,要求在Hive中建表映射成功该文件。
1 | 1 后羿 5986 1784 396 336 remotely archer |
字段含义:id、name(英雄名称)、hp_max(最大生命)、mp_max(最大法力)、attack_max(最高物攻)、defense_max(最大物防)、attack_range(攻击范围)、role_main(主要定位)、role_assist(次要定位)
实践:
1 | CREATE TABLE t_archer ( |
1 | 上传文件 |
复杂数据类型建表练习
需求:文件hot_hero_skin_price.txt中记录了手游《王者荣耀》热门英雄的相关皮肤价格信息,内容如下,要求在Hive中建表映射成功该文件。
1 | 1,孙悟空,53,西部大镖客:288-大圣娶亲:888-全息碎片:0-至尊宝:888-地狱火:1688 |
字段:id、name(英雄名称)、win_rate(胜率)、skin_price(皮肤及价格)
实践:
1 | 先上传文件 |
1 | -- 后建表并指定文件所在位置 |
Hive内、外部表
内部表 | 外部表 | |
---|---|---|
创建方式 | 默认情况 | 使用EXTERNAL语法关键字 |
Hive管理范围 | 元数据、表数据 | 元数据 |
删除表结果 | 删除元数据及HDFS上的文件数据 | 只删除元数据 |
操作 | 支持ARCHIVE,UNARCHIVE,TRUNCATE,MERGE,CONCATENATE | 不支持 |
事务 | 支持ACID/事务性 | 不支持 |
缓存 | 支持结果缓存 | 不支持 |
Hive分区表
概念: 分区的概念提供了一种将Hive表数据分离为多个文件/目录的方法。不同分区对应着不同的文件夹,同一分区的数据存储在同一个文件夹下。只需要根据分区值找到对应的文件夹,扫描本分区下的文件即可,避免全表数据扫描。
静态分区
描述:静态分区指的是分区的字段值是由用户在加载数据的时候手动指定的。
语法:
1 | LOAD DATA [LOCAL] INPATH "" INTO TABLE table_name PARTITION (分区字段 = '分区值'); |
[LOCAL] 表示数据是位于本地文件系统还是HDFS文件系统
分区字段不能是表中已经存在的
案例:
有一组文件位于本地文件系统上,请为其建立分区表。
1 | [eitan@hadoop102 ~]$ cd documents/txt/hero/ |
1 | -- 建表时需要指定分区字段 |
动态分区
描述:动态分区指的是分区的字段值是基于查询结果自动推断出来的。核心语法就是insert+select。
启用hive动态分区,需要在hive会话中设置两个参数:
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
语法:
1 | INSERT INTO TABLE table_name PARTITION (分区字段) SELECT table_fields FROM table_name; |
SELECT 查询字段必须要与 INSERT 后的 table_name 表字段一一对应,并最后加上 PARTITION 的分区字段
案例: 对学生表按地区、年龄分区
1 | -- 创建原数据表,并把响应数据放入目标目录下 |
如果表中定义了PARTITIONED,则INSERT语句中PARTITION不用写,并且写了分区顺序也是按表定义的来。
Hive分桶表
概念: 将所给数据按规则划分到不同物理文件中。
语法:
1 | --分桶表建表语句 |
案例:
现有美国2021-1-28号,各个县county的新冠疫情累计案例信息,包括确诊病例和死亡病例,数据格式如下所示:
1 | 2021-01-28,Juneau City and Borough,Alaska,02110,1108,3 |
字段含义如下:count_date(统计日期),county(县),state(州),fips(县编码code),cases(累计确诊病例),deaths(累计死亡病例)。
实践:
1 | --step1:开启分桶的功能 从Hive2.0开始不再需要设置 |
到HDFS上查看t_usa_covid19_bucket底层数据结构可以发现,数据被分为了5个文件
Hive事务表
Hive事务表的局限性
- 尚不支持BEGIN,COMMIT和ROLLBACK。所有语言操作都是自动提交的;
- 仅支持ORC文件格式(STORED AS ORC);
- 默认情况下事务配置为关闭。需要配置参数开启使用;
- 表必须是分桶表(Bucketed)才可以使用事务功能;
- 表参数transactional必须为true;
- 外部表不能成为ACID表,不允许从非ACID会话读取/写入ACID表。
Hive事务表实践
1 | --Hive中事务表的创建使用 |
Hive视图
概念
Hive中的视图(view)是一种虚拟表,只保存定义,不实际存储数据。通常从真实的物理表查询中创建生成视图,也可以从已经存在的视图上创建新视图。
创建视图时,将冻结视图的架构,如果删除或更改基础表,则视图将失败,并且视图不能存储数据,操作数据,只能查询。
概况起来就是:视图是用来简化操作的,它其实是一张虚表,在视图中不缓冲记录,也没有提高查询性能。
视图语法
1 | -- 1、创建视图 |
Hive物化视图
物化视图、视图区别
- 视图是虚拟的,逻辑存在的,只有定义没有存储数据;
- 物化视图是真实的,物理存在的,里面存储着预计算的数据;
- 视图的目的是简化降低查询的复杂度,而物化视图的目的是提高查询性能。
物化视图语法
1 | --物化视图的创建语法 |
物化视图创建后,select查询执行数据自动落地,”自动”也即在query的执行期间,任何用户对该物化视图是不可见的;
默认该物化视图可被用于查询优化器optimizer查询重写(在物化视图创建期间可以通过DISABLE REWRITE参数设置禁止使用);
SerDe和storage format非强制参数,可以用户配置,默认可用hive.materializedview.serde、 hive.materializedview.fileformat;
物化视图可以使用custom storage handlers存储在外部系统(如druid)
1
2
3 CREATE MATERIALIZED VIEW druid_wiki_mv
STORED AS 'org.apache.hadoop.hive.druid.DruidStorageHandler'
AS SELECT __time, page, user, c_added, c_removed FROM src;
- 物化视图创建后即可用于相关查询的加速,用户提交查询query,若该query经过重写后可命中已建视图,则被重写命中相关已建视图实现查询加速。是否重写查询使用物化视图可以通过全局参数控制(默认为true):
1 SET hive.materializedview.rewriting=true;用户可选择性的失能物化视图的重写:
1 ALTER MATERIALIZED VIEW [db_name.]materialized_view_name ENABLE|DISABLE REWRITE;
案例
1 | -- 1、Hive是否支持并发 |
Database(数据库)DDL操作
Create Database
1 | CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name |
COMMENT:数据库的注释说明语句
LOCATION:指定数据库在HDFS存储位置,默认/user/hive/warehouse
WITH DBPROPERTIES:用于指定一些数据库的属性配置。
Describe Database
1 | DESCRIBE DATABASE/SCHEMA [EXTENDED] db_name; |
EXTENDED:用于显示更多信息。
Use Database
1 | USE database_name; |
Drop Database
1 | DROP (DATABASE|SCHEMA) [IF EXISTS] database_name [RESTRICT|CASCADE]; |
默认行为是RESTRICT,这意味着仅在数据库为空时才删除它。要删除带有表的数据库,我们可以使用CASCADE。
Alter Database
1 | --更改数据库属性 |
Table(表)DDL操作
Describe Table
1 | DESCRIBE [FORMATTED|EXTENDED] [db_name.]table_name; |
Drop Table
1 | DROP TABLE [IF EXISTS] table_name [PURGE]; |
如果已配置垃圾桶(且未指定PURGE),则该表对应的数据实际上将移动到.Trash/Current目录,而元数据完全丢失。如果指定了PURGE,则表数据不会进入.Trash/Current目录,跳过垃圾桶直接被删除。
Truncate Table
1 | TRUNCATE [TABLE] table_name; |
从表中删除所有行。可以简单理解为清空表的所有数据但是保留表的元数据结构。如果HDFS启用了垃圾桶,数据将被丢进垃圾桶,否则将被删除。
Alter Table
1 | -- 1、更改表名 |
Partition(分区)DDL操作
Add Partition
1 | -- 一次添加一个分区 |
分区值仅在为字符串时才应加引号。位置必须是数据文件所在的目录。
ADD PARTITION会更改表元数据,但不会加载数据。如果分区位置中不存在数据,查询将不会返回任何结果。
Rename Partition
1 | -- 重命名分区 |
Delete Partition
1 | ALTER TABLE table_name DROP [IF EXISTS] PARTITION (dt='2008-08-08', country='us'); |
将删除该分区的数据和元数据。
Msck Partition
1 | -- 修复分区 |
MSCK命令的默认选项是“添加分区”。使用此选项,它将把HDFS上存在但元存储中不存在的所有分区添加到元存储中。DROP PARTITIONS选项将从已经从HDFS中删除的metastore中删除分区信息。SYNC PARTITIONS选项等效于调用ADD和DROP PARTITIONS。
如果存在大量未跟踪的分区,则可以批量运行MSCK REPAIR TABLE,以避免OOME(内存不足错误)。
Alter Partition
1 | -- 更改分区文件存储格式 |
Hive Show显示语法
1 | -- 1、显示所有数据库 SCHEMAS和DATABASES的用法 功能一样 |
Hive 的数据操纵语言(DML)
DML-LOAD加载数据
LOAD语法
1 | LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)] |
filepath
filepath表示的待移动数据的路径,可以引用一个文件(在这种情况下,Hive将文件移动到表中),也可以是一个目录(在这种情况下,Hive将把该目录中的所有文件移动到表中)。
具有schema的完整URI,例如:hdfs://namenode:9000/user/hive/project/data1
LOCAL
如果指定了LOCAL, load命令将在本地文件系统中查找文件路径。
如果没有指定LOCAL关键字,如果filepath指向的是一个完整的URI,hive会直接使用这个URI。否则Hive会使用hadoop配置文件中定义的schema 和 authority,即参数fs.default.name指定的(默认HDFS)。
OVERWRITE
如果使用了OVERWRITE关键字,则目标表(或者分区)中的内容会被删除,然后再将 filepath 指向的文件/目录中的内容添加到表/分区中。
案例
1 | -- step1:建表 |
Hive3.0 Load新特性
Hive 3.0及更高版本中,除了移动复制操作之外,还支持其他加载操作,因为Hive在内部在某些场合下会将加载重写为INSERT AS SELECT。
比如,如果表具有分区,则load命令没有指定分区,则将load转换为INSERT AS SELECT,并假定最后一组列为分区列。如果文件不符合预期的架构,它将引发错误。
1 | ------- hive 3.0 load命令新特性 ------------------ |
本来加载的时候没有指定分区,语句是报错的,但是文件的格式符合表的结构,前两个是col1,col2,最后一个是分区字段col3,则此时会将load语句转换成为insert as select语句。
DML-Insert插入数据
insert + select
1 | -- Hive中insert主要是结合select查询语句使用,将查询结果插入到表中,例如: |
INSERT OVERWRITE将覆盖表或分区中的任何现有数据。
如果查询出来的数据类型和插入表格对应的列数据类型不一致,将会进行转换,但是不能保证转换一定成功,转换失败的数据将会为NULL。
multiple inserts多重插入
multiple inserts可以翻译成为多次插入,多重插入,核心是:一次扫描,多次插入。其功能也体现出来了就是减少扫描的次数。
1 | ------------ multiple inserts ---------------------- |
dynamic partition insert动态分区插入
分区的值是由后续的select查询语句的结果来动态确定的。根据查询结果自动分区。案例参照 分区表-动态分区
insert + directory导出数据
1 | -- 标准语法: |
导出操作是一个OVERWRITE覆盖操作。
1 | --1、导出查询结果到HDFS指定目录下 |
Hive Transaction事务
实现原理
用HDFS文件作为原始数据(基础数据),用delta保存事务操作的记录增量数据;
正在执行中的事务,是以一个staging开头的文件夹维护的,执行结束就是delta文件夹。每次执行一次事务操作都会有这样的一个delta增量文件夹;
当访问Hive数据时,根据HDFS原始文件和delta增量文件做合并,查询最新的数据。
合并器(Compactor)
随着表的修改操作,创建了越来越多的delta增量文件,就需要合并以保持足够的性能。
合并器Compactor是一套在Hive Metastore内运行,支持ACID系统的后台进程。所有合并都是在后台完成的,不会阻止数据的并发读、写。合并后,系统将等待所有旧文件的读操作完成后,删除旧文件。
合并操作分为两种,minor compaction(小合并)、major compaction(大合并):
小合并会将一组delta增量文件重写为单个增量文件,默认触发条件为10个delta文件;
大合并将一个或多个增量文件和基础文件重写为新的基础文件,默认触发条件为delta文件相应于基础文件占比,10%。
参数 说明 hive.compactor.delta.num.threshold Specifies the number of delta directories in a partition that triggers an automatic minor compaction.The default value is 10. hive.compactor.delta.pct.threshold Specifies the percentage size of delta files relative to the corresponding base files that triggers an automatic major compaction. The default value is. 1, which is 10 percent.
DML-Update、Delete更新、删除数据
见Hive事务表-Hive事务表实践
Hive 的数据查询语言(DQL)
语法树
1 | [WITH CommonTableExpression (, CommonTableExpression)*] |
- ALL和DISTINCT选项指定是否应返回重复的行。如果没有给出这些选项,则默认值为ALL(返回所有匹配的行)。DISTINCT指定从结果集中删除重复的行。
执行顺序
在查询过程中执行顺序:from > where > group(含聚合)> having >order > select;
聚合语句(sum,min,max,avg,count)要比having子句优先执行
where子句在查询过程中执行优先级别优先于聚合语句(sum,min,max,avg,count)
1 | select state,sum(deaths) as cnts |
ORDER BY
1 | ---order by |
CLUSTER BY
1 | --cluster by |
Hive SQL中的CLUSTER BY语法可以指定根据后面的字段将数据分组,每组内再根据这个字段正序排序(不允许指定排序规则),概况起来就是:根据同一个字段,分且排序。
DISTRIBUTE BY +SORT BY
1 | -- 案例:把学生表数据根据性别分为两个部分,每个分组内根据年龄的倒序排序。 |
如果说CLUSTER BY的功能是分且排序(同一个字段),那么DISTRIBUTE BY +SORT BY就相当于把cluster by的功能一分为二:DISTRIBUTE BY负责分,SORT BY负责分组内排序,并且可以是不同的字段。
sort by不是全局排序,其在数据进入reducer前完成排序。因此,如果用sort by进行排序,并且设置mapred.reduce.tasks>1,则sort by只保证每个reducer的输出有序,不保证全局有序。
distribute by(字段)根据指定字段将数据分到不同的reducer,分发算法是hash散列。
Union联合查询
1 | select_statement UNION [ALL | DISTINCT] select_statement UNION [ALL | DISTINCT] select_statement ... |
Common Table Expressions(CTE)
1 | --选择语句中的CTE |
公用表表达式(CTE)是一个临时结果集,该结果集是从WITH子句中指定的简单查询派生而来的,该查询紧接在SELECT或INSERT关键字之前。
join连接查询
inner join
连接的两个表中都存在与连接条件相匹配的数据才会被留下来。
left join
join时以左表的全部数据为准,右边与之关联;左表数据全部返回,右表关联上的显示返回,关联不上的显示null返回。
right jion
join时以右表的全部数据为准,左边与之关联;右表数据全部返回,左表关联上的显示返回,关联不上的显示null返回。
full outer join
它等价于对这两个数据集合分别进行左外连接和右外连接,然后再使用消去重复行的操作将上述两个结果集合并为一个结果集。
left semi join
只返回左边表的记录的字段,前提是其记录对于右边的表满足ON语句中的判定条件。相当于inner join但是只返回左边的字段。
cross join
相当于无条件的inner join。
join注意事项
如果每个表在联接子句中使用相同的列,则Hive将多个表上的联接转换为单个MR作业
1
2
3
4
5SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1)
--由于联接中仅涉及b的key1列,因此被转换为1个MR作业来执行,并且表a和b的键的特定值的值被缓冲在reducer的内存中。然后,对于从c中检索的每一行,将使用缓冲的行来计算联接。
SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key2)
--计算涉及两个MR作业。其中的第一个将a与b连接起来,并缓冲a的值,同时在reducer中流式传输b的值。在join的时候,可以通过语法STREAMTABLE提示指定要流式传输的表。如果省略STREAMTABLE提示,则Hive将流式传输最右边的表
1
2SELECT /*+ STREAMTABLE(a) */ a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1)
--a,b,c三个表都在一个MR作业中联接,并且表b和c的键的特定值的值被缓冲在reducer的内存中。然后,对于从a中检索到的每一行,将使用缓冲的行来计算联接。如果省略STREAMTABLE提示,则Hive将流式传输最右边的表。如果除一个要连接的表之外的所有表都很小,则可以将其作为仅map作业执行
1
2SELECT /*+ MAPJOIN(b) */ a.key, a.value FROM a JOIN b ON a.key = b.key
--不需要reducer。对于A的每个Mapper,B都会被完全读取。限制是不能执行FULL / RIGHT OUTER JOIN b。