Hive教程

  • 1.1 HiveHiveHive的介绍
  • 1.2 HiveHiveHive的设计原理
  • 1.3 HiveHiveHive的架构图
  • 1.4 HiveHiveHive的手动安装部署与配置
  • 1.5 HiveHiveHive和HDFSHDFSHDFS之间的存储关系
  • 1.6 HiveHiveHive数据库元数据表信息
  • 1.7 HiveHiveHive中的DDLDDLDDL和DMLDMLDML
    • 1.7.1 创建库
    • 1.7.2 删除库
    • 1.7.3 创建表
    • 1.7.4 加载数据
    • 1.7.5 向表中写入其他表的内容
    • 1.7.6 把数据从Hive中写入到本地文件系统
  • 1.8 HiveHiveHive中表的分类
    • 1.8.1查看表的类型
    • 1.8.2 管理表
    • 1.8.3 外部表
    • 1.8.4 管理表和外部表的区别
    • 1.8.5 分区表
      • 1.8.5.1 手动分区
      • 1.8.5.2 自动分区
    • 1.8.6 分桶表
  • 1.9 HiveHiveHive中的特殊joinjoinjoin
    • 1.9.1 MapMapMap JOINJOINJOIN
      • 1.9.1.1 MapMapMap JOINJOINJOIN方式一
      • 1.9.1.2 MapMapMap JOINJOINJOIN方式二
    • 1.9.2 SMBSMBSMB JOINJOINJOIN
  • 1.10 HiveHiveHive中的排序
  • 1.11 HiveHiveHive中的SQLSQLSQL脚本
  • 1.12 HiveHiveHive中的特殊数据类型
    • 1.12.1 arrayarrayarray
    • 1.12.2 mapmapmap
  • 1.13 HiveHiveHive中使用正则表达式
  • 1.14 HiveHiveHive的函数
    • 1.14.1 HiveHiveHive的函数分类
      • 1.14.1.1 UDFUDFUDF
      • 1.14.1.2 UDAFUDAFUDAF
      • 1.14.1.3 UDTFUDTFUDTF
      • 1.14.1.4 创建临时函数
      • 1.14.1.5 创建永久函数
    • 1.14.2 HiveHiveHive的字符串函数
      • 1.14.2.1 substring/substrsubstring/substrsubstring/substr
      • 1.14.2.2 coalescecoalescecoalesce
      • 1.14.2.3 ififif
      • 1.14.2.4 splitsplitsplit
      • 1.14.2.5 instrinstrinstr
      • 1.14.2.6 lowerlowerlower
      • 1.14.2.7 upperupperupper
      • 1.14.2.8 reversereversereverse
      • 1.14.2.9 regexpregexpregexp_replacereplacereplace
      • 1.14.2.10 regexpregexpregexp_extractextractextract
      • 1.14.2.11 concat/concatconcat/concatconcat/concat_wswsws
      • 1.14.2.12 parseparseparse_urlurlurl
      • 1.14.2.13 parseparseparse_urlurlurl__tupletupletuple
    • 1.14.3 HiveHiveHive的日期函数
      • 1.14.3.1 yearyearyear
      • 1.14.3.2 monthmonthmonth
      • 1.14.3.3 daydayday
      • 1.14.3.4 hourhourhour
      • 1.14.3.5 tototo_datedatedate
      • 1.14.3.6 minuteminuteminute
      • 1.14.3.7 secondsecondsecond
      • 1.14.3.8 datedatedate_addaddadd
      • 1.14.3.9 datedatedate_subsubsub
      • 1.14.3.10 unixunixunix_timestamptimestamptimestamp
      • 1.14.3.11 fromfromfrom_unixtimeunixtimeunixtime
      • 1.14.3.12 datediffdatediffdatediff
      • 1.14.3.13 weekofyearweekofyearweekofyear
    • 1.14.4 laterallaterallateral viewviewview侧视图
    • 1.14.5 explodeexplodeexplode函数
    • 1.14.6 特殊函数
      • 1.14.6.1 reflectreflectreflect
      • 1.14.6.2 jsonjsonjson处理
        • 1.14.6.2.1 使用HiveHiveHive中的内置函数对jsonjsonjson进行处理
        • 1.14.6.2.2 通过jsonjsonjson的解析工具类直接加载数据解析
    • 1.14.7 窗口函数和分析函数
      • 1.14.7.1 窗口函数
        • 1.14.7.1.1 位置窗口
          • 1.14.7.1.1.1 FIRSTFIRSTFIRST_VALUEVALUEVALUE
          • 1.14.7.1.1.2 LASTLASTLAST_VALUEVALUEVALUE
          • 1.14.7.1.1.3 LEADLEADLEAD
          • 1.14.7.1.1.4 LAGLAGLAG
        • 1.14.7.1.2 聚合窗口
          • 1.14.7.1.2.1 MAXMAXMAX
          • 1.14.7.1.2.2 MINMINMIN
          • 1.14.7.1.2.3 SUMSUMSUM
          • 1.14.7.1.2.4 COUNTCOUNTCOUNT
          • 1.14.7.1.2.5 AVGAVGAVG
      • 1.14.7.2 分析函数
        • 1.14.7.2.1 ROWROWROW_NUMBERNUMBERNUMBER
        • 1.14.7.2.2 RANKRANKRANK
        • 1.14.7.2.3 DENSEDENSEDENSE_RANKRANKRANK
        • 1.14.7.2.4 ROWROWROW__NUMBERNUMBERNUMBER,RANKRANKRANK以及DENSEDENSEDENSE___RANKRANKRANK的区别
        • 1.14.7.2.5 NTILENTILENTILE :对分区内部再次进行均分,通常用作求数据的百分比,百分率等。
    • 1.14.8 CASE WHEN 用法
      • 1.14.8.1 第一种用法
      • 1.14.8.2 第二种用法
    • 1.14.9 行列转换
      • 1.14.9.1 行转列
        • 1.14.9.1.1 多行转多列
        • 1.14.9.1.2 多行转单列
      • 1.14.9.2 列转行
        • 1.14.9.2.1 多列转多行
        • 1.14.9.2.2 单列转多行
  • 1.15 HiveHiveHive的调优
    • 1.15.1 fetchfetchfetch tasktasktask
    • 1.15.2 严格模式
    • 1.15.3 本地模式
    • 1.15.4 JVMJVMJVM重用
    • 1.15.5 推测执行
    • 1.15.6 压缩
      • 1.15.6.1 优点
      • 1.15.6.2 缺点
      • 1.15.6.3 压缩分析
      • 1.15.6.4 压缩设置
    • 1.15.7 MapMapMap端聚合
    • 1.15.8 并行计算
    • 1.15.9 SQLSQLSQL优化
      • 1.15.9.1 分区裁剪
      • 1.15.9.2 列裁剪
      • 1.15.9.3 count(distinct)count(distinct)count(distinct)
      • 1.15.9.4 表优化
    • 1.15.10 数据存储格式
      • 1.15.10.1 行式存储
        • 1.15.10.1.1 优点
        • 1.15.10.1.2 缺点
      • 1.15.10.2 列式存储
        • 1.15.10.2.1 优点
        • 1.15.10.2.2缺点
    • 1.15.11 数据倾斜
      • 1.15.11.1 MapreduceMapreduceMapreduce的解决方案
      • 1.15.11.2 HiveHiveHive的解决方案
  • 1.16 数仓设计
    • 1.16.1 数据仓库
      • 1.16.1.1 数据仓库的特点
      • 1.16.1.2 数据仓库和数据库的区别
    • 1.16.2 分层设计
      • 1.16.2.1 常见的分层架构图
      • 1.16.2.2 分层实现
        • 1.16.2.2.1 ODSODSODS层
        • 1.16.2.2.2 DWDDWDDWD层
        • 1.16.2.2.3 DWS/DMDWS/DMDWS/DM层
        • 1.16.2.2.4 APP/ADS层
        • 1.16.2.2.5 常见的一些辅助层
    • 1.16.3 建模设计
      • 1.16.3.2.1 雪花模型
        • 1.16.3.2.1.1 结构
        • 1.16.3.2.1.2 存在的问题
      • 1.16.3.2.2 星型模型
        • 1.16.3.2.2.1 结构
        • 1.16.3.2.2.2 特点
      • 1.16.3.2.3 星座模型
        • 1.16.3.2.3.1 结构
  • 1.17 HiveHiveHive的mavenmavenmaven相关依赖

1.1 HiveHiveHive的介绍

HiveHiveHive是FacebookFacebookFacebook公司设计的一款专门为数据分析师提供的使用SQLSQLSQL可以操作HadoopHadoopHadoop的基于HadoopHadoopHadoop之上的数据中间件,相当于是HadoopHadoopHadoop的一个客户端。HiveHiveHive有两大功能,存储和计算,存储是将表映射成HDFSHDFSHDFS上的文件,计算是将SQLSQLSQL语句转换成MapreduceMapreduceMapreduce代码运行在YARNYARNYARN集群上,在当前的大数据环境下,MapreduceMapreduceMapreduce运行的太慢了,所以当前HIVEHIVEHIVE的主要应用场景是数据仓库的构建。

1.2 HiveHiveHive的设计原理

将HDFSHDFSHDFS文件通过metadatametadatametadata元数据映射成表的数据,将SQLSQLSQL转换为MapreduceMapreduceMapreduce程序来操作HadoopHadoopHadoop。

1.3 HiveHiveHive的架构图

  • 客户端 :负责与用户交互,让用户开发SQLSQLSQL,并返回结果显示给用户
  • 服务端
    • 连接器 :管理客户端访问的连接。
    • 解析器 :通过访问HiveHiveHive的元数据对SQLSQLSQL的词法、语法进行校验,例如检查库、表、字段是否都存在。
    • 逻辑计划 :将SQLSQLSQL语句中的参数进行解析,赋值给底层的MapreduceMapreduceMapreduce模板。
    • 优化器 :根据MapreduceMapreduceMapreduce的使用,自动选择最优的方式来进行实现。
    • 物理计划 :形成一个完整的MapreduceMapreduceMapreduce程序。
    • 执行器 :将MapreduceMapreduceMapreduce程序提交给YARNYARNYARN集群运行。
  • 元数据
    • 负责存储表与文件之间的映射关系
    • 负责存储所有表的信息。数据库、字段、分隔符等
  • MetaStoreMetaStoreMetaStore :元数据管理服务,负责HiveHiveHive和数据库进行交互。

1.4 HiveHiveHive的手动安装部署与配置

  ##解压tar -zxvf hive-1.1.0-cdh5.14.0.tar.gz -C /usr/local##创建软连接ln -s /usr/local/hive-1.1.0-cdh5.14.0 /usr/local/hive##配置系统环境变量vim /etc/profile##HIVE HOMEexport HIVE_HOME=/usr/local/hiveexport PATH=$PATH:$HIVE_HOME/bin##刷新环境变量source /etc/profile##修改环境变量cd /usr/local/hive/confvim hive-env.shexport HADOOP_HOME=/usr/local/hadoop-x.x.x-cdhx.x.xexport HIVE_CONF_DIR=/usr/local/hive/conf##配置元数据存储在关系型数据库中vim hive-site.xml<!--配置将元数据存储在MySQL中,如果是其他数据库的话,配置对应的jdbc连接和Driver驱动--><property><name>javax.jdo.option.ConnectionURL</name><value>jdbc:mysql://v6:3306/hive?createDatabaseIfNotExist=true</value></property><property><name>javax.jdo.option.ConnectionDriverName</name><value>com.mysql.jdbc.Driver</value></property><property><name>javax.jdo.option.ConnectionUserName</name><value>root</value></property><property><name>javax.jdo.option.ConnectionPassword</name><value>123456</value></property><!--配置统一的元数据管理服务MetaStore--><property><name>hive.metastore.uris</name><value>thrift://v3:9083</value></property><!--显示当前的数据库名称--><property><name>hive.cli.print.current.db</name><value>true</value></property><!--显示SQL结果的每一列的名称--><property><name>hive.cli.print.header</name><value>true</value></property>##并且添加对应的驱动包到HIVE的lib目录下mv mysql-connector-java-5.1.38.jar /usr/local/hive/lib##修改Hive的日志存储位置mkdir /usr/local/hive/logscd /usr/local/hive/confmv hive-log4j.properties.template hive-log4j.propertiesvim hive-log4j.propertieshive.log.threshold=ALL#指定日志级别hive.root.logger=INFO,DRFA  #指定日志存储位置hive.log.dir=/usr/local/hive/logshive.log.file=hive.log##启动HIVE##1. 先启动Hadoop的HDFS和YARN##2.在Hadoop中创建HIVE的目录hdfs dfs -mkdir /tmphdfs dfs -chmod g+w /tmphdfs dfs -mkdir -p /user/hive/warehousehdfs dfs -chmod g+w /user/hive/warehouse##在HIVE2.1版本及以上在第一次启动HIVE的时候还要初始化元数据cd /usr/local/hive/bin./schematool -dbType mysql -initSchema##3.必须先启动MetaStore服务cd /usr/local/hive/bin./hive --service metastore &#检测是否真正启动成功netstat -atunlp | grep 9083##启动HIVE的服务端./hiveserver2 &#检测是否真正启动成功netstat -atunlp | grep 10000##最后就可以启动HIVE的客户端了通过beeline./beeline -u jdbc:hive2://v5:10000 -n root -p 123456#退出客户端!quit

1.5 HiveHiveHive和HDFSHDFSHDFS之间的存储关系

  • HiveHiveHive数仓在HDFSHDFSHDFS上的位置:hive.metastore.warehouse.dir=/user/hive/warehousehive.metastore.warehouse.dir=/user/hive/warehousehive.metastore.warehouse.dir=/user/hive/warehouse
  • HiveHiveHive中创建的所有数据库都会在该目录下创建对应一个目录,自动以dbname.dbdbname.dbdbname.db命名
    • 这个目录也作为defaultdefaultdefault数据库的目录
  • HiveHiveHive中的所有数据库,都会对应一个hdfshdfshdfs的目录
  • HiveHiveHive中所有的表,都会默认对应一个hdfshdfshdfs的目录,目录在数据库目录的下面
  • HiveHiveHive表中的数据,默认在表的目录下面

1.6 HiveHiveHive数据库元数据表信息

  • DBSDBSDBS:记录了HiveHiveHive中所有数据库的信息
  • TBLSTBLSTBLS:记录了HiveHiveHive中所有表的信息
  • SDSSDSSDS:记录了所有表与HDFSHDFSHDFS的映射关系

1.7 HiveHiveHive中的DDLDDLDDL和DMLDMLDML

1.7.1 创建库

  CREATE DATABASE [IF NOT EXISTS] database_name[COMMENT '库详细信息'][LOCATION HDFS_PATH];--LOCATION:所有Hive中的数据库默认会有一个HDFS对应的目录,如果不存在会自动在/user/hive/warehouse目录下创建,该选项可以自定义,手动指定某个HDFS目录作为数据库目录

1.7.2 删除库

  DROP DATABASE [IF EXISTS] database_name [CASCADE];--CASCADE:强制删除,不加CASCADE只能删除空数据库

1.7.3 创建表

  CREATE [EXTERNAL] TABLE [IF NOT EXISTS] TAB_NAME(COLUMN1 TYPE1,COLUMN2 TYPE2...)[PARTITIONED BY COLUMN] --按照那个字段进行分区[CLUSTERED BY COLUMN INTO N BUCKETS ] --按照那个字段进行分桶ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' --指定列分隔符 默认为\001ROW FORMAT DELIMITED LINES TERMINATED BY '\n' --指定行的分隔符 默认为\n[STORED AS FILE_FORMAT] --指定表中数据文件的类型,默认为textfile,可选orc/parquet等[LOCATION HDFS_PATH] --手动指定表所在的HDFS目录--注意:Hive中的SQL语句不能包含制表符--EXTERNAL : 声明外部表的关键字--将SQL语句的结果保存为一张不存在的表CREATE TABLE [IF NOT EXISTS] TB_NAME AS SELECT ...--复制一个已存在的表的表结构,不复制数据,构建一张新的表CREATE TABLE [IF NOT EXISTS] TB_NAME LIKE EXISTS_TB_NAME;

1.7.4 加载数据

  LOAD DATA [LOCAL] INPATH '' [OVERWRITE] INTO TABLE TB_NAME;--LOCAL:表示加载本地数据,原理实际上是将本地文件上传到了表的目录下--不加LOCAL:表示加载HDFS数据,原理实际上将HDFS上的文件移动到表的目录下--OVERWRITE :会覆盖表中已存在的数据

1.7.5 向表中写入其他表的内容

   --方式一INSERT OVERWRITE/INTO TABLE TB_NAME SELECT ...;--OVERWRITE:插入并覆盖--INTO:追加

1.7.6 把数据从Hive中写入到本地文件系统

   --方式二INSERT OVERWRITE [LOCAL] DIRECTORY directory1 [ROW FORMAT] SELECT ... FROM ...--LOCAL:表示写入本地文件系统--不加LOCAL表示写入HDFS文件系统--ROW FORMATrow format delimited fields terminated by '\001' --列分隔符row format delimited lines terminated by '\n' --行分隔符

1.8 HiveHiveHive中表的分类

1.8.1查看表的类型

  desc formatted tb_name

1.8.2 管理表

默认的表的创建类型,

1.8.3 外部表

在创建表的时候可以通过EXTERNALEXTERNALEXTERNAL关键字来创建一张外部表

1.8.4 管理表和外部表的区别

  • 管理表在删除数据的时候表结构元数据以及HDFSHDFSHDFS的表目录以及数据都被删除了。
  • 外部表在删除数据的时候只删除了表结构以及当前表对应的元数据,表的目录以及数据都还存在

1.8.5 分区表

在HiveHiveHive中,由于数据是增量的,如果把所有的数据存储在一个文件中,不利于数据的检索查询,于是出现了分区的概念,分区有两种实现方式,分区后每个分区表对应一个目录,表的最后一级目录是分区目录。分区表主要是为了优化底层MapreduceMapreduceMapreduce的输入。

1.8.5.1 手动分区

原始数据就是分区存在的,按照时间或者数据的特征。

--语法,一级分区
CREATE TABLE TB_NAME(
COLUMN1 STRING,
COLUMN2 STRING,
COLUMN3 STRING,
....
)
PARTITIONED BY (COLUMN4 TYPE)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
-- 向分区表中导入数据
LOAD DATA [LOCAL] INPATH '' INTO TABLE TB_NAME PARTITION(COLUMN4 = '...');
--语法,多级分区
CREATE TABLE TB_NAME(
COLUMN1 STRING,
COLUMN2 STRING,
COLUMN3 STRING,
....
)
PARTITIONED BY (COLUMN4 TYPE,COLUMN5 TYPE)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\n';
-- 向分区表中导入数据
LOAD DATA [LOCAL] INPATH '' INTO TABLE TB_NAME PARTITION (COLUMN4='...',COLUMN5 = '...');

注意:手动分区的分区字段不存在于数据文件中,但是在创建分区表后,表的字段个数算上分区字段。

1.8.5.2 自动分区

原始数据不是分区存在的,这样可以在导入数据的时候进行分区,写入分区表中。

--语法 示例
--开启自动分区的参数
SET hive.exec.dynamic.partition.mode = nonstrict;
CREATE TABLE TB_NAME(
COLUMN1 STRING,
COLUMN2 STRING,
COLUMN3 STRING,
....
)
PARTITIONED BY (COLUMN4 TYPE)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
-- 导入数据
INSERT INTO TABLE TB_NAME PARTITION(COLUMN4) SELECT *,COLUMN4 FROM TB_NAME;

注意:自动分区的分区字段存在于源数据中,并且分区字段要是最后一个字段。

1.8.6 分桶表

在HiveHiveHive中,两张表进行关联查询的时候,如果两张表的数据量都非常大,在这两个表进行join的时候,会产生笛卡尔积,在Hive中是严禁产生笛卡尔积的joinjoinjoin的,分桶主要应用场景是两个大表进行joinjoinjoin去笛卡尔积的,SMBSMBSMB joinjoinjoin。HiveHiveHive中的分桶就是MapreduceMapreduceMapreduce的分区,分桶的规则就是HashHashHash取余规则。

--分桶的操作示例
CREATE TABLE TB_NAME1(
COLUMN1 TYPE1,
COLUMN2 TYPE2,
COLUMN3 TYPE3
...
)
CLUSTERED BY (CLOUMN3) INTO 3 BUCKETS
--给分桶表中添加数据
--CLOUMN4这个字段存在于TB_NAME2表中,并且和TB_NAME1的CLOUMN3字段内容相同
INSERT OVERWRITE/INTO TABLE TB_NAME1 SELECT * FROM TB_NAME2 CLUSTER BY (CLOUMN4);

1.9 HiveHiveHive中的特殊joinjoinjoin

1.9.1 MapMapMap JOINJOINJOIN

HiveHiveHive中小表JOINJOINJOIN大表用到的JOINJOINJOIN ,小表的大小阈值为128M,可以认为这是一张小表,配置的参数为:

set hive.mapjoin.smalltable.filesize=25123456;

HiveHiveHive中程序走MapMapMap JOINJOINJOIN有两种方式

1.9.1.1 MapMapMap JOINJOINJOIN方式一

在HiveHiveHive中可以配置参数,HiveHiveHive会自动判断是否走MapMapMap JOINJOINJOIN,参数为:

set hive.auto.convert.join = true; 默认为true

1.9.1.2 MapMapMap JOINJOINJOIN方式二

可以强制程序走Map JOIN,示例如下

SELECT /*Map(A)*/ * FROM TB_NAME A LEFT JOIN TB_NAME2 B ON A.COLUMN = B.COLUMN

1.9.2 SMBSMBSMB JOINJOINJOIN

是两张桶表之间的JOINJOINJOIN ,并且这两张桶表的桶个数要为整数倍,在HiveHiveHive中如果表的数据量很大并且和其他表还有关联关系,建议把表设置为桶表。
设置相关的参数

set hive.auto.convert.sortmerge.join=true;
set hive.optimize.bucketmapjoin = true;
set hive.optimize.bucketmapjoin.sortedmerge = true;

1.10 HiveHiveHive中的排序

  • orderorderorder bybyby :全局排序:只能用于reduce只有一个的排序
  • sortsortsort bybyby :局部排序,每个reduce内部的排序
  • distributedistributedistribute bybyby :类似于分桶表,指定SQLSQLSQL转换为MapreduceMapreduceMapreduce后按照那个字段进行分区,也就是表的分区字段,一般和sortsortsort bybyby配合使用
  • clusterclustercluster bybyby :相当于sortsortsort bybyby + distributedistributedistribute bybyby,如果sortsortsort bybyby和distributedistributedistribute bybyby指定的字段是同一个字段,则可以使用clusterclustercluster bybyby代替,但是排序只能是倒序
  • reducereducereduce相关的参数设置
set hive.exec.reducers.bytes.per.reducer= :设置每个reduce最多处理多少数据
set hive.exec.reducers.max=:设置reduce的最大个数
set mapreduce.job.reduces= :设置reduceTask的数量

1.11 HiveHiveHive中的SQLSQLSQL脚本

cd /usr/local/hive/bin
./hive
-d/--hivevar/--hiveconf:#用于自定义一个Hive的变量
--database:#指定访问的数据库名称
-e:#执行一条SQL语句
-f:#执行一个SQL文件
-S:##显示比较少的日志
-v:##显示详细的日志

示例

  ./hive --database db_name -e "SELECT * FROM TB_NAME"./hive --database db_name -S -d tb_name = $tbname -f /root/hive.sql
SELECT * FROM ${hiveconf:tb_name}

1.12 HiveHiveHive中的特殊数据类型

1.12.1 arrayarrayarray

--示例
CREATE TABLE TB_NAME(
COLUMN1 TYPE,
COLUMN2 array<String>
...
)
--数据样式 1    1,2,3,4,5,6
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' ---列分隔符
COLLECTION ITEMS TERMINATED BY ',';  --集合每个元素之间的分隔符LOAD DATA [LOCAL] INPATH '文件位置' INTO TABLE TB_NAME;--查询方式
SELECT SIZE(COLUMN2) AS NUMB,COLUMN FROM TB_NAME;
SELECT COLUMN ,COLUMN2[0],COLUMN2[1] FROM TB_NAME;

1.12.2 mapmapmap

--示例
CREATE TABLE TB_NAME(
COLUMN1 TYPE,
COLUMN2 map<string,string>
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY '-' MAP KEYS TERMINATED BY ':';
COLLECTION ITEMS TERMINATED BY '-' --KEYVALUE对的分隔符
MAP KEYS TERMINATED BY ':' --KEY和VALUE之间的分隔符
--数据样式 1    唱歌:非常喜欢-跳舞:一般-游泳:不喜欢
LOAD DATA [LOCAL] INPATH '文件位置' INTO TABLE TB_NAME;--查询方式
SELECT COLUMN1 ,SIZE(COLUMN2) AS NUMB FROM TB_NAME
SELECT COLUMN1,COLUMN2["唱歌"] AS TEMP FROM TB_NAME;

1.13 HiveHiveHive中使用正则表达式

对于列的分隔符不固定的数据,在数据加载到HIVE表的时候可以使用正则校验,示例

CREATE TABLE TB_NAME(
COLUMN TYPE,
COLUMN1 TYPE
...
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES(
"input.regex" = "(...) (...)"
)
--ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe' 通过正则匹配每一个字段
--input.regex 指定每个字段的正则表达式

1.14 HiveHiveHive的函数

show functions;--查看所有的内置函数
desc function extended func_name; --查看某个内置函数的用法

1.14.1 HiveHiveHive的函数分类

1.14.1.1 UDFUDFUDF

普通函数,一对一的函数,一进一出,
实现一个自己创建的UDFUDFUDF函数步骤
* 开发一个类并继承GenericUDFGenericUDFGenericUDF这个类
* 重写这个抽象类的三个方法
* 在该方法中实现对应的逻辑,在实现对应逻辑的过程中对于数据类型尽量使用HadoopHadoopHadoop的序列化类型。
示例

public class GenericUDFArray extends GenericUDF {private transient Converter[] converters;private transient ArrayList<Object> ret = new ArrayList<Object>();@Overridepublic ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {GenericUDFUtils.ReturnObjectInspectorResolver returnOIResolver = new GenericUDFUtils.ReturnObjectInspectorResolver(true);for (int i = 0; i < arguments.length; i++) {if (!returnOIResolver.update(arguments[i])) {throw new UDFArgumentTypeException(i, "Argument type \""+ arguments[i].getTypeName()+ "\" is different from preceding arguments. "+ "Previous type was \"" + arguments[i - 1].getTypeName() + "\"");}}converters = new Converter[arguments.length];ObjectInspector returnOI =returnOIResolver.get(PrimitiveObjectInspectorFactory.javaStringObjectInspector);for (int i = 0; i < arguments.length; i++) {converters[i] = ObjectInspectorConverters.getConverter(arguments[i],returnOI);}return ObjectInspectorFactory.getStandardListObjectInspector(returnOI);}@Overridepublic Object evaluate(DeferredObject[] arguments) throws HiveException {ret.clear();for (int i = 0; i < arguments.length; i++) {ret.add(converters[i].convert(arguments[i].get()));}return ret;}@Overridepublic String getDisplayString(String[] children) {return getStandardDisplayString("array", children, ",");}
}

1.14.1.2 UDAFUDAFUDAF

聚合函数,多进一出
实现一个自己创建的UDAFUDAFUDAF函数步骤

* 开发一个类,继承$AbstractGenericUDAFResolver$* 重写方法getEvaluator

示例

@Description(name = "collect_set", value = "_FUNC_(x) - Returns a set of objects with duplicate elements eliminated")
public class GenericUDAFCollectSet extends AbstractGenericUDAFResolver {static final Log LOG = LogFactory.getLog(GenericUDAFCollectSet.class.getName());public GenericUDAFCollectSet() {}@Overridepublic GenericUDAFEvaluator getEvaluator(TypeInfo[] parameters)throws SemanticException {if (parameters.length != 1) {throw new UDFArgumentTypeException(parameters.length - 1,"Exactly one argument is expected.");}switch (parameters[0].getCategory()) {case PRIMITIVE:case STRUCT:case MAP:case LIST:break;default:throw new UDFArgumentTypeException(0,"Only primitive, struct, list or map type arguments are accepted but "+ parameters[0].getTypeName() + " was passed as parameter 1.");}return new GenericUDAFMkCollectionEvaluator(BufferType.SET);}}

1.14.1.3 UDTFUDTFUDTF

表生成函数,一进多出
实现一个自己创建的UDTFUDTFUDTF函数步骤
* 定义一个类继承GenericUDTFGenericUDTFGenericUDTF类
* 实现如下方法
* initializeinitializeinitialize:初始化的方法
* processprocessprocess:真正实现转换的 方法
* closecloseclose:关闭资源的方法
注意:自定义UDTFUDTFUDTF函数只能在SELECTSELECTSELECT语句中使用,不能跟其他字段放在一起使用,不能嵌套使用,不能与groupgroupgroup bybyby/sortsortsort bybyby/distributedistributedistribute bybyby/clusterclustercluster bybyby一起使用,能与orderorderorder bybyby一起使用。
示例

public class GenericUDTFStack extends GenericUDTF {@Overridepublic void close() throws HiveException {}private transient List<ObjectInspector> argOIs = new ArrayList<ObjectInspector>();private transient Object[] forwardObj = null;private transient ArrayList<ReturnObjectInspectorResolver> returnOIResolvers =new ArrayList<ReturnObjectInspectorResolver>();IntWritable numRows = null;Integer numCols = null;@Overridepublic StructObjectInspector initialize(ObjectInspector[] args)throws UDFArgumentException {if (args.length < 2)  {throw new UDFArgumentException("STACK() expects at least two arguments.");}if (!(args[0] instanceof WritableConstantIntObjectInspector)) {throw new UDFArgumentException("The first argument to STACK() must be a constant integer (got " +args[0].getTypeName() + " instead).");}numRows =((WritableConstantIntObjectInspector)args[0]).getWritableConstantValue();if (numRows == null || numRows.get() < 1) {throw new UDFArgumentException("STACK() expects its first argument to be >= 1.");}// Divide and round up.numCols = (args.length - 1 + numRows.get() - 1) / numRows.get();for (int jj = 0; jj < numCols; ++jj) {returnOIResolvers.add(new ReturnObjectInspectorResolver());for (int ii = 0; ii < numRows.get(); ++ii) {int index = ii * numCols + jj + 1;if (index < args.length && !returnOIResolvers.get(jj).update(args[index])) {throw new UDFArgumentException("Argument " + (jj + 1) + "'s type (" +args[jj + 1].getTypeName() + ") should be equal to argument " +index + "'s type (" + args[index].getTypeName() + ")");}}}forwardObj = new Object[numCols];for (int ii = 0; ii < args.length; ++ii) {argOIs.add(args[ii]);}ArrayList<String> fieldNames = new ArrayList<String>();ArrayList<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>();for (int ii = 0; ii < numCols; ++ii) {fieldNames.add("col" + ii);fieldOIs.add(returnOIResolvers.get(ii).get());}return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs);}@Overridepublic void process(Object[] args)throws HiveException, UDFArgumentException {for (int ii = 0; ii < numRows.get(); ++ii) {for (int jj = 0; jj < numCols; ++jj) {int index = ii * numCols + jj + 1;if (index < args.length) {forwardObj[jj] = returnOIResolvers.get(jj).convertIfNecessary(args[index], argOIs.get(index));} else {forwardObj[ii] = null;}}forward(forwardObj);}}@Overridepublic String toString() {return "stack";}
}

1.14.1.4 创建临时函数

  • 把项目打好包后上传到HiveHiveHive的libliblib目录下
  • CREATECREATECREATE TEMPORARYTEMPORARYTEMPORARY FUNCTIONFUNCTIONFUNCTION functionNamefunctionNamefunctionName ASASAS classNameclassNameclassName
    • functionNamefunctionNamefunctionName: 函数名
    • classNameclassNameclassName:类全限定名

1.14.1.5 创建永久函数

  • 把打好的jarjarjar包上传的hdfshdfshdfs上面
  • CREATECREATECREATE TEMPORARYTEMPORARYTEMPORARY FUNCTIONFUNCTIONFUNCTION functionNamefunctionNamefunctionName ASASAS classNameclassNameclassName USINGUSINGUSING JARJARJAR hdfsPathhdfsPathhdfsPath;
    • functionNamefunctionNamefunctionName:函数名
    • classNameclassNameclassName:类全限定名,
    • hdfsPathhdfsPathhdfsPath:jarjarjar包hdfshdfshdfs路径

1.14.2 HiveHiveHive的字符串函数

1.14.2.1 substring/substrsubstring/substrsubstring/substr

截取字符串
示例:

SELECT substr('Facebook', 5) FROM src LIMIT 1;
'book'
SELECT substr('Facebook', -5) FROM src LIMIT 1;
'ebook'
SELECT substr('Facebook', 5, 1) FROM src LIMIT 1;
'b'
SELECT substring('Facebook', 5) FROM src LIMIT 1;
'book'
SELECT substring('Facebook', -5) FROM src LIMIT 1;
'ebook'
SELECT substring('Facebook', 5, 1) FROM src LIMIT 1;
'b'

1.14.2.2 coalescecoalescecoalesce

非空查找函数
coalesce(expression,value1,value2……)coalesce(expression,value1,value2……)coalesce(expression,value1,value2……)
coalesce()coalesce()coalesce()函数的第一个参数expressionexpressionexpression为待检测的表达式,而其后的参数个数不定。
coalesce()coalesce()coalesce()函数将会返回包括expressionexpressionexpression在内的所有参数中的第一个非空表达式。
如果expressionexpressionexpression不为空值则返回expressionexpressionexpression;否则判断value1value1value1是否是空值,
如果value1value1value1不为空值则返回value1value1value1;否则判断value2value2value2是否是空值,
如果value2value2value2不为空值则返回value2value2value2;……以此类推,
如果所有的表达式都为空值,则返回NULLNULLNULL。

1.14.2.3 ififif

ififif判断函数
if(expr1,a,b)if(expr1,a,b)if(expr1,a,b)函数的第一个参数是一个表达式,如果满足条件则返回aaa,否则返回bbb。

1.14.2.4 splitsplitsplit

字符串分割
示例

SELECT split('oneAtwoBthreeC', '[ABC]') FROM src LIMIT 1;
["one", "two", "three"]

1.14.2.5 instrinstrinstr

查找字符串
示例

SELECT instr('Facebook', 'boo') FROM src LIMIT 1;
5

1.14.2.6 lowerlowerlower

转换小写
示例

SELECT lower('Facebook') FROM src LIMIT 1;
'facebook'

1.14.2.7 upperupperupper

转换大写
示例

SELECT lower('facebook') FROM src LIMIT 1;
'FACEBOOK'

1.14.2.8 reversereversereverse

反转
示例

SELECT reverse('Facebook') FROM src LIMIT 1;
'koobecaF'

1.14.2.9 regexpregexpregexp_replacereplacereplace

正则替换
示例

SELECT regexp_replace('100-200', '(\d+)', 'num') FROM src LIMIT 1;
'num-num'

1.14.2.10 regexpregexpregexp_extractextractextract

正则表达式解析函数
语法:regexpextract(stringsubject,stringpattern,intindex)regexp_extract(string subject,string pattern,int index)regexpe​xtract(stringsubject,stringpattern,intindex)
返回值:stringstringstring
说明:将字符串subjectsubjectsubject按照patternpatternpattern正则表达式的规则拆分,返回indexindexindex指定的字符。

  • 第一参数:要处理的字段
  • 第二参数: 需要匹配的正则表达式
  • 第三个参数:
    • 0是显示与之匹配的整个字符串
    • 1 是显示第一个括号里面的
    • 2 是显示第二个括号里面的字段…
      示例
SELECT regexp_extract('100-200', '(\d+)-(\d+)', 1) FROM src LIMIT 1;
'100'

1.14.2.11 concat/concatconcat/concatconcat/concat_wswsws

字符串拼接
示例

SELECT concat('abc', 'def') FROM src LIMIT 1;
'abcdef'
SELECT concat_ws('.', 'www', array('facebook', 'com')) FROM src LIMIT 1;
'www.facebook.com'

1.14.2.12 parseparseparse_urlurlurl

语法:parseparseparse_url(str,partToExtract)url(str,partToExtract)url(str,partToExtract) partToExtractpartToExtractpartToExtract的选项包含[HOST,PATH,QUERY,REF,PROTOCOL,FILE,AUTHORITY,USERINFO][HOST,PATH,QUERY,REF,PROTOCOL,FILE,AUTHORITY,USERINFO][HOST,PATH,QUERY,REF,PROTOCOL,FILE,AUTHORITY,USERINFO]

select parse_url(‘http://facebook.com/path/p1.php?query=1’, ‘PROTOCOL’) from dual;
http
select parse_url(‘http://facebook.com/path/p1.php?query=1’, ‘HOST’) from dual;
facebook.com
select parse_url(‘http://facebook.com/path/p1.php?query=1’, ‘REF’) from dual;
空
select parse_url(‘http://facebook.com/path/p1.php?query=1’, ‘PATH’) from dual;
/path/p1.php
select parse_url(‘http://facebook.com/path/p1.php?query=1’, ‘QUERY’) from dual;
空
select parse_url(‘http://facebook.com/path/p1.php?query=1’, ‘FILE’) from dual;
/path/p1.php?query=1
select parse_url(‘http://facebook.com/path/p1.php?query=1’, ‘AUTHORITY’) from dual;
facebook.com
select parse_url(‘http://facebook.com/path/p1.php?query=1’, ‘USERINFO’) from dual;
空

1.14.2.13 parseparseparse_urlurlurl__tupletupletuple

UDTF函数 解析url字符串一般用来解析IP域名等信息

SELECT parse_url_tuple("https://xuexi.boxuegu.com/video.html?courseId=1708","HOST","PATH","QUERY","QUERY:courseId") as(HOST,PATH,QUERY,QUERY_NAME);
+--------------------+--------------+----------------+-------------+--+
|        host        |     path     |     query      | query_name  |
+--------------------+--------------+----------------+-------------+--+
| xuexi.boxuegu.com  | /video.html  | courseId=1708  | 1708        |
+--------------------+--------------+----------------+-------------+--+

1.14.3 HiveHiveHive的日期函数

1.14.3.1 yearyearyear

获取日期格式中的年

SELECT year('2009-07-30') FROM src LIMIT 1;
2009

1.14.3.2 monthmonthmonth

获取日期格式中的月

SELECT month('2009-07-30') FROM src LIMIT 1;
7

1.14.3.3 daydayday

获取日期格式中的天

SELECT day('2009-07-30') FROM src LIMIT 1;
30

1.14.3.4 hourhourhour

获取日期格式中的小时

SELECT hour('2009-07-30 12:58:59') FROM src LIMIT 1;
12
SELECT hour('12:58:59') FROM src LIMIT 1;
12

1.14.3.5 tototo_datedatedate

日期时间转日期函数

SELECT to_date('2009-07-30 04:17:52') FROM src LIMIT 1;
'2009-07-30'

1.14.3.6 minuteminuteminute

日期转分钟函数

SELECT minute('2009-07-30 12:58:59') FROM src LIMIT 1;
58
SELECT minute('12:58:59') FROM src LIMIT 1;
58

1.14.3.7 secondsecondsecond

日期转秒函数

SELECT second('2009-07-30 12:58:59') FROM src LIMIT 1;
59
SELECT second('12:58:59') FROM src LIMIT 1;
59

1.14.3.8 datedatedate_addaddadd

取当前时间后面的时间

SELECT date_add('2009-07-30', 1) FROM src LIMIT 1;
'2009-07-31'

1.14.3.9 datedatedate_subsubsub

取当前时间前面的时间

SELECT date_sub('2009-07-30', 1) FROM src LIMIT 1;
'2009-07-29'

1.14.3.10 unixunixunix_timestamptimestamptimestamp

将标准日期转换为时间戳

select unix_timestamp('2018-12-05 01:10:00','yyyy-MM-dd HH:mm:ss');
+-------------+--+
|     _c0     |
+-------------+--+
| 1543943400  |
+-------------+--+
select unix_timestamp('2018-12-05','yyyy-MM-dd');
+-------------+--+
|     _c0     |
+-------------+--+
| 1543939200  |
+-------------+--+

1.14.3.11 fromfromfrom_unixtimeunixtimeunixtime

将时间戳转换为标准格式

SELECT from_unixtime(0, 'yyyy-MM-dd HH:mm:ss')
'1970-01-01 00:00:00'

1.14.3.12 datediffdatediffdatediff

日期比较函数

SELECT datediff('2009-07-28', '2009-07-29')
-1
SELECT datediff('2009-07-30', '2009-07-29')、
1

1.14.3.13 weekofyearweekofyearweekofyear

日期转周函数

SELECT weekofyear('2008-02-20') FROM src LIMIT 1;
8
SELECT weekofyear('1980-12-31 12:59:59') FROM src LIMIT 1;
1

1.14.4 laterallaterallateral viewviewview侧视图

一般与splitsplitsplit、explodeexplodeexplode、parseparseparseurlurlurltopletopletople 等UDTFUDTFUDTF函数连用,它可以将一列数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合

--语法:
LATERAL VIEW UDTF(args) AS VIEW_NAME AS COLUMN1,COLUMN2;

1.14.5 explodeexplodeexplode函数

函数类别:UDTFUDTFUDTF
功能:将一个arrayarrayarray或者mapmapmap进行展开,对于arrayarrayarray来说,会将集合的每一个元素作为一行,对于mapmapmap来说,会将每一对keyvaluekeyvaluekeyvalue变为一行,keykeykey为一列,valuevaluevalue为一列。一般情况下与侧视图laterallaterallateral viewviewview连用

--示例ARRAY
CREATE TABLE TB_ARRAY(
NAME STRING,
ID ARRAY<STRING>
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '/t'
COLLECTION ITEMS TERMINATED BY ',';SELECT * FROM TB_ARRAY;
+----------------+-------------------------+--+
| tb_array.name  |       tb_array.id       |
+----------------+-------------------------+--+
| zhangsan       | ["1","2","3","4","5"]   |
| lisi           | ["6","7","8","9","10"]  |
+----------------+-------------------------+--+
SELECT EXPLODE(ID) FROM TB_ARRAY;
+------+--+
| col  |
+------+--+
| 1    |
| 2    |
| 3    |
| 4    |
| 5    |
| 6    |
| 7    |
| 8    |
| 9    |
| 10   |
+------+--+
SELECT A.NAME,B.ID FROM TB_ARRAY A LATERAL VIEW EXPLODE(ID) B AS ID;
+-----------+-------+--+
|  a.name   | b.id  |
+-----------+-------+--+
| zhangsan  | 1     |
| zhangsan  | 2     |
| zhangsan  | 3     |
| zhangsan  | 4     |
| zhangsan  | 5     |
| lisi      | 6     |
| lisi      | 7     |
| lisi      | 8     |
| lisi      | 9     |
| lisi      | 10    |
+-----------+-------+--+
--示例Map
CREATE TABLE TB_MAP(
ID STRING,
HOBBY MAP<STRING,STRING>
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY '-'
MAP KEYS TERMINATED BY ':';SELECT * FROM TB_MAP;
+------------+----------------------------------------+--+
| tb_map.id  |              tb_map.hobby              |
+------------+----------------------------------------+--+
| 1          | {"唱歌":"非常喜欢","跳舞":"不喜欢","打游戏":"非常喜欢"}  |
| 2          | {"游泳":"非常喜欢","跳绳":"不喜欢"}               |
+------------+----------------------------------------+--+
SELECT EXPLODE(HOBBY) FORM TB_MAP;
+------+--------+--+
| key  | value  |
+------+--------+--+
| 唱歌   | 非常喜欢   |
| 跳舞   | 不喜欢    |
| 打游戏  | 非常喜欢   |
| 游泳   | 非常喜欢   |
| 跳绳   | 不喜欢    |
+------+--------+--+
SELECT A.ID,B.* FROM TB_MAP A LATERAL VIEW EXPLODE(HOBBY) B AS KEY,VALUE;
+-------+--------+----------+--+
| a.id  | b.key  | b.value  |
+-------+--------+----------+--+
| 1     | 唱歌     | 非常喜欢     |
| 1     | 跳舞     | 不喜欢      |
| 1     | 打游戏    | 非常喜欢     |
| 2     | 游泳     | 非常喜欢     |
| 2     | 跳绳     | 不喜欢      |
+-------+--------+----------+--+

1.14.6 特殊函数

1.14.6.1 reflectreflectreflect

功能:可以通过实例化对象调用javajavajava类的方法,也可以直接调用JavaJavaJava中静态类的方法
要求:该类的方法必须返回一个基础类型或者HiveHiveHive能识别的序列化类型
用法:reflectreflectreflect(classnameclassnameclassname,methodmethodmethod,argsargsargs)
测试:

select reflect(“java.util.UUID”,“randomUUID”);
select reflect("java.lang.Math","max",3,2);

1.14.6.2 jsonjsonjson处理

joinjoinjoin处理HiveHiveHive中的数据有两种方式

1.14.6.2.1 使用HiveHiveHive中的内置函数对jsonjsonjson进行处理

getgetgetjsonjsonjsonobjectobjectobject:从jsonjsonjson数据中获取jsonjsonjson字段
jsonjsonjson_tupletupletuple:udtfudtfudtf函数,解析jsonjsonjson数据
示例

vim /export/datas/hivedata.json
{"id": 1701439105,"ids": [2154137571,3889177061],"total_number": 493}
{"id": 1701439106,"ids": [2154137571,3889177061],"total_number": 494}create table tb_json_test1(
json string
);
load data local inpath '/export/datas/hivedata.json' into table tb_json_test1;select
get_json_object(t.json,'$.id') as id,
get_json_object(t.json,'$.total_number') as total_number
from
tb_json_test1 t;select
t2.*
from
tb_json_test1 t1
lateral view
json_tuple(t1.json,'id','total_number') t2 as c1,c2;
1.14.6.2.2 通过jsonjsonjson的解析工具类直接加载数据解析
  • 先将jsonjsonjson的解析类jsonjsonjson-serdeserdeserde-1.3.71.3.71.3.7-jarjarjar-withwithwith-dependencies.jardependencies.jardependencies.jar放入HiveHiveHive的libliblib目录下
  • 重新启动HiveHiveHive的服务端才可以生效
create table tb_json_test2 (
id string,
ids array<string>,
total_number int
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
STORED AS TEXTFILE;--注意:表中字段名称必须与json数据中字段名称一致
load data local inpath '/export/datas/hivedata.json' into table tb_json_test2;

1.14.7 窗口函数和分析函数

示例表信息

SELECT * FROM TB_DEPT;
+-------------+---------------+----------------+---------------+--+
| tb_dept.id  | tb_dept.name  | tb_dept.price  | tb_dept.type  |
+-------------+---------------+----------------+---------------+--+
| 7369        | SMITH         | 1000.0         | 20            |
| 7566        | JONES         | 2975.0         | 20            |
| 7698        | BLAK          | 2850.0         | 30            |
| 7782        | CLARK         | 6000.0         | 10            |
| 7788        | SCOTT         | 3000.0         | 20            |
| 7839        | KING          | 5000.0         | 10            |
| 7876        | ADAMS         | 1100.0         | 20            |
| 7900        | JAMES         | 950.0          | 30            |
| 7902        | FORD          | 3000.0         | 20            |
| 7934        | MILLER        | 1300.0         | 10            |
+-------------+---------------+----------------+---------------+--+

1.14.7.1 窗口函数

语法 :

函数名(args) OVER(PARTITION BY  COLUMN ORDER BY  COLUMN DESC)
PARTITION BY :按照某一列进行分区,这一列的值相同的行会放到一起
ORDER BY :分区内部按照某一列进行排序

手动指定窗口

--preceding:往前 例如:数字 preceding
--following:往后 例如:数字 following
--current row :当前行
--unbounded : 起点
--unbounded preceding :表示从前面的起点,分区的第一行
--unbounded following :表示到后面的终点,分区的最后一行rows between 起始位置 and 结束位置
rows between unbounded preceding and current row :从第一行到当前行,做分区也做排序的默认窗口
rows between unbounded preceding and unbounded following :从第一行到最后一行,只做分区不做排序的默认窗口
1.14.7.1.1 位置窗口
1.14.7.1.1.1 FIRSTFIRSTFIRST_VALUEVALUEVALUE

取窗口中第一个值。

SELECT *,
FIRST_VALUE(ID) OVER(PARTITION BY TYPE ORDER BY PRICE DESC) AS ID_ FROM TB_DEPT;
+-------+---------+---------+-------+-------+--+
|  id   |  name   |  price  | type  |  id_  |
+-------+---------+---------+-------+-------+--+
| 7782  | CLARK   | 6000.0  | 10    | 7782  |
| 7839  | KING    | 5000.0  | 10    | 7782  |
| 7934  | MILLER  | 1300.0  | 10    | 7782  |
| 7902  | FORD    | 3000.0  | 20    | 7902  |
| 7788  | SCOTT   | 3000.0  | 20    | 7902  |
| 7566  | JONES   | 2975.0  | 20    | 7902  |
| 7876  | ADAMS   | 1100.0  | 20    | 7902  |
| 7369  | SMITH   | 1000.0  | 20    | 7902  |
| 7698  | BLAK    | 2850.0  | 30    | 7698  |
| 7900  | JAMES   | 950.0   | 30    | 7698  |
+-------+---------+---------+-------+-------+--+
1.14.7.1.1.2 LASTLASTLAST_VALUEVALUEVALUE

取窗口中最后一个值。

--分区又排序的话,默认的窗口大小为开始到当前节点
SELECT *,
LAST_VALUE(ID) OVER(PARTITION BY TYPE ORDER BY PRICE DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS ID_ FROM TB_DEPT;
+-------+---------+---------+-------+-------+--+
|  id   |  name   |  price  | type  |  id_  |
+-------+---------+---------+-------+-------+--+
| 7782  | CLARK   | 6000.0  | 10    | 7934  |
| 7839  | KING    | 5000.0  | 10    | 7934  |
| 7934  | MILLER  | 1300.0  | 10    | 7934  |
| 7902  | FORD    | 3000.0  | 20    | 7369  |
| 7788  | SCOTT   | 3000.0  | 20    | 7369  |
| 7566  | JONES   | 2975.0  | 20    | 7369  |
| 7876  | ADAMS   | 1100.0  | 20    | 7369  |
| 7369  | SMITH   | 1000.0  | 20    | 7369  |
| 7698  | BLAK    | 2850.0  | 30    | 7900  |
| 7900  | JAMES   | 950.0   | 30    | 7900  |
+-------+---------+---------+-------+-------+--+
1.14.7.1.1.3 LEADLEADLEAD

向后偏移,LEADLEADLEAD(COLUMNCOLUMNCOLUMN,偏移量,默认值)。

SELECT *,LEAD(PRICE,1,0) OVER(PARTITION BY TYPE ORDER BY PRICE DESC) AS LEAD_PRICE FROM TB_DEPT;
+-------------+---------------+----------------+---------------+-------------+--+
| tb_dept.id  | tb_dept.name  | tb_dept.price  | tb_dept.type  | lead_price  |
+-------------+---------------+----------------+---------------+-------------+--+
| 7782        | CLARK         | 6000.0         | 10            | 5000.0      |
| 7839        | KING          | 5000.0         | 10            | 1300.0      |
| 7934        | MILLER        | 1300.0         | 10            | 0.0         |
| 7902        | FORD          | 3000.0         | 20            | 3000.0      |
| 7788        | SCOTT         | 3000.0         | 20            | 2975.0      |
| 7566        | JONES         | 2975.0         | 20            | 1100.0      |
| 7876        | ADAMS         | 1100.0         | 20            | 1000.0      |
| 7369        | SMITH         | 1000.0         | 20            | 0.0         |
| 7698        | BLAK          | 2850.0         | 30            | 950.0       |
| 7900        | JAMES         | 950.0          | 30            | 0.0         |
+-------------+---------------+----------------+---------------+-------------+--+
1.14.7.1.1.4 LAGLAGLAG

向前偏移,LAGLAGLAG(COLUMNCOLUMNCOLUMN,偏移量,默认值)。

SELECT * ,LAG(PRICE,1,0) OVER (PARTITION BY TYPE ORDER BY PRICE DESC) AS LAG_PRICE FROM TB_DEPT;
+-------------+---------------+----------------+---------------+------------+--+
| tb_dept.id  | tb_dept.name  | tb_dept.price  | tb_dept.type  | lag_price  |
+-------------+---------------+----------------+---------------+------------+--+
| 7782        | CLARK         | 6000.0         | 10            | 0.0        |
| 7839        | KING          | 5000.0         | 10            | 6000.0     |
| 7934        | MILLER        | 1300.0         | 10            | 5000.0     |
| 7902        | FORD          | 3000.0         | 20            | 0.0        |
| 7788        | SCOTT         | 3000.0         | 20            | 3000.0     |
| 7566        | JONES         | 2975.0         | 20            | 3000.0     |
| 7876        | ADAMS         | 1100.0         | 20            | 2975.0     |
| 7369        | SMITH         | 1000.0         | 20            | 1100.0     |
| 7698        | BLAK          | 2850.0         | 30            | 0.0        |
| 7900        | JAMES         | 950.0          | 30            | 2850.0     |
+-------------+---------------+----------------+---------------+------------+--+
1.14.7.1.2 聚合窗口
1.14.7.1.2.1 MAXMAXMAX

取窗口中的最大值。

SELECT *,MAX(PRICE) OVER (PARTITION BY TYPE ORDER BY PRICE DESC) AS MAX_PRICE FROM TB_DEPT;
+-------------+---------------+----------------+---------------+------------+--+
| tb_dept.id  | tb_dept.name  | tb_dept.price  | tb_dept.type  | max_price  |
+-------------+---------------+----------------+---------------+------------+--+
| 7782        | CLARK         | 6000.0         | 10            | 6000.0     |
| 7839        | KING          | 5000.0         | 10            | 6000.0     |
| 7934        | MILLER        | 1300.0         | 10            | 6000.0     |
| 7902        | FORD          | 3000.0         | 20            | 3000.0     |
| 7788        | SCOTT         | 3000.0         | 20            | 3000.0     |
| 7566        | JONES         | 2975.0         | 20            | 3000.0     |
| 7876        | ADAMS         | 1100.0         | 20            | 3000.0     |
| 7369        | SMITH         | 1000.0         | 20            | 3000.0     |
| 7698        | BLAK          | 2850.0         | 30            | 2850.0     |
| 7900        | JAMES         | 950.0          | 30            | 2850.0     |
+-------------+---------------+----------------+---------------+------------+--+
1.14.7.1.2.2 MINMINMIN

取窗口中的最小值。

SELECT *,MIN(PRICE) OVER (PARTITION BY TYPE ORDER BY PRICE ASC) AS MIN_PRICE FROM TB_DEPT;
+-------------+---------------+----------------+---------------+------------+--+
| tb_dept.id  | tb_dept.name  | tb_dept.price  | tb_dept.type  | min_price  |
+-------------+---------------+----------------+---------------+------------+--+
| 7934        | MILLER        | 1300.0         | 10            | 1300.0     |
| 7839        | KING          | 5000.0         | 10            | 1300.0     |
| 7782        | CLARK         | 6000.0         | 10            | 1300.0     |
| 7369        | SMITH         | 1000.0         | 20            | 1000.0     |
| 7876        | ADAMS         | 1100.0         | 20            | 1000.0     |
| 7566        | JONES         | 2975.0         | 20            | 1000.0     |
| 7902        | FORD          | 3000.0         | 20            | 1000.0     |
| 7788        | SCOTT         | 3000.0         | 20            | 1000.0     |
| 7900        | JAMES         | 950.0          | 30            | 950.0      |
| 7698        | BLAK          | 2850.0         | 30            | 950.0      |
+-------------+---------------+----------------+---------------+------------+--+
1.14.7.1.2.3 SUMSUMSUM

取窗口中的数据总和。

SELECT *,SUM(PRICE) OVER (PARTITION BY TYPE ORDER BY PRICE ASC) AS MIN_PRICE FROM TB_DEPT;
+-------------+---------------+----------------+---------------+------------+--+
| tb_dept.id  | tb_dept.name  | tb_dept.price  | tb_dept.type  | min_price  |
+-------------+---------------+----------------+---------------+------------+--+
| 7934        | MILLER        | 1300.0         | 10            | 1300.0     |
| 7839        | KING          | 5000.0         | 10            | 6300.0     |
| 7782        | CLARK         | 6000.0         | 10            | 12300.0    |
| 7369        | SMITH         | 1000.0         | 20            | 1000.0     |
| 7876        | ADAMS         | 1100.0         | 20            | 2100.0     |
| 7566        | JONES         | 2975.0         | 20            | 5075.0     |
| 7902        | FORD          | 3000.0         | 20            | 11075.0    |
| 7788        | SCOTT         | 3000.0         | 20            | 11075.0    |
| 7900        | JAMES         | 950.0          | 30            | 950.0      |
| 7698        | BLAK          | 2850.0         | 30            | 3800.0     |
+-------------+---------------+----------------+---------------+------------+--+
1.14.7.1.2.4 COUNTCOUNTCOUNT

求窗口中的数据条数。

SELECT *,COUNT(PRICE) OVER (PARTITION BY TYPE ORDER BY PRICE ASC) AS MIN_PRICE FROM TB_DEPT;
+-------------+---------------+----------------+---------------+------------+--+
| tb_dept.id  | tb_dept.name  | tb_dept.price  | tb_dept.type  | min_price  |
+-------------+---------------+----------------+---------------+------------+--+
| 7934        | MILLER        | 1300.0         | 10            | 1          |
| 7839        | KING          | 5000.0         | 10            | 2          |
| 7782        | CLARK         | 6000.0         | 10            | 3          |
| 7369        | SMITH         | 1000.0         | 20            | 1          |
| 7876        | ADAMS         | 1100.0         | 20            | 2          |
| 7566        | JONES         | 2975.0         | 20            | 3          |
| 7902        | FORD          | 3000.0         | 20            | 5          |
| 7788        | SCOTT         | 3000.0         | 20            | 5          |
| 7900        | JAMES         | 950.0          | 30            | 1          |
| 7698        | BLAK          | 2850.0         | 30            | 2          |
+-------------+---------------+----------------+---------------+------------+--+
1.14.7.1.2.5 AVGAVGAVG

求窗口中的平均值。

SELECT *,AVG(PRICE) OVER (PARTITION BY TYPE ORDER BY PRICE ASC) AS MIN_PRICE FROM TB_DEPT;
+-------------+---------------+----------------+---------------+---------------------+--+
| tb_dept.id  | tb_dept.name  | tb_dept.price  | tb_dept.type  |      min_price      |
+-------------+---------------+----------------+---------------+---------------------+--+
| 7934        | MILLER        | 1300.0         | 10            | 1300.0              |
| 7839        | KING          | 5000.0         | 10            | 3150.0              |
| 7782        | CLARK         | 6000.0         | 10            | 4100.0              |
| 7369        | SMITH         | 1000.0         | 20            | 1000.0              |
| 7876        | ADAMS         | 1100.0         | 20            | 1050.0              |
| 7566        | JONES         | 2975.0         | 20            | 1691.6666666666667  |
| 7902        | FORD          | 3000.0         | 20            | 2215.0              |
| 7788        | SCOTT         | 3000.0         | 20            | 2215.0              |
| 7900        | JAMES         | 950.0          | 30            | 950.0               |
| 7698        | BLAK          | 2850.0         | 30            | 1900.0              |
+-------------+---------------+----------------+---------------+---------------------+--+

1.14.7.2 分析函数

语法

函数名() OVER(PARTITION BY COLUMN ORDER BY COLUMN)
1.14.7.2.1 ROWROWROW_NUMBERNUMBERNUMBER

给每个分区内部编号

SELECT * ,ROW_NUMBER() OVER(PARTITION BY TYPE ORDER BY PRICE DESC) AS CN FROM TB_DEPT;
+-------------+---------------+----------------+---------------+-----+--+
| tb_dept.id  | tb_dept.name  | tb_dept.price  | tb_dept.type  | cn  |
+-------------+---------------+----------------+---------------+-----+--+
| 7782        | CLARK         | 6000.0         | 10            | 1   |
| 7839        | KING          | 5000.0         | 10            | 2   |
| 7934        | MILLER        | 1300.0         | 10            | 3   |
| 7902        | FORD          | 3000.0         | 20            | 1   |
| 7788        | SCOTT         | 3000.0         | 20            | 2   |
| 7566        | JONES         | 2975.0         | 20            | 3   |
| 7876        | ADAMS         | 1100.0         | 20            | 4   |
| 7369        | SMITH         | 1000.0         | 20            | 5   |
| 7698        | BLAK          | 2850.0         | 30            | 1   |
| 7900        | JAMES         | 950.0          | 30            | 2   |
+-------------+---------------+----------------+---------------+-----+--+
1.14.7.2.2 RANKRANKRANK

用于实现分区内排名编号[会留空位]

SELECT * ,RANK() OVER(PARTITION BY TYPE ORDER BY PRICE DESC) AS CN FROM TB_DEPT;
+-------------+---------------+----------------+---------------+-----+--+
| tb_dept.id  | tb_dept.name  | tb_dept.price  | tb_dept.type  | cn  |
+-------------+---------------+----------------+---------------+-----+--+
| 7782        | CLARK         | 6000.0         | 10            | 1   |
| 7839        | KING          | 5000.0         | 10            | 2   |
| 7934        | MILLER        | 1300.0         | 10            | 3   |
| 7902        | FORD          | 3000.0         | 20            | 1   |
| 7788        | SCOTT         | 3000.0         | 20            | 1   |
| 7566        | JONES         | 2975.0         | 20            | 3   |
| 7876        | ADAMS         | 1100.0         | 20            | 4   |
| 7369        | SMITH         | 1000.0         | 20            | 5   |
| 7698        | BLAK          | 2850.0         | 30            | 1   |
| 7900        | JAMES         | 950.0          | 30            | 2   |
+-------------+---------------+----------------+---------------+-----+--+
1.14.7.2.3 DENSEDENSEDENSE_RANKRANKRANK

用于实现分区内排名编号[不留空位]

SELECT * ,DENSE_RANK() OVER(PARTITION BY TYPE ORDER BY PRICE DESC) AS CN FROM TB_DEPT;
+-------------+---------------+----------------+---------------+-----+--+
| tb_dept.id  | tb_dept.name  | tb_dept.price  | tb_dept.type  | cn  |
+-------------+---------------+----------------+---------------+-----+--+
| 7782        | CLARK         | 6000.0         | 10            | 1   |
| 7839        | KING          | 5000.0         | 10            | 2   |
| 7934        | MILLER        | 1300.0         | 10            | 3   |
| 7902        | FORD          | 3000.0         | 20            | 1   |
| 7788        | SCOTT         | 3000.0         | 20            | 1   |
| 7566        | JONES         | 2975.0         | 20            | 2   |
| 7876        | ADAMS         | 1100.0         | 20            | 3   |
| 7369        | SMITH         | 1000.0         | 20            | 4   |
| 7698        | BLAK          | 2850.0         | 30            | 1   |
| 7900        | JAMES         | 950.0          | 30            | 2   |
+-------------+---------------+----------------+---------------+-----+--+
1.14.7.2.4 ROWROWROWNUMBERNUMBERNUMBER,RANKRANKRANK以及DENSEDENSEDENSE_RANKRANKRANK的区别
  • 这三个分析函数都是实现分区内排名编号
  • ROWROWROW_NUMBERNUMBERNUMBER:给每个分区排序,如果排序的数据重复,源数据从后往前排列排序
  • RANKRANKRANK:给每个分区排序,如果排序的数据重复,则重复的数据的排名一样并且留有空位
  • DENSEDENSEDENSE_RANKRANKRANK:给每个分区排序,如果排序的数据重复,则重复的数据的排名一样并且不留空位
1.14.7.2.5 NTILENTILENTILE :对分区内部再次进行均分,通常用作求数据的百分比,百分率等。
SELECT * ,NTILE(2) OVER(PARTITION BY TYPE ORDER BY PRICE DESC) AS CN FROM TB_DEPT;
+-------------+---------------+----------------+---------------+-----+--+
| tb_dept.id  | tb_dept.name  | tb_dept.price  | tb_dept.type  | cn  |
+-------------+---------------+----------------+---------------+-----+--+
| 7782        | CLARK         | 6000.0         | 10            | 1   |
| 7839        | KING          | 5000.0         | 10            | 1   |
| 7934        | MILLER        | 1300.0         | 10            | 2   |
| 7902        | FORD          | 3000.0         | 20            | 1   |
| 7788        | SCOTT         | 3000.0         | 20            | 1   |
| 7566        | JONES         | 2975.0         | 20            | 1   |
| 7876        | ADAMS         | 1100.0         | 20            | 2   |
| 7369        | SMITH         | 1000.0         | 20            | 2   |
| 7698        | BLAK          | 2850.0         | 30            | 1   |
| 7900        | JAMES         | 950.0          | 30            | 2   |
+-------------+---------------+----------------+---------------+-----+--+

1.14.8 CASE WHEN 用法

1.14.8.1 第一种用法

CASE COLUMN
WHEN VALUE1 THEN RS1
WHEN VALUE2 THEN RS2
WHEN VALUE3 THEN RS3
ELSE REN
END

1.14.8.2 第二种用法

CASE
WHEN COLUMN=VALUE THEN RS1
WHEN COLUMN=VALUE2 THEN RS2
WHEN COLUMN=VALUE3 THEN RS3
ELSE RSN
END

1.14.9 行列转换

1.14.9.1 行转列

1.14.9.1.1 多行转多列

示例

CREATE TABLE ROW2TOCOL2(
COLUMN1 STRING,
COLUMN2 STRING,
COLUMN3 INT
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'SELECT * FROM ROW2TOCOL2;
+---------------------+---------------------+---------------------+--+
| row2tocol2.column1  | row2tocol2.column2  | row2tocol2.column3  |
+---------------------+---------------------+---------------------+--+
| a                   | c                   | 1                   |
| a                   | d                   | 2                   |
| a                   | e                   | 3                   |
| b                   | c                   | 4                   |
| b                   | d                   | 5                   |
| b                   | e                   | 6                   |
+---------------------+---------------------+---------------------+--+
SELECT COLUMN1,
MAX(CASE COLUMN2 WHEN 'c' THEN COLUMN3 ELSE 0 END) AS C,
MAX(CASE COLUMN2 WHEN 'd' THEN COLUMN3 ELSE 0 END) AS D,
MAX(CASE COLUMN2 WHEN 'e' THEN COLUMN3 ELSE 0 END) AS E
FROM ROW2TOCOL2 GROUP BY COLUMN1;
+----------+----+----+----+--+
| column1  | c  | d  | e  |
+----------+----+----+----+--+
| a        | 1  | 2  | 3  |
| b        | 4  | 5  | 6  |
+----------+----+----+----+--+
1.14.9.1.2 多行转单列

示例

CREATE TABLE ROW2TOCOL(
COLUMN1 STRING,
COLUMN2 STRING,
COLUMN3 INT
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'SELECT * FROM ROW2TOCOL;
+--------------------+--------------------+--------------------+--+
| row2tocol.column1  | row2tocol.column2  | row2tocol.column3  |
+--------------------+--------------------+--------------------+--+
| a                  | b                  | 1                  |
| a                  | b                  | 2                  |
| a                  | b                  | 3                  |
| c                  | d                  | 4                  |
| c                  | d                  | 5                  |
| c                  | d                  | 6                  |
+--------------------+--------------------+--------------------+--+SELECT COLUMN1, COLUMN2,
CONCAT_WS(',', COLLECT_SET(CAST(COLUMN3 AS STRING))) AS COLUMN3 FROM
ROW2TOCOL GROUP BY COLUMN1, COLUMN2;
+----------+----------+----------+--+
| column1  | column2  | column3  |
+----------+----------+----------+--+
| a        | b        | 1,2,3    |
| c        | d        | 4,5,6    |
+----------+----------+----------+--+
--COLLECT_SET :将某一列的所有元素放在一个不重复的数组中
--COLLECT_LIST :将某一列的所有元素放在一个可重复的数组中
--CONCAT :不能指定结果中每个元素的分隔符,只要有一个元素为null,结果就是null
--CONCAT_WS('分隔符',str...):可以指定结果中每个元素的分隔符,只要有一个元素不为null,结果就不为null

1.14.9.2 列转行

1.14.9.2.1 多列转多行

示例

CREATE TABLE COL2TOROW2(
COLUMN1 STRING,
COLUMN2 STRING,
COLUMN3 STRING,
COLUMN4 STRING
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'SELECT * FROM COL2TOROW2;
+---------------------+---------------------+---------------------+---------------------+--+
| col2torow2.column1  | col2torow2.column2  | col2torow2.column3  | col2torow2.column4  |
+---------------------+---------------------+---------------------+---------------------+--+
| a                   | 1                   | 2                   | 3                   |
| b                   | 4                   | 5                   | 6                   |
+---------------------+---------------------+---------------------+---------------------+--+
SELECT COLUMN1, 'c' as COLUMN2, COLUMN2 as COLUMN3 from COL2TOROW2
UNION ALL
SELECT COLUMN1, 'd' as COLUMN2, COLUMN3 as COLUMN3 from COL2TOROW2
UNION ALL
SELECT COLUMN1, 'e' as COLUMN2, COLUMN4 as COLUMN3 from COL2TOROW2;
+--------------+--------------+--------------+--+
| _u1.column1  | _u1.column2  | _u1.column3  |
+--------------+--------------+--------------+--+
| a            | c            | 1            |
| a            | d            | 2            |
| a            | e            | 3            |
| b            | c            | 4            |
| b            | d            | 5            |
| b            | e            | 6            |
+--------------+--------------+--------------+--+
UNION:实现SQL语句行的拼接
UNION :要求字段个数是一致的
UNION ALL:要求字段个数和类型都是一致的
1.14.9.2.2 单列转多行

示例

CREATE TABLE COL1TOROW2(
A STRING,
B STRING,
C STRING
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'SELECT * FROM COL1TOROW2;
+---------------+---------------+---------------+--+
| col1torow2.a  | col1torow2.b  | col1torow2.c  |
+---------------+---------------+---------------+--+
| a             | b             | 1,2,3         |
| c             | d             | 4,5,6         |
+---------------+---------------+---------------+--+
SELECT A.a,A.b,B.c FROM COL1TOROW2 A LATERAL VIEW EXPLODE(SPLIT(A.c,",")) B AS c
+------+------+------+--+
| a.a  | a.b  | b.c  |
+------+------+------+--+
| a    | b    | 1    |
| a    | b    | 2    |
| a    | b    | 3    |
| c    | d    | 4    |
| c    | d    | 5    |
| c    | d    | 6    |
+------+------+------+--+

1.15 HiveHiveHive的调优

1.15.1 fetchfetchfetch tasktasktask

<!--有的SQL不走Mapreduce,不走Mapreduce的SQL走了fetch.task,更快。这个由如下的参数决定-->
<property>
<name>hive.fetch.task.conversion</name>
<value>minimal</value>
</property>
<!--value的值有两个,1.minimal:select *和对分区表的分区过滤不走Mapreduce
2.more :简单的select[不包含聚合、分组、排序等等]、字段过滤、limit都不走Mapreduce
在工作中建议改为more
-->

1.15.2 严格模式

<property>
<name>hive.mapred.mode</name>
<value>nonstrict</value><!--非严格模式-->
<value>strict</value><!--严格模式-->
</property>
  • 默认为非严格模式,在工作中要设定为严格模式
  • 严格模式可以避免一些程序的故障,更加严格代码规范
    • 笛卡尔积:joinjoinjoin时不指定关联字段会产生笛卡尔积
    • 在分区表进行查询时不指定分区过滤
    • 讲bigintbigintbigint类型与字符串或者doubledoubledouble类型进行比较
    • 如果做了全局排序不使用limitlimitlimit进行输出

1.15.3 本地模式

<!--- 如果一个SQL语句处理的数据量不是很大,不需要提交给yarn取运行,直接在当前机器上完成计算-->
<property>
<name>hive.exec.mode.local.auto</name>
<value>false</value><!--不开启-->
<value>true</value><!--开启-->
</property>
  • 当程序开启了本地模式,以下情况就不会提交给yarn去运行,直接在本地做计算

    • 处理的数据不超过128M128M128M
    • 该SQLSQLSQL对应的MapTaskMapTaskMapTask不超过4个
    • 该SQLSQLSQL对应的ReduceTaskReduceTaskReduceTask不超过1个

1.15.4 JVMJVMJVM重用

<!--当我们执行一个Mapreduce程序的时候,每一个Task进程都会启动一个JVM,当进程执行完毕,JVM销毁
可以通过设置这个参数,来达到JVM重用的特性,例如value修改为10,则表示10个Task在一个JVM中运行,当运行结束后,
JVM进行销毁-->
<property>
<name>mapreduce.job.jvm.numtasks</name>
<value>10</value>
</property>

1.15.5 推测执行

<!--推测执行:当程序运行Task任务时,如果某个任务一直没有运行,其他Task都在等待这个Task,如果开启了推测执行的话,程序会在启动一个Task运行这个任务,这两个Task那个先完成任务另外一个会被kill掉--><!--开启mapTask的推测执行-->
<property>
<name>mapreduce.map.speculative</name>
<value>true</value>
</property><!--开启reduceTask的推测执行-->
<property>
<name>mapreduce.reduce.speculative</name>
<value>true</value>
</property>
  • 不建议一定开启

    • 如果因为环境问题导致的故障,环境问题一直存储,每次产生的新的tasktasktask最终都会失败
    • 最终导致多个tasktasktask全部阻塞

1.15.6 压缩

1.15.6.1 优点

  • 减少存储磁盘空间,降低单节点的磁盘IOIOIO。
  • 由于压缩后的数据占用的带宽更少,因此可以加快数据在HadoopHadoopHadoop集群流动
    的速度,减少网络传输带宽

1.15.6.2 缺点

  • 需要花费额外的时间用CPUCPUCPU做压缩和解压缩计算。

1.15.6.3 压缩分析

  • 数据在进入MapTaskMapTaskMapTask任务前可以进行压缩,然后进行解压处理
  • 数据在MapTaskMapTaskMapTask任务处理完成后的输出可以压缩,这样可以节省网络I/OI/OI/O,因为ReduceTaskReduceTaskReduceTask通常和MapTaskMapTaskMapTask不在一个机器上。
  • 数据在ReduceTaskReduceTaskReduceTask中处理完后可以进行压缩存储在HDFSHDFSHDFS上,可以降低磁盘占用量。

1.15.6.4 压缩设置

<!--hive中的压缩就是Mapreduce中的压缩,所以先在mapred-site.xml文件中配置Mapreduce的压缩-->
<!-- 配置Mapreduce的Map端压缩以及压缩算法-->
<property>
<name>mapreduce.map.output.compress</name>
<value>true</value>
</property>
<property>
<name>mapreduce.map.output.compress.codec</name>
<value>org.apache.hadoop.io.compress.SnappyCodec</value>
</property>
<!--然后再hive中配置中间结果压缩-->
<property>
<name>hive.exec.compress.intermediate</name>
<value>true</value>
</property>
<!--配置Hive最终输出数据压缩功能-->
<property>
<name>hive.exec.compress.output</name>
<value>true</value>
</property>
<!-- 配置Mapreduce的Reudce端压缩以及压缩算法-->
<property>
<name>mapreduce.output.fileoutputformat.compress</name>
<value>true</value>
</property>
<property>
<name>mapreduce.output.fileoutputformat.compress.codec</name>
<value>org.apache.hadoop.io.compress.SnappyCodec</value>
</property>
<!--设置Mapreduce最终数据输出压缩为块压缩-->
<property>
<name>mapreduce.output.fileoutputformat.compress.type</name>
<value>BLOCK</value>
</property>

1.15.7 MapMapMap端聚合

<!--就是Mapreduce底层的Map端的Combiner-->
<property>
<name>hive.map.aggr</name>
<value>true</value><!--默认为true-->
</property>
<property>
<name>hive.groupby.mapaggr.checkinterval</name><!--在底层的Mapreduce程序执行时会开启Combiner-->
<value>100000</value><!--在Map端进行聚合操作的条目数目-->
</property>

1.15.8 并行计算

<!--hive执行SQL默认使用的是顺序执行,可以开启并行计算来执行SQL语句-->
<property>
<name>hive.exec.parallel</name>
<value>true</value>
</property>
<property>
<name>hive.exec.parallel.thread.number</name>
<value>true</value><!--代表一次SQL计算中最大允许执行的Job个数-->
</property>

1.15.9 SQLSQLSQL优化

1.15.9.1 分区裁剪

  • 如果做了分区表,在对表进行分析处理时,尽量加上分区字段的过滤
  • 先过滤,后处理

1.15.9.2 列裁剪

  • 如果处理数据时,先将不需要用到的列过滤掉,然后再处理
  • 先过滤,后处理

1.15.9.3 count(distinct)count(distinct)count(distinct)

  • 在countcountcount时,如果结果需要做去重,一定先distinctdistinctdistinct,然后再聚合
  • 先过滤,后处理,不然会导致数据倾斜
  • distinctdistinctdistinct在hivehivehive的底层就是分组

1.15.9.4 表优化

  • 分区表:尽量根据业务需求将表作分区表,方便以后对分区数据进行处理
  • 分桶表:如果后期的需求中,会出现大数据的joinjoinjoin,推荐创建分桶表
  • 表的数据存储

1.15.10 数据存储格式

创建表的时候,表的存储格式分为好多种,以下为常用的存储类型

  • TEXTFILETEXTFILETEXTFILE :行式存储,默认表的存储格式,普通的文本类型,不支持块压缩,磁盘开销大。
  • RCFILERCFILERCFILE: RCFileRCFileRCFile是一种行列存储相结合的存储方式
  • ORCORCORC:数据按行分块 每块按照列存储 ,压缩快 快速列存取,效率比rcfilercfilercfile高,是rcfilercfilercfile的改良版本
  • PARQUETPARQUETPARQUET:能够很好的压缩,有很好的查询性能,支持有限的模式演进。但是写速度通常比较慢。这中文件格式主要是用在ImpalaImpalaImpala上面的。

注意:PARQUETPARQUETPARQUET数据存储类型可以和文件压缩一块使用 parquet+snappyparquet+snappyparquet+snappy
ORCORCORC一般不建议和文件压缩一块使用,组合使用可能更耗时间,单独的ORCORCORC存储格式已经有很高的压缩比了

1.15.10.1 行式存储

1.15.10.1.1 优点
  • 相关的数据是保存在一起,比较符合面向对象的思维,因为一行数据就是一条记录
  • 这种存储格式比较方便进行INSERTINSERTINSERT/UPDATEUPDATEUPDATE操作
1.15.10.1.2 缺点
  • 如果查询只涉及某几个列,它会把整行数据都读取出来,不能跳过不必要的列读取。当然数据比较少,一般没啥问题,如果数据量比较大就比较影响性能
  • 由于每一行中,列的数据类型不一致,导致不容易获得一个极高的压缩比,也就是空间利用率不高
  • 不是所有的列都适合作为索引

1.15.10.2 列式存储

1.15.10.2.1 优点
  • 查询时,只有涉及到的列才会被查询,不会把所有列都查询出来,即可以跳过不必要的列查询
  • 高效的压缩率,不仅节省储存空间也节省计算内存和CPUCPUCPU
  • 任何列都可以作为索引
1.15.10.2.2缺点
  • INSERTINSERTINSERT/UPDATEUPDATEUPDATE很麻烦或者不方便
  • 不适合扫描小量的数据

1.15.11 数据倾斜

只要是涉及到分布式计算,都存在数据倾斜的问题。在分布式计算中,将大的任务拆分为多个小的任务,但是由于拆分的规则,任务分配不平衡,这就会产生数据倾斜,产生的原因有两种,一种数据本身就是倾斜的,另一种为由于分配规则不适合导致的数据倾斜。以下列出常用的解决方案

1.15.11.1 MapreduceMapreduceMapreduce的解决方案

  • 开启MapMapMap端的聚合CombinerCombinerCombiner
  • 弃用系统默认的hashhashhash规则,改用随机分区或者其他的分区规则。
  • 如果数据本身就是倾斜的,可以通过添加随机数来将数据转换为不是倾斜的数据。

1.15.11.2 HiveHiveHive的解决方案

  • 如果是joinjoinjoin产生的数据倾斜,可以使用MapJoinMapJoinMapJoin,强制数据量小的一方为小表。尽量先去重,做数据裁剪,对joinjoinjoin的字段去重后再joinjoinjoin。将不会被joinjoinjoin上的数据先过滤,再进行joinjoinjoin。
  • 使用参数优化进行MapMapMap端的CombinerCombinerCombiner
  • 使用参数进行负载均衡
  • 调整MapTaskMapTaskMapTask和ReduceTaskReduceTaskReduceTask的个数
<!--当选项设定为true,生成的查询计划会有两个MRJob。第一个MRJob会进行随机分区,进行第一次聚合,第二个MRJob会进行hash分区,做整体聚合-->
<property>
<name>hive.groupby.skewindata</name>
<value>true</value>
</property>

1.16 数仓设计

1.16.1 数据仓库

数据仓库是一个更加集成的、统一化的面向主题的数据存储模型。本身自己不产生数据,也不消费数据。只存储数据,数据是随着时间变化的,只有增量,不产生更新、删除等操作。数据仓库的目标为实现整个公司所有数据的统一化,标准化的数据管理、数据共享。

1.16.1.1 数据仓库的特点

  • 面向主题:整个数据仓库中的数据有多少种应用,就有多少种主题。只要确定数据仓库种的数据和主题的关系即可。
  • 集成化的:所有数据源的数据全部进入数据仓库中,
  • 时变的:数据会不断增加,常见的是T+1T+1T+1模式,每天导入昨天的数据进入数据仓库。
    • 只导入增量的数据,数据不会更新,如果数据更新了,增量导入更新的数据。
  • 非易失的:数据仓库中的数据一般只进行增量更新。
  • 数据表的分类
    • 增量表:只有每天增量的数据,以后每一次导入都是增量导入
    • 全量表:全量导入的数据,第一次导入都是全量导入
    • 拉链表:保存所有的历史数据,查询时可以根据条件只查询最新的数据。

1.16.1.2 数据仓库和数据库的区别

  • 数据库:面向单一业务的,OLTPOLTPOLTP联机事务处理,设计主要体现在功能型,性能的衡量。
  • 数据仓库:面向主题的,OLAPOLAPOLAP联机分析处理,主要实现复杂的分析,主要用于运营决策。

1.16.2 分层设计

所有不同的数据源数据进入数据仓库,经过统一的数据转换,得到最终想要的数据。

1.16.2.1 常见的分层架构图

1.16.2.2 分层实现

1.16.2.2.1 ODSODSODS层

操作数据层

  • 所有的不同数据源的数据在经过预处理以后,入库的 第一层就是ODSODSODS层
  • 最原始的数据,只经过了简单的ETLETLETL处理,变成了结构化的数据
  • 原始表:将 原始数据文件经过了一些简单的过滤得到了一张表结构的数据
  • 设计表或者库名称一般以odsodsods_开头
1.16.2.2.2 DWDDWDDWD层

详细数据层

  • 将ODSODSODS层的数据进一步的转化,实现转换、补全构建宽表
  • 补全一些维度的字段:时间维度,地域维度
  • 设计表或者库名称一般以dwddwddwd_开头
1.16.2.2.3 DWS/DMDWS/DMDWS/DM层

汇总数据层/数据集市【一个主题的数据表】

  • 将DWDDWDDWD层中构建的宽表,根据每个主题中的业务拆分不同的分析模型
  • 后期在主题中实现分析应用
  • 从DWDDWDDWD层的宽表中提取各个分析需要用到的字段构建分析模型表
  • 设计表或者库名称一般以dwsdwsdws_ / dmdmdm_开头
1.16.2.2.4 APP/ADS层

数据应用层

  • 在DM/DWSDM/DWSDM/DWS中实现应用得到结果表
  • 设计表或者库名称一般以adsadsads_ / appappapp_开头
1.16.2.2.5 常见的一些辅助层
  • DIMDIMDIM:维度层:存储维度表
  • TMPTMPTMP:临时层:存放临时表

1.16.3 建模设计

解决数据库和表到底如何进行设计,采用什么样的建模模型。
####1.16.3.1 ERERER模型
关系实体模型【传统的网站或者基于数据库的设计一般都用ER模型】
####1.16.3.2 维度模型
基于不同维度来描述一件事情,大数据分析主要使用的建模模型,通过不同维度来看待一件事情的好坏。每一个维度就是一张表,例如时间维度、地域维度、平台维度、终端维度、板块维度、来源维度等等,维度模型中常见的设计模式有:

1.16.3.2.1 雪花模型

子维度通过外键关联父维度

1.16.3.2.1.1 结构

1.16.3.2.1.2 存在的问题

如果想描述一个事实,维度中引用了多级外键,在数据检索时非常的慢,需要逐级检索

1.16.3.2.2 星型模型

所有的维度直接关联事实表,不存在子维度关联父维度【比较常用】子维度通过外键关联父维度

1.16.3.2.2.1 结构

1.16.3.2.2.2 特点

数据存储时允许亢余,用空间换时间。

1.16.3.2.3 星座模型

基于星型模型中的多个事实表可以共用相同的维度表

1.16.3.2.3.1 结构

1.17 HiveHiveHive的mavenmavenmaven相关依赖

  <properties><hadoop.version>2.6.0-cdh5.14.0</hadoop.version><mysql.version>5.1.38</mysql.version><hive.version>1.1.0-cdh5.14.0</hive.version></properties><dependencies><!-- Hadoop Client 依赖 --><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>${hadoop.version}</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-client</artifactId><version>${hadoop.version}</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-hdfs</artifactId><version>${hadoop.version}</version></dependency><!-- MySQL Client 依赖 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><!-- Hive依赖 --><dependency><groupId>org.apache.hive</groupId><artifactId>hive-exec</artifactId><version>${hive.version}</version></dependency><dependency><groupId>org.apache.hive</groupId><artifactId>hive-common</artifactId><version>${hive.version}</version></dependency><dependency><groupId>org.apache.hive</groupId><artifactId>hive-cli</artifactId><version>${hive.version}</version></dependency><dependency><groupId>org.apache.hive</groupId><artifactId>hive-jdbc</artifactId><version>${hive.version}</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.0</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin></plugins></build>

Hive保姆级教程(万字长文,建议收藏)相关推荐

  1. zeppelin安装和配置(保姆级教程)

    zeppelin简单介绍: Zeppelin是一个基于Web的notebook,提供交互数据分析和可视化.支持多种数据引擎,如hive.spark等.还支持多种编程语言,如python.Scala等. ...

  2. JavaScript保姆级教程 ——— 重难点详细解析(万字长文,建议收藏)

    JavaScript保姆级教程 --- 重难点详细解析(建议收藏) 1. JS函数 2. JS事件 3. JavaScript 对象 4. JavaScript prototype(原型对象) 5. ...

  3. ❤️周末爆肝两天❤️,万字长文,手把手教你配置CSDN主页的独特域名(保姆级教程,建议收藏)

    ❤️ 感受下效果图 ❤️ 目录 一.前言 二.先解决有没有的问题 1. 前置条件 2. 购买云服务器 3. 购买DNS域名 4. 配置Apache2服务 5. 配置云服务器的端口映射 6. 配置ngi ...

  4. 万字长文:Stable Diffusion 保姆级教程

    万字长文:Stable Diffusion 保姆级教程 2022年绝对是人工智能爆发的元年,前有 stability.ai 开源 Stable Diffusion 模型,后有 Open AI 发布 C ...

  5. 从购买服务器到网站搭建成功保姆级教程~超详细

    ??从购买服务器到网站搭建成功保姆级教程~真的超详细,各位看官细品 ??前言 ??预备知识 ??什么是云服务器? ??什么是域名? ??什么是SSL证书? ??服务器选配 ??阿里云[官网链接](ht ...

  6. html类选择器使用在什么场景,你需掌握的CSS知识都在这了(长文建议收藏,文末有福利)...

    1.CSS盒模型,在不同浏览器的差异 css 标准盒子模型 css盒子模型 又称为框模型(Box Model),包含了元素内容(content).内边距(padding).边框(border).外边距 ...

  7. 数仓建设保姆级教程,离线和实时一网打尽(理论+实战)

    本文大纲: 因内容较多,带目录的PDF查看是比较方便的,点击下方链接获取完整PDF版: 数仓建设保姆级教程PDF文档 一.数仓基本概念 1. 数据仓库架构 我们在谈数仓之前,为了让大家有直观的认识,先 ...

  8. 50000字,数仓建设保姆级教程,离线和实时一网打尽(理论+实战) 下

    文档大纲: 本文上半部分之前已经发过了,传送门:50000字,数仓建设保姆级教程,离线和实时一网打尽(理论+实战) 上 此篇文章是整个文档的下半部分,将接着上半部分从第五章开始. 五.实时数仓建设核心 ...

  9. 满满干货!红书运营保姆级教程

    **满满干货!红书运营保姆级教程** 1. 同类三种媒体发布平台的优劣势 今日头条: 今日头条的用户基础雄厚,活跃的用户比较多,所能带来的流量是比较大的,这也就导致了今日头条的推荐量雄厚,是不可多得的 ...

最新文章

  1. SpringCloud(第 051 篇)EurekaServer集群高可用注册中心以及简单的安全认证
  2. python加绝对值_python如何使用绝对值
  3. SQL之rand,round,floor,ceiling,cast小数处理函数
  4. pytorch中的批量归一化BatchNorm1d和BatchNorm2d的用法、原理记录
  5. jaxb 生成java类_重用生成的JAXB类
  6. php视图查询的优势,ThinkPHP视图查询详解
  7. js类似matlab_JavaScript与MATLAB的计算性能差异对比研究
  8. windows python安装包_Python-3.9安装包(windows版)
  9. Ubuntu 中如何使用 PPA 安装应用程序
  10. java extjs 教程_Extjs项目实战视频教程
  11. 项目实训(一)基于unity的2D多人乱斗闯关游戏设计与开发 unity的下载及了解
  12. 如何生成公众号带参数二维码
  13. zeppelin使用shiro进行权限验证
  14. python替换excel指定内容_Python脚本操作Excel实现批量替换功能
  15. Java 生成微信扫描的二维码,跳转到指定网址,图片增加二维码及文字水印
  16. 线性代数(行列式矩阵向量)
  17. vc文件拖曳(控件)
  18. 5岁儿童自学python编程-少儿python编程启蒙培训班-小孩学习编程去哪里好
  19. 智慧农业解决方案-最新全套文件
  20. DNS正向解析与反向解析

热门文章

  1. Excel内置插件实现多个同类型文件合并,无需代码
  2. 浪潮超融合服务器虚拟机管理,浪潮在美发布InCloudRail超融合,这是什么样的节奏?...
  3. 小象奶茶馆结算系统3.0版本(python)
  4. easyui 根据值查找匹配
  5. java语言程序设计培训_JAVA语言程序设计Z
  6. 【macOS】MAC地址获取
  7. CMake是什么?具体有什么作用?
  8. MAC系统如何更换管理员用户
  9. 铁三角发布 BP3600 沉浸声录音话筒
  10. 城市客运运输量的BP神经网络预测的python实现