1.Hive 基本概念
1.1. Hive 简介
Hive 的前生属于 Facebook,用于解决海量结构化数据的统计分析,现在属于 Apache 软件基金会。Hive 是一个构建在Hadoop 之上的数据分析工具(Hive 没有存储数据的能力,只有使用数据的能力),底层由 HDFS 来提供数据存储,可以将结构化的数据文件映射为一张数据库表,并且提供类似 SQL 的查询功能,本质就是将 HQL 转化成 MapReduce 程序。说白了 Hive 可以理解为一个将 SQL 转换为 MapReduce 程序的工具,甚至更近一步说 Hive 就是一个 MapReduce 客户端。
总结:交互方式采用 SQL,元数据存储在 Derby 或 MySQL,数据存储在 HDFS,分析数据底层实现是 MapReduce,执行程序运行在 YARN 上。
1.2. Hive vs 数据库
由于 Hive 采用了类似 SQL 的查询语言 HQL(Hive Query Language),因此很容易将 Hive 理解为数据库。其实从结构上来看,Hive 和数据库除了拥有类似的查询语言,再无类似之处,具体区别如下。
- 查询语言:由于 SQL 被广泛的应用在数据仓库中,因此,专门针对 Hive 的特性设计了类 SQL 的查询语言 HQL。熟悉SQL 开发的开发者可以很方便的使用 Hive 进行开发。
- 数据存储:Hive 是建立在 Hadoop 之上的,所有 Hive 的数据都是存储在 HDFS 中。而数据库则可以将数据保存在块设备或者本地文件系统中。
- 数据更新:由于 Hive 是针对数据仓库应用设计的,而数据仓库的内容是读多写少。因此,Hive 中不支持对数据的修改和添加,所有的数据都是在加载时确定好的。而数据库中的数据通常是需要经常进行修改的,因此可以使用 INSERT INTO … VALUES 添加数据,使用 UPDATE … SET 修改数据。
- 执行方式:Hive 中大多数查询的执行是通过 Hadoop 提供的 MapReduce 来实现的。而数据库通常有自己的执行引擎。
- 执行延迟:Hive 在查询数据的时候,由于没有索引,需要扫描整个表,因此延迟较高。另外一个导致 Hive 执行延迟高的因素是 MapReduce 框架。由于 MapReduce 本身具有较高的延迟,因此在利用 MapReduce 执行 Hive 查询时,也会有较高的延迟。相对的,数据库的执行延迟较低。当然,这个低是有条件的,即数据规模较小,当数据规模大到超过数据库的处理能力的时候,Hive 的并行计算显然能体现出优势。
- 可扩展性:由于 Hive 是建立在 Hadoop 之上的,因此 Hive 的可扩展性和 Hadoop 的可扩展性是一致的(世界上最大的Hadoop 集群在 Yahoo!,2009 年的规模在 4000 台节点左右)。而数据库由于 ACID 语义的严格限制,扩展行非常有限。目前最先进的并行数据库 Oracle 在理论上的扩展能力也只有 100 台左右。
- 数据规模:由于 Hive 建立在集群上并可以利用 MapReduce 进行并行计算,因此可以支持很大规模的数据。而数据库支持的数据规模相对较小。
- 索引:Hive 在加载数据的过程中不会对数据进行任何处理,甚至不会对数据进行扫描,因此也没有对数据中的某些Key 建立索引。Hive 要访问数据中满足条件的特定值时,需要暴力扫描整个数据,因此访问延迟较高。由于底层实现是 MapReduce 的原因, Hive 可以并行访问数据,因此即使没有索引,对于大数据量的访问,Hive 仍然可以体现出优势。数据库中,通常会针对一个或者几个列建立索引,因此对于少量的特定条件的数据访问,数据库可以有很高的效率,较低的延迟。由于数据的访问延迟较高,决定了 Hive 不适合在线数据查询。 值得一提的是,Hive 在 0.8 版本后加入了位图索引。Hive 索引原理为:在指定列上建立索引,生成一张索引表(Hive的一张物理表),记录以下三个字段:索引列的值、该值对应的 HDFS 文件路径、该值在文件中的偏移量。在执行索引字段查询时候,首先额外生成一个 MapReduce Job,根据对索引列的过滤条件,从索引表中过滤出索引列的值对应的 HDFS 文件路径及偏移量,输出到 HDFS 上的一个文件中,然后根据这些文件中的 HDFS 路径和偏移量,筛选原始 Input 文件,生成新的 Split 作为整个 Job 的 Split,达到不用全表扫描的目的。
- 事务:Hive 在 0.14 版本后开始支持事务,前提是文件格式必须为 ORC 格式,同时必须分桶,还必须显式声明transactional=true。
1.3. 为什么使用 Hive
要问为什么使用 Hive 不妨直接问为什么不使用 Hadoop?使用 MapReduce 面临的问题是:
- 学习成本较高,因为要学习 Java 或者 Python(用来编写 MapReduce 程序)
- MapReduce 实现复杂的查询逻辑的时候,开发难度相对较大(约束 Key 和 Value 的类型,自定义排序规则、自定义分 区器等等)
- 为什么 Hive 要比直接使用 MapReduce 开发效率更高?因为: - 操作接口采用类似 SQL 的语法,提供快速开发的能力- 免去了写 MapReduce 的过程,减少开发人员的学习成本- 功能扩展方便
1.4. Hive 优缺点
- 优点 - 操作接口采用类似 SQL 的语法,提供快速开发的能力(简单、容易上手)。- 免去了写 MapReduce 的过程,减少开发人员的学习成本。- Hive 的执行延迟比较高,因此 Hive 常用于离线数据分析,对实时性要求不高的场合。- Hive 优势在于处理大数据,对于处理小数据没有优势,因为 Hive 的执行延迟比较高。- Hive 支持用户自定义函数,用户可以根据自己的需求来实现自己的函数。- 集群可自由拓展并且具有良好的容错性,节点出现问题 SQL 仍可完成执行。
- 缺点 - Hive 的 HQL 表达能力有限,当逻辑需求特别复杂的时候,还是要借助 MapReduce。 - 迭代式算法无法表达- 数据挖掘方面不擅长- Hive 操作默认基于 MapReduce 引擎,而 MapReduce 引擎与其它的引擎(如 Spark 引擎)相比,特点就是慢、延迟高、不适合交互式查询,所以 Hive 也有这个缺点(这里讲的是默认引擎,Hive 是可以更改成其他引擎的)。- Hive 自动生成的 MapReduce 作业,通常情况下不够智能化。- Hive 调优比较困难,粒度较粗。
1.5. Hive 应用场景
- 日志分析:大部分互联网公司使用 Hive 进行日志分析,包括百度、淘宝等。 统计网站一个时间段内的 PV、UV
- 多维度数据分析
- 海量结构化数据的离线分析
1.6. 思考题
思考:计算文件 user.txt 中张三出现的次数,使用 MapReduce 怎么写,然后再比照下图的 Hive 实现过程。
2. Hive 架构
2.1. Client
Hive 允许 Client 连接的方式有三个 CLI(Hive Shell)、JDBC/ODBC(Java 访问 Hive)、WEBUI(浏览器访问 Hive)。JDBC/ODBC 访问中间件 Thrift 软件框架,跨语言服务开发。DDL DQL DML,整体仿写一套 SQL 语句。
2.2. MetaStroe
元数据,数据的数据。元数据包括表名、表结构信息、表所属的数据库(默认是 default 库)、表的拥有者(权限信息)、列/分区字段、表的类型(是否是外部表)、表的数据所在目录等。
元数据的存放一般需要借助于其他的数据载体(Derby 或 MySQL),默认存放在自带的 Derby 数据库(单用户局限性)中,推荐使用 MySQL 进行存储。连接数据库需要提供:uri、username、password、driver。
元数据服务的作用是:客户端连接 MetaStroe 服务,MetaStroe 服务再去连接 MySQL 数据库来存取元数据。有了MetaStroe 服务,就可以有多个客户端同时连接,而且这些客户端不需要知道 MySQL 数据库的用户名和密码,只需要连接MetaStroe 服务即可。
Hive 默认将元数据存储在 Derby 数据库中,但其仅支持单线程操作,若有一个用户在操作,其他用户则无法使用,造成效率不高;而且当在切换目录后,重新进入 Hive 会找不到原来已经创建的数据库和表,因此一般使用 MySQL 数据库存储元数据。
2.3. Driver
- 解析器(SQL Parser):将 SQL 字符串转换成抽象语法树 AST,这一步一般都用第三方工具库完成,比如 ANTLR;对AST 进行语法分析,分析查询语法和查询计划,检查 SQL 语义是否有误。
- 编译器(Compiler):获取元数据,检查表是否存在、字段是否存在,然后将 AST 编译生成逻辑执行计划。
- 优化器(Query Optimizer):对逻辑执行计划进行优化。
- 执行器(Execution):把逻辑执行计划转换成可以运行的物理计划。最后根据优化后的物理执行计划生成底层代码进行执行,对于 Hive 来说,就是 MR/Spark。
大致流程如下:
- Parser:将 HQL 语句解析成抽象语法树(AST:Abstract Syntax Tree);
- Semantic Analyzer:将抽象语法树编译成查询块;
- Logic Plan Generator:将查询块转换成逻辑查询计划;
- Logic Optimizer:重写逻辑查询计划,优化逻辑执行计划(RBO);
- Physical Plan Gernerator:将逻辑计划转化成物理计划(MapReduce Jobs);
- Physical Optimizer:选择最佳的 Join 策略,优化物理执行计划(CBO);
- Execution:最后根据优化后的物理执行计划生成底层代码,进行执行。
2.4. HDFS
Hive 的数据存储在 HDFS 中,计算由 MapReduce 完成。HDFS 和 MapReduce 是源码级别上的整合,两者结合最佳。解释器、编译器、优化器完成 HQL 查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。
3.Hive 工作原理
当创建表的时候,需要指定 HDFS 文件路径,表和其文件路径会保存到 MetaStore,从而建立表和数据的映射关系。当数据加载入表时,根据映射获取到对应的 HDFS 路径,将数据导入。
用户输入 SQL 后,Hive 会将其转换成 MapReduce 或者 Spark 任务,提交到 YARN 上执行,执行成功将返回结果。
在搭建 Hive 数据仓库时,就会将 SQL 语句的常用指令操作,比如 SELECT、FROM、WHERE 以及函数等用 MapReduce写成模板,并且将这些 MapReduce 模板封装到 Hive 中。
那我们所需要做的,就是根据业务需求编写相应的 SQL 语句,Hive 会自动的到封装好的 MapReduce 模板中去进行匹配。匹配完后将运行 MapReduce 程序,生成相应的分析结果,然后反馈给我们。总之就是做离线数据分析时,Hive 要比直接使用 MapReduce 开发效率更高。
4.Hive 安装
4.1.1. 内嵌模式
内嵌模式使用的是内嵌的 Derby 数据库来存储元数据,不需要额外起 MetaStore 服务。数据库和 MetaStore 服务都嵌入在主 Hive Server 进程中。内嵌模式属于默认方式,配置简单,但是一次只能一个客户端连接,适用于实验,不适用于生产环境。解压 Hive 安装包,启动 bin/hive 即可使用。
缺点:不同路径启动 Hive,每一个 Hive 都拥有一套自己的元数据,无法共享。
4.1.2. 本地模式
本地模式采用外部数据库来存储元数据,目前支持的数据库有:Oracle、MySQL、PostgreSQL、SQL Server。在这里我们使用 MySQL。本地模式不需要单独起 MetaStore 服务,用的是跟 Hive 在同一个进程里的 MetaStore 服务。也就是说当你启动一个 Hive 服务,里面默认会帮我们启动一个 MetaStore 服务。Hive 会根据hive.metastore.uris 参数值来判断,如果为空,则为本地模式。
缺点:每启动一次 Hive 服务,都内置启动了一个 MetaStore。
4.1.3. 远程模式
远程模式下,需要单独起 MetaStore 服务,然后每个客户端都在配置文件里配置连接到该 MetaStore 服务。远程模式的 MetaStore 服务和 Hive 运行在不同的进程里。在生产环境中,建议用远程模式来配置 Hive Metastore。在这种情况下,其他依赖 Hive 的软件都可以通过 MetaStore 访问 Hive。
远程模式下需要配置 hive.metastore.uris 参数来指定 MetaStore 服务运行的机器 IP 和端口,并且需要单独手动启动 MetaStore 服务。HiveServer2 是 Hive 启动的一个服务,客户端可以使用 JDBC/ODBC 协议,通过 IP + Port 的方式对其进行访问,达到并发访问的目的。
提示:Hive 4.0.0 版本开始 hive shell 也改为了 beeline 的连接方式。
5.Hive 交互方式
5.1. 第一种
[root@node03 ~]# hive...
hive (default)> SHOW DATABASES;
OK
database_name
default
Time taken: 0.633 seconds, Fetched: 1 row(s)
hive (default)>exit;
default 是默认的数据库,路径为 /hive/warehouse 。
5.2. 第二种*
单节点。
[root@node03 ~]# beeline -u jdbc:hive2://node01:10000 -n root...
Connecting to jdbc:hive2://node01:10000
Connected to: Apache Hive (version 3.1.3)
Driver: Hive JDBC (version 3.1.3)
Transaction isolation: TRANSACTION_REPEATABLE_READ
Beeline version 3.1.3 by Apache Hive
0: jdbc:hive2://node01:10000> SHOW DATABASES;...
+----------------+
| database_name |
+----------------+
| default |
+----------------+
1 row selected (0.066 seconds)0: jdbc:hive2://node01:10000>!exit
Closing: 0: jdbc:hive2://node01:10000
10000 为 hive.server2.thrift.port 的默认值(Thrift Server 的 TCP 端口默认为 10000)。
HA 方式。
当 HiveServer2 注册至 ZooKeeper 以后,JDBC 连接的 URL 格式需要为:
jdbc:hive2://<zookeeper quorum>/<db>;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2-ha
- :ZooKeper 服务器列表,例如 node01:2181,node02:2181,node03:2181 ;
- :要连接至 Hive 的哪个数据库,默认为 default;
- serviceDiscoveryMode :指定模式为 zooKeeper;
- zooKeeperNamespace :指定 ZooKeper 中的 Namespace,即参数 hive.server2.zookeeper.namespace 所定义的值。其他参数请参考官网:https://cwiki.apache.org/confluence/display/Hive/HiveServer2+Clients#HiveServer2Clients-ConnectionURLWhenZooKeeperServiceDiscoveryIsEnabled
[root@node03 ~]# beeline -u"jdbc:hive2://node01:2181,node02:2181,node03:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2-ha" -n root
...
Connecting to
jdbc:hive2://node01:2181,node02:2181,node03:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hi
veserver2-ha
# 注意下面这行:连接至 node01:10000[main]: INFO jdbc.HiveConnection: Connected to node01:10000
Connected to: Apache Hive (version 3.1.3)
Driver: Hive JDBC (version 3.1.3)
Transaction isolation: TRANSACTION_REPEATABLE_READ
Beeline version 3.1.3 by Apache Hive
0: jdbc:hive2://node01:2181,node02:2181,node03:2181>
5.3. 第三种
使用 -e 参数来直接执行 HQL 的语句。
# 单节点
bin/beeline -u "jdbc:hive2://node01:10000/default" -n root hive -e "SHOW DATABASES;"# HA 方式
bin/beeline -u
"jdbc:hive2://node01:2181,node02:2181,node03:2181/default;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2-ha" -n root hive -e "SHOW DATABASES;"
使用 -f 参数通过指定文本文件来执行 HQL 的语句。
# 单节点
bin/beeline -u "jdbc:hive2://node01:10000/default" -n root hive -f "default.sql"# HA 方式
bin/beeline -u
"jdbc:hive2://node01:2181,node02:2181,node03:2181/default;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2-ha" -n root hive -f "default.sql"
5.4. 总结
MetaStore 服务实际上就是一种 Thrift 服务,通过它我们可以获取到 Hive 元数据。通过 Thrift 服务获取原数据的方式,屏蔽了数据库访问需要的驱动,URL,用户名,密码等细节。
HiveServer2(HS2)是一个服务端接口,使远程客户端可以执行对 Hive 的查询并返回结果。一般来讲,我们认为HiveServer2 是用来提交查询的,而 MetaStore 才是真正用来访问元数据的,所以推荐使用第二种,这种方式更加安全或者从设计上来讲更加合理,如下图所示。
6.Hive 元数据/数据类型
了解 Hive 元数据库中一些重要的表结构及用途,方便 Impala、SparkSQL、Hive 等组件访问元数据库时的理解。
6.1. 元数据
6.1.1. 版本表
存储 Hive 版本的元数据表(VERSION),该表比较简单,但很重要。
如果该表出现问题,根本进入不了 Hive-Cli。比如该表不存在,当启动 Hive-Cli 时候,就会报错“Table ‘hive.version’doesn’t exist”。
6.1.2. 数据库相关表
Hive 数据库相关的元数据表主要有 DBS、DATABASE_PARAMS,这两张表通过 DB_ID 字段进行关联。
DBS:该表存储 Hive 中所有数据库的基本信息,字段如下。
DATABASE_PARAMS:该表存储数据库的相关参数,在 CREATE DATABASE 时候用 WITH
DBPROPERTIES(property_name=property_value, …) 指定的参数。
6.1.3. 视图相关表
Hive 表和视图相关的元数据表主要有 TBLS、TABLE_PARAMS、TBL_PRIVS,这三张表通过 TBL_ID 字段进行关联。
TBLS:该表中存储 Hive 表,视图,索引表的基本信息。
TABLE_PARAMS:该表存储表/视图的属性信息。
TBL_PRIVS:该表存储表/视图的授权信息。
6.1.4. 文件存储信息相关表
Hive 文件存储信息相关的元数据表主要涉及 SDS、SD_PARAMS、SERDES、SERDE_PARAMS,由于 HDFS 支持的文件格式很多,而建 Hive 表的时候也可以指定各种文件格式,所以 Hive 在将 HQL 解析成 MapReduce 时候,需要知道去哪里,使用哪种格式去读写 HDFS 文件,而这些信息就保存在这几张表中。
SDS:该表保存文件存储的基本信息,如INPUT_FORMAT、OUTPUT_FORMAT、是否压缩等。TBLS表中的SD_ID与该表关联,可以获取Hive表的存储信息。
SD_PARAMS:该表存储 Hive 存储的属性信息,在创建表时候使用 STORED BY ‘storage.handler.class.name’ [WITHSERDEPROPERTIES (…) 指定。
SERDES:该表存储序列化使用的类信息。
SERDE_PARAMS:该表存储序列化的一些属性、格式信息,比如:行、列分隔符。
6.1.5. 表字段相关表
Hive 表字段相关的元数据表主要涉及 COLUMNS_V2。
COLUMNS_V2:该表存储表对应的字段信息。
6.1.6. 分区相关表
Hive 表分区相关的元数据表主要涉及 PARTITIONS、PARTITION_KEYS、PARTITION_KEY_VALS、PARTITION_PARAMS
PARTITIONS:该表存储表分区的基本信息。
PARTITION_KEYS:该表存储分区的字段信息。
PARTITION_KEY_VALS:该表存储分区字段值。
PARTITION_PARAMS:该表存储分区的属性信息。
6.1.7. 其他表
其他不常用的元数据表。
- DB_PRIVS:数据库权限信息表。通过 GRANT 语句对数据库授权后,将会在这里存储。
- IDXS:索引表,存储 Hive 索引相关的元数据。
- INDEX_PARAMS:索引相关的属性信息。
- TBL_COL_STATS:表字段的统计信息。使用 ANALYZE 语句对表字段分析后记录在这里。
- TBL_COL_PRIVS:表字段的授权信息。
- PART_PRIVS:分区的授权信息。
- PART_COL_PRIVS:分区字段的权限信息。
- PART_COL_STATS:分区字段的统计信息。
6.2. 数据类型
6.2.1. 基础数据类型
6.2.2. 复杂数据类型
Hive 有三种复杂数据类型 ARRAY、MAP 和 STRUCT。ARRAY 和 MAP 与 Java 中的 Array 和 Map 类似,而 STRUCT 与 C 语言中的 Struct 类似,它封装了一个命名字段集合,复杂数据类型允许任意层次的嵌套
7. Hive 基础
这里只做MySQL没学过的。
指定数据库创建的位置(数据库在 HDFS 上的存储路径)。
CREATEDATABASEIFNOTEXISTS school location '/hive/school.db';
建表的字段说明:
- CREATE TABLE :创建一个指定名称的表。如果相同名称的表已经存在,则抛出异常;可以使用 IF NOT EXISTS选项来进行判断。
- EXTERNAL :此关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径(LOCATION)。- 创建内部表时,会将数据移动到数据仓库指向的路径(默认位置);- 创建外部表时,仅记录数据所在的路径,不对数据的位置做任何改变。- 在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。
- COMMENT :为表和列添加注释。
- PARTITIONED BY :创建分区表。
- CLUSTERED BY :创建分桶表。
- SORTED BY :排序方式,不常用。
- ROW FORMAT : DELIMITED [FIELDS TERMINATED BY char] [COLLECTION ITEMS TERMINATED BY char] [MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char] | SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value, property_name=property_value, …)] 。 用户在建表的时候可以自定义 SerDe 或者使用自带的 SerDe。如果没有指定 ROW FORMAT 或者 ROW FORMAT DELIMITED,将会使用自带的 SerDe(默认是 LazySimpleSerDe 类,只支持单字节分隔符)。 在建表的时候,用户还需要为表指定列,用户在指定表的列的同时也会指定自定义的 SerDe,Hive 通过 SerDe 确定表的具体的列的数据。 SerDe 是 Serialize/Deserilize 的简称,目的是用于序列化和反序列化。
- STORED AS :指定存储文件的类型。常用的存储文件类型有: SEQUENCEFILE(二进制序列文件) TEXTFILE(文本) RCFILE(列式存储格式文件)如果文件数据是纯文本,可以使用 STORED AS TEXTFILE。如果数据需要压缩,使用STORED AS SEQUENCEFILE
- LOCATION :指定表在 HDFS 上的存储位置。
- LIKE :允许用户复制现有的表结构,但是不复制数据。
案例1
准备数据:
songsong,bingbing_lili,xiao song:18_xiaoxiao song:19,hui long guan_beijing
yangyang,caicai_susu,xiao yang:18_xiaoxiao yang:19,chao yang_beijing
建表语句:
USE test;CREATETABLEIFNOTEXISTS t_person (
name string,
friends array<string>,
children map<string,int>,
address struct<street:string ,city:string>)ROW FORMAT DELIMITED FIELDSTERMINATEDBY','
COLLECTION ITEMS TERMINATEDBY'_'
MAP KEYSTERMINATEDBY':'LINESTERMINATEDBY'\n';
最后执行以下语句将 person.txt 文件的数据载入 t_person 表。执行 LOAD DATA 语句后 person.txt 文件将会被移动到 t_person 表所在路径下( /hive/warehouse/t_person/person.txt )。
LOADDATA INPATH '/yjx/person.txt'INTOTABLE t_person;
案例2
准备数据:
01||周杰伦||中国||台湾||男||稻香
02||刘德华||中国||香港||男||笨小孩
03||汪 峰||中国||北京||男||光明
04||朴 树||中国||北京||男||那些花儿
05||许 巍||中国||陕西||男||故乡
06||Taylor Swift||美国||宾夕法尼亚||女||Blank Space
07||Maroon 5||美国||加利福尼亚||男||Sugar
RegexSerDe。Hive 内置了很多的 SerDe 类,可以使用 RegexSerDe 正则序列化器来处理。推荐使用。
官方文档:https://cwiki.apache.org/confluence/display/Hive/SerDe
Built-in SerDes:
- Avro (Hive 0.9.1 and later)
- ORC (Hive 0.11 and later)
- RegEx
- Thrift
- Parquet (Hive 0.13 and later)
- CSV (Hive 0.14 and later)
- JsonSerDe (Hive 0.12 and later in hcatalog-core)
创建 t_singer 表并使用 RegexSerDe 序列化器(正则语法检测网站:https://regex101.com/)。
建表语句:
CREATETABLEIFNOTEXISTS t_singer (
id string,
name string,
country string,
province string,
gender string,
works string
)ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'WITH SERDEPROPERTIES ("input.regex"="(\\d*)\\|\\|([\\u4e00-\\u9fa5\\w\\x20\\-]*)\\|\\|([\\u4e00-
\\u9fa5\\w\\x20\\-]*)\\|\\|([\\u4e00-\\u9fa5\\w\\x20\\-]*)\\|\\|([\\u4e00-\\u9fa5\\w\\x20\\-]*)\\|\\|
([\\u4e00-\\u9fa5\\w\\x20\\-]*)");
导入数据:
LOADDATA INPATH '/yjx/singer.txt'INTOTABLE t_singer;
内外部表
1.内部表
所谓内部表(managed table)即 Hive 管理的表,Hive 内部表的管理既包含逻辑以及语法上的,也包含实际物理意义上的,即创建 Hive 内部表时,数据将真实存在于表所在的目录内,删除内部表时,物理数据和文件也一并删除。默认创建的是内部表。
执行 LOAD DATA 语句后 user.txt 文件将会被移动到 t_user 表所在路径下
( /hive/warehouse/test.db/t_user/user.txt )。此时如果使用 DROP 语句删除 t_user 后,其数据和表的元数
据都会被删除。
2.外部表
外部表(external table)则不然,其管理仅仅只是在逻辑和语法意义上的,即新建表仅仅是指向一个外部目录而已。同样,删除时也并不物理删除外部目录,而仅仅是将引用和定义删除。
一般情况下,在企业内部都是使用外部表的。因为会有多人操作数据仓库,可能会产生数据表误删除操作,为了数据安全性,通常会使用外部表,且方便达到数据共享。
外部表则不一样,数据的创建和删除完全由自己控制,Hive 不管理这些数据。
7.3.2.1. 方案一:创建时指定数据位置*
数据的位置可以在创建时指定,在 Hive 的数据仓库 /hive/warehouse/test.db 目录下不会创建 t_user 目录。
-- 可以指定到某个目录(该目录下的文件都会被扫描到),也可以指定到某个具体的文件。通配符 * 无效,例如/yjx/teacher/*/*
LOCATION '/yjx/user';
提示:如果 /yjx/user 目录不存在 Hive 会帮我们自动创建,我们只需要将 t_user 表所需的数据上传
至 /yjx/user 目录即可。或者数据已经存在于 HDFS 某个目录,Hive 创建外部表时直接指定数据位置即可。
7.3.2.2. 方案二:先建表再导入
也可以先单独建立外部表,建立时不指定数据位置,然后通过 LOAD DATA 命令载入数据。
LOADDATA INPATH '/yjx/user/user.txt'INTOTABLE test.t_user2;
注意:在这种情况下,执行 LOAD DATA 语句后 user.txt 文件将会被移动到 t_user2 表所在路径下
( /hive/warehouse/test.db/t_user2/user.txt )。唯一的区别是,外部表此时如果使用 DROP 语句删除
t_user2 后,只会删除元数据,也就是说 t_user2 目录和 user.txt 数据并不会被删除。
总结:推荐使用方案一,数据不会被随意移动,更易于团队使用。
载入数据
语法:
LOADDATA[LOCAL] INPATH 'datapath'[OVERWRITE]INTOTABLE student [PARTITION(partcol1=val1,…)];LOADDATA:加载数据
[LOCAL]:本地,不加 LOCAL 就是从 HDFS 获取
INPATH:数据的路径
'datapath':具体的路径,要参考本地还是 HDFS,支持通配符 *,例如 /yjx/user/*/*[OVERWRITE]:覆盖,不加 OVERWRITE 则追加数据
INTOTABLE:加入到表
student:表名
[PARTITION(partcol1=val1,…)]:分区
LOADDATALOCAL INPATH '/root/user.txt'INTOTABLE t_user;
要加载的文件必须和Hiveserver2在同一个节点
通过查询插入数据:
-- 插入查询结果-- 将查询结果插入一张表-- 追加INSERTINTO t_user1 SELECT id, username FROM t_user;-- 覆盖INSERT OVERWRITE TABLE t_user1 SELECT id, username FROM t_user;INSERT OVERWRITE TABLE t_user2 SELECT id, password FROM t_user;-- 将查询结果一次性存放到多张表(多重模式)-- 追加FROM t_user
INSERTINTO t_user1 SELECT id, username
INSERTINTO t_user2 SELECT id, password;-- 覆盖FROM t_user
INSERT OVERWRITE TABLE t_user1 SELECT id, username
INSERT OVERWRITE TABLE t_user2 SELECT id, password;
导出数据
1. 通过SQL导出
-- 将查询结果导出到本地INSERT OVERWRITE LOCAL DIRECTORY '/root/user'SELECT*FROM t_user;
结果:
[root@node01 ~]# cat /root/user/000000_0
1admin123456男18
2zhangsanabc123男23
3lisi654321女16
按指定格式导出:
-- 按指定的格式将数据导出到本地INSERT OVERWRITE LOCAL DIRECTORY '/root/person'ROW FORMAT DELIMITED FIELDSTERMINATEDBY','
COLLECTION ITEMS TERMINATEDBY'-'
MAP KEYSTERMINATEDBY':'LINESTERMINATEDBY'\n'SELECT*FROM t_person;
-- 将查询结果导出到 HDFSINSERT OVERWRITE DIRECTORY '/yjx/export/user'ROW FORMAT DELIMITED FIELDSTERMINATEDBY','SELECT*FROM t_user;
2.导出到HDFS
1.直接首先拷贝文件到其他目录。
hdfs dfs -cp /hive/warehouse/t_person/* /yjx/export/person
2.将数据和元数据同时导出。
首先在HDFS上创建一个存储导出数据的目录:
hdfs dfs -mkdir -p /yjx/export/person
将元数据和数据同时导出。
export table t_person to'/yjx/export/person'
导出结果:
这种时候当表被drop后,可以恢复
importfrom'/yjx/export/person'
8.基本查询
1.常用函数正则
语法:REGEXP_EXTRACT(str, regexp[, idx])
返回值:String
说明:将字符串 str 按照 regexp 正则表达式的规则拆分,返回 idx 指定的字符。
-- 将字符串按照正则表达式的规则拆分,返回 index 指定的字符,1 表示返回正则表达式中第一个()对应的结果,以此类推SELECT REGEXP_EXTRACT('2022-08-11 14:15:25.326 [gateway-server,,] [reactor-http-nio-2] DEBUG','([\\d\\x20-:\\.]*) (.*) (.*) ([a-zA-Z]*)',1);+--------------------------+| _c0 |+--------------------------+|2022-08-1114:15:25.326|+--------------------------+
语法: REGEXP_REPLACE(str, regexp, rep)
返回值:String
说明:将字符串 str 中的符合 regexp 正则表达式的部分替换为 rep。
SELECT REGEXP_REPLACE("Mr. and Mrs. Dursley, of number four, Privet Drive, were proud to say that they
were perfectly normal, thank you very much.","[^\\w'-]+"," ");+----------------------------------------------------+| _c0 |+----------------------------------------------------+| Mr and Mrs Dursley of number four Privet Drive were proud to say that they were perfectly normal
thank you very much |+----------------------------------------------------+
2.排序
Hive 中有四种排序:
- 全局排序:ORDER BY
- 内部排序:SORT BY
- 分区排序:DISTRIBUTE BY
- 组合排序:CLUSTER BY
1.全局排序
order by 语法,全局排序是在一个Reduce中进行排序的。
2.局部排序
sort by
SORT BY
主要用于
DISTRIBUTE BY
子句之后在每个 reducer 内部进行排序,和这里简单的查询排序需求不同。单独使用sort by 没有意义。
3.分区排序
distribute by 会根据指定字段将数据分到不同的Reduce,分发算法为hash散列。
DISTRIBUTE BY 类似 MR 中的 PARTITION(自定义分区),进行分区,一般结合 SORT BY 使用(注意:DISTRIBUTE BY要在 SORT BY 之前)。
对于 DISTRIBUTE BY 进行测试,一定要分配多 Reduce 进行处理,否则无法看到 DISTRIBUTE BY 的效果。
SELECT*FROM emp DISTRIBUTE BY deptno SORT BY sal DESC;
结果:
4.组合排序
CLUSTER BY 除了具有 DISTRIBUTE BY 的功能外还兼具 SORTS BY 的功能,所以当 DISTRIBUTE BY 和 SORTS BY 字段相同时,可以使用 CLUSTER BY 方式。但是排序只能是升序排序,不能指定排序规则为 ASC 或者 DESC,否则会报错。
BY
- 分区排序:DISTRIBUTE BY
- 组合排序:CLUSTER BY
1.全局排序
order by 语法,全局排序是在一个Reduce中进行排序的。
2.局部排序
sort by
SORT BY
主要用于
DISTRIBUTE BY
子句之后在每个 reducer 内部进行排序,和这里简单的查询排序需求不同。单独使用sort by 没有意义。
3.分区排序
distribute by 会根据指定字段将数据分到不同的Reduce,分发算法为hash散列。
DISTRIBUTE BY 类似 MR 中的 PARTITION(自定义分区),进行分区,一般结合 SORT BY 使用(注意:DISTRIBUTE BY要在 SORT BY 之前)。
对于 DISTRIBUTE BY 进行测试,一定要分配多 Reduce 进行处理,否则无法看到 DISTRIBUTE BY 的效果。
SELECT*FROM emp DISTRIBUTE BY deptno SORT BY sal DESC;
结果:[外链图片转存中…(img-ZwWsoM2J-1730988915267)]
4.组合排序
CLUSTER BY 除了具有 DISTRIBUTE BY 的功能外还兼具 SORTS BY 的功能,所以当 DISTRIBUTE BY 和 SORTS BY 字段相同时,可以使用 CLUSTER BY 方式。但是排序只能是升序排序,不能指定排序规则为 ASC 或者 DESC,否则会报错。
版权归原作者 m0_63924864 所有, 如有侵权,请联系我们删除。