Hive学习笔记1

Hive学习笔记1

本博客仅作学习记录所用,基于尚硅谷和黑马程序员做的笔记…
Hive学习笔记2
Hive学习笔记3

什么是Hive

  1. hive简介
    Hive:由Facebook开源用于解决海量结构化日志的数据统计工具。
    Hive是基于Hadoop的一个数据仓库工具,可以将存储在HDFS上的结构化、半结构化数据文件映射为一张数据库表,基于表提供了一种类似SQL的查询模型,称为Hive查询语言(HQL),用于访问和分析存储在Hadoop文件中的大型数据集。

  2. Hive本质:将HQL转化成MapReduce程序
    (1)Hive处理的数据存储在HDFS
    (2)Hive分析数据底层的实现是MapReduce
    (3)执行程序运行在Yarn上

用户编写sql语句,Hive自动将sql转换成MapReduce程序
返回顶部

什么是数据仓库

  1. 数据仓库(英语:Data Warehouse,简称数仓、DW),是一个用于存储、分析、报告的数据系统。数据仓库的目的是构建面向分析的集成化数据环境,为企业提供决策支持(Decision Support)。
  2. 数据仓库本身并不“生产”任何数据,其数据来源于不同外部系统;同时数据仓库自身也不需要“消费”任何的数据,其结果开放给各个外部应用使用,这也是为什么叫“仓库”,而不叫“工厂”的原因。

返回顶部

数据库和数据仓库

  1. 数据仓库不是大型的数据库,虽然数据仓库存储数据规模大。
  2. 数据仓库的出现,并不是要取代数据库。
  3. 数据库是面向事务的设计,数据仓库是面向主题设计的。
  4. 数据库一般存储业务数据,数据仓库存储的一般是历史数据。
  5. 数据库是为捕获数据而设计,数据仓库是为分析数据而设计。

返回顶部

Hive的优缺点

  1. 优点
    (1)操作接口采用类SQL语法,提供快速开发的能力(简单、容易上手)。
    (2)避免了去写MapReduce,减少开发人员的学习成本。
    (3)Hive的执行延迟比较高,因此Hive常用于数据分析,对实时性要求不高的场合。
    (4)Hive优势在于处理大数据,对于处理小数据没有优势,因为Hive的执行延迟比较高。
    (5)Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数。

  2. 缺点
    1)Hive的HQL表达能力有限
    (1)迭代式算法无法表达 (何为迭代?类似第一个MR的结果作为第二个MR的输入,一层一层地往下迭代)
    (2)数据挖掘方面不擅长,由于MapReduce数据处理流程的限制,效率更高的算法却无法实现。
    2)Hive的效率比较低
    (1)Hive自动生成的MapReduce作业,通常情况下不够智能化
    (2)Hive调优比较困难,粒度较粗

返回顶部

Hive与Hadoop的关系

从功能来说,数据仓库软件,至少需要具备下述两种能力:

  1. 存储数据的能力
  2. 分析数据的能力

Apache Hive作为一款大数据时代的数据仓库软件,当然也具备上述两种能力。只不过Hive并不是自己实现了上述两种能力,而是借助Hadoop。
Hive利用HDFS存储数据,利用MapReduce查询分析数据
这样突然发现Hive没啥用,不过是套壳Hadoop罢了。其实不然,Hive的最大的魅力在于用户专注于编写HQL,Hive帮您转换成为MapReduce程序完成对数据的分析。

返回顶部

Hive架构原理


在这里插入图片描述

  1. 用户接口:Client
    CLI(command-line interface)为shell命令行、JDBC/ODBC(jdbc 访问 hive),Hive中的Thrift服务器允许外部客户端通过网络与Hive进行交互,类似于JDBC或ODBC协议、WebGUI(浏览器访问 hive)

  2. 元数据:Metadata
    元数据包括:表名、表所属的数据库(默认是 default)、表的拥有者、表的列/分区字段、表的类型(是否是外部表)、表的数据所在目录,表的列对应着文件哪一个字段(顺序信息),文件字段之间的分隔符是什么 等;
    默认存储在自带的 derby 数据库中,推荐使用 MySQL 存储 Metastore

  3. Metastore
    Metastore即元数据服务。Metastore服务的作用是管理metadata元数据,对外暴露服务地址,让各种客户端通过连接metastore服务,由metastore再去连接MySQL数据库来存取元数据
    有了metastore服务,就可以有多个客户端同时连接,而且这些客户端不需要知道MySQL数据库的用户名和密码,只需要连接metastore 服务即可。某种程度上也保证了hive元数据的安全。
    在这里插入图片描述

  4. Hadoop
    使用 HDFS 进行存储,使用 MapReduce 进行计算。

  5. 驱动器:Driver
    (1)语法解析器(SQL Parser):将 SQL 字符串转换成抽象语法树 AST,这一步一般都用第三方工具库完成,比如 antlr;对 AST 进行语法分析,比如表是否存在、字段是否存在、SQL语义是否有误。
    (2)计划编译器(Physical Plan):将 AST 编译生成逻辑执行计划。
    (3)优化器(Query Optimizer):对逻辑执行计划进行优化。
    (4)执行器(Execution):把逻辑执行计划转换成可以运行的物理计划。生成的物理计划存储在 HDFS 中,并在随后有执行引擎调用执行。
    执行引擎:Hive本身并不直接处理数据文件。而是通过执行引擎处理。当下Hive支持MapReduce、Tez、Spark 3种执行引擎。

在这里插入图片描述
用户写完sql之后,hive需要针对sql进行语法校验,并且根据记录的元数据信息解读sql背后的含义,制定执行计划。并且把执行计划转换成MapReduce程序来执行,把执行的结果封装返回给用户

Hive 通过给用户提供的一系列交互接口,接收到用户的指令(SQL),使用自己的 Driver,结合元数据(MetaStore),将这些指令翻译成 MapReduce,提交到 Hadoop 中执行,最后将执行返回的结果输出到用户交互接口。

返回顶部

Hive和数据库比较

在这里插入图片描述

  1. 查询语言
    由于SQL被广泛的应用在数据仓库中,因此,专门针对Hive的特性设计了类SQL的查询语言HQL。熟悉SQL开发的开发者可以很方便的使用Hive进行开发。
  2. 数据更新
    由于Hive是针对数据仓库应用设计的,而数据仓库的内容是读多写少的。因此,Hive中不建议对数据的改写,所有的数据都是在加载的时候确定好的。而数据库中的数据通常是需要经常进行修改的,因此可以使用 INSERT INTO … VALUES 添加数据,使用 UPDATE … SET修改数据。
  3. 执行延迟
    Hive 在查询数据的时候,由于没有索引,需要扫描整个表,因此延迟较高。另外一个导致 Hive 执行延迟高的因素是 MapReduce框架。由于MapReduce 本身具有较高的延迟,因此在利用MapReduce 执行Hive查询时,也会有较高的延迟。相对的,数据库的执行延迟较低。当然,这个低是有条件的,即数据规模较小,当数据规模大到超过数据库的处理能力的时候,Hive的并行计算显然能体现出优势。
  4. 数据规模
    由于Hive建立在集群上并可以利用MapReduce进行并行计算,因此可以支持很大规模的数据;对应的,数据库可以支持的数据规模较小

返回顶部

metastore三种配置方式

介绍

metastore服务配置有3种模式:内嵌模式、本地模式、远程模式
区分3种配置方式的关键是弄清楚两个问题:

  1. Metastore服务是否需要单独配置、单独启动?
  2. Metadata是存储在内置的derby中,还是第三方RDBMS,比如Mysql。
内嵌模式本地模式远程模式
Metastore单独配置,启动
Metadata存储介质DerbyMySQLMySQL

内嵌模式

内嵌模式(Embedded Metastore)是metastore默认部署模式。此种模式下,元数据存储在内置的Derby数据库,并且Derby数据库和metastore服务都嵌入在主HiveServer进程中,当启动HiveServer进程时,Derby和metastore都会启动。不需要额外起Metastore服务。
但是一次只能支持一个活动用户,适用于测试体验,不适用于生产环境。
在这里插入图片描述

本地模式

  1. 本地模式(Local Metastore)下,Hive Metastore服务与主HiveServer进程在同一进程中运行,但是存储元数据的数据库在单独的进程中运行,并且可以在单独的主机上metastore服务将通过JDBC与metastore数据库进行通信
  2. 本地模式采用外部数据库来存储元数据,推荐使用MySQL。
  3. hive根据hive.metastore.uris 参数值来判断,如果为空,则为本地模式
  4. 缺点是:每启动一次hive服务,都内置启动了一个metastore。
    在这里插入图片描述

远程模式

  1. 远程模式(Remote Metastore)下,Metastore服务在其自己的单独JVM上运行,而不在HiveServer的JVM中运行。如果其他进程希望与Metastore服务器通信,则可以使用Thrift Network API进行通信。
  2. 在生产环境中,建议用远程模式来配置Hive Metastore。在这种情况下,其他依赖hive的软件都可以通过Metastore访问hive。由于还可以完全屏蔽数据库层,因此这也带来了更好的可管理性/安全性。

远程模式下,需要配置hive.metastore.uris 参数来指定metastore服务运行的机器ip和端口,并且需要单独手动启动metastore服务
在这里插入图片描述
返回顶部

Hive安装

Hive安装地址

  1. Hive官网地址 http://hive.apache.org/
  2. 文档查看地址 https://cwiki.apache.org/confluence/display/Hive/GettingStarted
  3. 下载地址 http://archive.apache.org/dist/hive/
  4. github地址 https://github.com/apache/hive

Hive安装部署(内嵌模式)

  1. 安装Hive
    1)把apache-hive-3.1.2-bin.tar.gz上传到linux的/opt/software目录下
    2)解压apache-hive-3.1.2-bin.tar.gz到/opt/module/目录下
[hyj@hadoop102 software]$ tar -zxvf apache-hive-3.1.2-bin.tar.gz -C /opt/module/

3)修改apache-hive-3.1.2-bin的名称为hive-3.1.2

[hyj@hadoop102 module]$ mv apache-hive-3.1.2-bin/ hive-3.1.2

4)修改/etc/profile.d/my_env.sh,添加hive环境变量

[hyj@hadoop102 module]$ sudo vim /etc/profile.d/my_env.sh

添加如下内容:

#HIVE_HOME 
export HIVE_HOME=/opt/module/hive-3.1.2
export PATH=$PATH:$HIVE_HOME/bin 

5)source一下,让环境变量生效

[hyj@hadoop102 module]$ source /etc/profile

6)解决日志Jar包冲突

[hyj@hadoop102 hive-3.1.2]$ cd lib/
[hyj@hadoop102 lib]$ mv log4j-slf4j-impl-2.10.0.jar log4j-slf4j-impl-2.10.0.bak

7)初始化元数据库

[hyj@hadoop102 hive-3.1.2]$ bin/schematool -dbType derby -initSchema
  1. 启动并使用Hive
    启动Hive之前必须先启动Hadoop集群。特别要注意,需等待HDFS 安全模式关闭之后再启动运行Hive。
    1)启动Hive
[hyj@hadoop102 hive-3.1.2]$ bin/hive

2)使用Hive

hive> show databases; 
hive> show tables; 
hive> create table test(id int); 
hive> insert into test values(1); 
hive> select * from test;

3)在CRT窗口中开启另一个窗口开启Hive,在/tmp/hyj目录下监控hive.log文件

[hyj@hadoop102 hyj]$ tail -f hive.log
Caused by: ERROR XSDB6: Another instance of Derby may have already booted 
the database /opt/module/hive/metastore_db.
 at 
org.apache.derby.iapi.error.StandardException.newException(Unknown 
Source)
 at 
org.apache.derby.iapi.error.StandardException.newException(Unknown
Source)
 at 
org.apache.derby.impl.store.raw.data.BaseDataFileFactory.privGetJBMSLockO
nDB(Unknown Source)
 at 
org.apache.derby.impl.store.raw.data.BaseDataFileFactory.run(Unknown 
Source)
......

原因在于Hive默认使用的元数据库为derby,开启Hive之后就会占用元数据库,且不与其他客户端共享数据,所以我们需要将Hive的元数据地址改为MySQL。

返回顶部

MySQL安装

1)检查当前系统是否安装过MySQL

[hyj@hadoop102 hive-3.1.2]$ rpm -qa | grep mariadb
mariadb-libs-5.5.56-2.el7.x86_64 
//如果存在通过如下命令卸载 
[hyj@hadoop102 hive-3.1.2]$ sudo rpm -e --nodeps mariadb-libs-5.5.56-2.el7.x86_64

-qa查看系统中已安装的所有rpm软件包
rpm -e 软件名卸载指定的rpm软件
--nodeps安装,升级或卸载软件时,忽略依赖关系

2)将MySQL安装包上传到/opt/software目录下
3)解压MySQL安装包

[hyj@hadoop102 software]$ tar -xf mysql-5.7.29-1.el7.x86_64.rpm-bundle.tar

tar命令:
-z,- -gzip,- -gunzip,- -ungzip 调用gzip执行压缩或解压缩。
-x,- -extract,- -get 解开tar文件
-v,- -verbose 列出每一步处理涉及的文件的信息,只用一个“v”时,仅列出文件名,使用两个“v”时,列出权限、所有者、大小、时间、文件名等信息。
-f,- -file [主机名:]文件名 指定要处理的文件名。可以用“-”代表标准输出或标准输入。
4)在安装目录下执行rpm安装 (注意:按照顺序依次执行 )

[hyj@hadoop102 software]$ sudo rpm -ivh mysql-community-common-5.7.29-1.el7.x86_64.rpm
[hyj@hadoop102 software]$ sudo rpm -ivh mysql-community-libs-5.7.29-1.el7.x86_64.rpm
[hyj@hadoop102 software]$ sudo rpm -ivh mysql-community-libs-compat-5.7.29-1.el7.x86_64.rpm
[hyj@hadoop102 software]$ sudo rpm -ivh mysql-community-client-5.7.29-1.el7.x86_64.rpm
[hyj@hadoop102 software]$ sudo rpm -ivh mysql-community-server-5.7.29-1.el7.x86_64.rpm 

-i安装一个新的rpm软件包(install)
-v显示过程中的详细信息
-h以#显示安装的进度
若是在执行rpm安装的过程中出现以下错误:

[hyj@hadoop102 software]$ sudo rpm -ivh mysql-community-server-5.7.29-1.el7.x86_64.rpm 
警告:mysql-community-server-5.7.29-1.el7.x86_64.rpm: 头V3 DSA/SHA1 Signature, 密钥 ID 5072e1f5: NOKEY
错误:依赖检测失败:
	mysql-community-common(x86-64) = 5.7.29-1.el7 被 mysql-community-server-5.7.29-1.el7.x86_64 需要

则在后面加上 --force --nodeps

[hyj@hadoop102 software]$ sudo rpm -ivh mysql-community-server-5.7.29-1.el7.x86_64.rpm --force --nodeps

--force强制安装所指定的rpm软件包
--nodeps安装软件时,忽略依赖关系

如果Linux是最小化安装的,在安装mysql-community-server-5.7.29-1.el7.x86_64.rpm时可能会出现如下错误 :

[hyj@hadoop102 software]$ sudo rpm -ivh mysql-community-server-5.7.29-1.el7.x86_64.rpm 
警告:mysql-community-server-5.7.29-1.el7.x86_64.rpm: 头V3 DSA/SHA1 
Signature, 密钥 ID 5072e1f5: NOKEY 
错误:依赖检测失败:  libaio.so.1()(64bit) 被 mysql-community-server-5.7.29-1.el7.x86_64 
需要
  libaio.so.1(LIBAIO_0.1)(64bit) 被 mysql-community-server-5.7.29-
1.el7.x86_64 
需要
    libaio.so.1(LIBAIO_0.4)(64bit) 被 mysql-community-server-5.7.29-
1.el7.x86_64 需要 

通过yum安装缺少的依赖,然后重新安装mysql-community-server-5.7.29-1.el7.x86_64即可

[hyj@hadoop102 software] yum install -y libaio

5)删除/etc/my.cnf文件中datadir指向的目录下的所有内容,如果有内容的情况下:
查看datadir的值:

[hyj@hadoop102 software]$ cat /etc/my.cnf
[mysqld] 
datadir=/var/lib/mysql 

删除/var/lib/mysql目录下的所有内容:

[hyj@hadoop102 software]$ cd /var/lib/mysql
[hyj@hadoop102 mysql]$ sudo rm -fr ./*

6)初始化数据库

[hyj@hadoop102 hive-3.1.2]$ sudo mysqld --initialize --user=mysql

我在此步出现了以下错误:

2022-05-22T08:44:45.327711Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated.  Please use --explicit_defaults_for_timestamp server option (see documentation for more details). 
2022-05-22T08:44:45.327928Z 0 [ERROR] Error message file '/usr/share/mysql/english/errmsg. sys' had only 1080 error messages, 
but it should contain at least 1120 error messages. 
Check that the above file is the right version for                     this program! 
2022-05-22T08:44:45.329400Z 0 [ERROR] --initialize specified but the data directory has files in it.  Aborting. 
2022-05-22T08:44:45.329418Z 0 [ERROR] Aborting

第一种错误(2022-05-22T08:44:45.327711Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details) 的解决方法:
在/etc/my.cnf文件中加上explicit_defaults_for_timestamp=true保存后就可以了.

第二种错误(2022-05-22T08:44:45.327928Z 0 [ERROR] Error message file ‘/usr/share/mysql/english/errmsg. sys’ had only 1080 error messages,
but it should contain at least 1120 error messages.
Check that the above file is the right version for this program!
)的解决方法为:

  1. 先去官网下载mysql-5.7.29-linux-glibc2.12-x86_64.tar.gz(下载对应版本的)
    官网下载地址:https://downloads.mysql.com/archives/community/
  2. 将mysql-5.7.29-linux-glibc2.12-x86_64.tar.gz上传到/opt/software目录下
  3. 将mysql-5.7.29-linux-glibc2.12-x86_64.tar.gz解压到当前目录下
  4. 将mysql安装目录下的share/english/errmsg.sys 文件覆盖 /usr/share/mysql/english/errmsg.sys文件即可
[hyj@hadoop102 software]$ tar -zxvf mysql-5.7.29-linux-glibc2.12-x86_64.tar.gz 
[hyj@hadoop102 software]$ cd mysql-5.7.29-linux-glibc2.12-x86_64/
[hyj@hadoop102 mysql-5.7.29-linux-glibc2.12-x86_64]$ cd share/english/
[hyj@hadoop102 english]$ ls
errmsg.sys
[hyj@hadoop102 english]$ sudo mv /usr/share/mysql/english/errmsg.sys /usr/share/mysql/english/errmsg.bak
[hyj@hadoop102 english]$ sudo cp errmsg.sys /usr/share/mysql/english/
[hyj@hadoop102 english]$ cd /opt/software
[hyj@hadoop102 software]$ rm -fr mysql-5.7.29-linux-glibc2.12-x86_64 mysql-5.7.29-linux-glibc2.12-x86_64.tar.gz

最后再重新初始化数据库就可以了.

7)查看临时生成的root用户的密码

[hyj@hadoop102 hive-3.1.2]$ sudo cat /var/log/mysqld.log
2022-05-22T09:05:28.213405Z 0 [Warning] InnoDB: New log files created, LSN=45790
2022-05-22T09:05:28.276436Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
2022-05-22T09:05:28.335326Z 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: 53196644-d9ae-11ec-92e2-000c299cf26e.
2022-05-22T09:05:28.336326Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
2022-05-22T09:05:29.237719Z 0 [Warning] CA certificate ca.pem is self signed.
2022-05-22T09:05:29.503983Z 1 [Note] A temporary password is generated for root@localhost: buTaniYo+0fa
2022-05-22T13:19:05.692948Z 0 [Warning] InnoDB: New log files created, LSN=45790
2022-05-22T13:19:05.720341Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
2022-05-22T13:19:05.774889Z 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: c1666745-d9d1-11ec-885c-000c299cf26e.
2022-05-22T13:19:05.775452Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
2022-05-22T13:19:06.319358Z 0 [Warning] CA certificate ca.pem is self signed.
2022-05-22T13:19:06.837494Z 1 [Note] A temporary password is generated for root@localhost: Y>BeV)/OJ9Eh
......

8)启动MySQL服务

[hyj@hadoop102 hive-3.1.2]$ sudo systemctl start mysqld.service

查看MySQL服务是否正在运行:

[hyj@hadoop102 lib]$ service mysqld status      #或systemctl status mysqld.service
Redirecting to /bin/systemctl status mysqld.service
● mysqld.service - MySQL Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
   Active: active (running) since 三 2022-07-13 10:40:43 CST; 2h 25min ago
     Docs: man:mysqld(8)
           http://dev.mysql.com/doc/refman/en/using-systemd.html
 Main PID: 1460 (mysqld)
   CGroup: /system.slice/mysqld.service
           └─1460 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid

713 10:40:40 hadoop102 systemd[1]: Starting MySQL Server...
713 10:40:43 hadoop102 systemd[1]: Started MySQL Server.

9)登录MySQL数据库

[hyj@hadoop102 hive-3.1.2]$ mysql -uroot -p

若是报以下错误:

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

则在/etc/my.cnf文件中添加如下内容:

[mysql]
socket=/var/lib/mysql/mysql.sock
[client]
socket=/var/lib/mysql/mysql.sock

再重启MySQL服务:

[hyj@hadoop102 hive-3.1.2]$ sudo systemctl restart mysqld.service

10)必须先修改root用户的密码,否则执行其他的操作会报错
set password=password("新密码");

mysql> set password=password("123456");

11)修改mysql库下的user表中的root用户允许任意ip连接

mysql> update mysql.user set host='%' where user='root';

mysql> flush privileges;  #刷新权限

返回顶部

Hive元数据配置到MySQL (本地模式)

本地模式和内嵌模式最大的区别就是:本地模式使用mysql来存储元数据。

  1. 拷贝驱动
    将MySQL的JDBC驱动mysql-connector-java-5.1.32.jar上传到Hive的lib目录下
  2. 配置Metastore到MySQL
    1)在$HIVE_HOME/conf目录下新建hive-site.xml文件
[hyj@hadoop102 conf]$ vim hive-site.xml

添加如下内容:

<?xml version="1.0"?> 
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?> 
<configuration>  
	<!-- jdbc连接的URL -->  
	<property>  
		<name>javax.jdo.option.ConnectionURL</name>  
		<value>jdbc:mysql://hadoop102:3306/metastore?useSSL=false</value> 
	</property>   
	<!-- jdbc连接的Driver--> 
	<property>  
 		<name>javax.jdo.option.ConnectionDriverName</name>  
 		<value>com.mysql.jdbc.Driver</value>
   </property>  
   <!-- jdbc连接的username--> 
   <property> 
       <name>javax.jdo.option.ConnectionUserName</name> 
       <value>root</value> 
   </property>   
   <!-- jdbc连接的password -->  
   <property> 
      <name>javax.jdo.option.ConnectionPassword</name>  
      <value>123456</value> 
   </property> 
   <!-- 关闭Hive元数据存储版本的验证 -->  
   <property> 
      <name>hive.metastore.schema.verification</name>  
      <value>false</value> 
   </property> 
   <!--关闭元数据存储授权-->  
   <property>  
   		<name>hive.metastore.event.db.notification.api.auth</name>  
        <value>false</value> 
    </property> 
    <!-- Hive默认在HDFS的工作目录 --> 
    <property> 
        <name>hive.metastore.warehouse.dir</name>  
        <value>/user/hive/warehouse</value>
     </property> 
</configuration> 

2)登陆MySQL

[hyj@hadoop102 hive-3.1.2]$ mysql -uroot -p123456

3)新建Hive元数据库

mysql> create database metastore;
mysql> quit;

4) 初始化Hive元数据库

[hyj@hadoop102 hive-3.1.2]$ schematool -dbType mysql -initSchema -verbose

初始化成功会在mysql中创建74张表.
3) 再次启动Hive (本地模式)
1)启动Hive

[hyj@hadoop102 hive-3.1.2]$ bin/hive

2)使用Hive

hive> show databases; 
hive> show tables; 
hive> create table test (id int); 
hive> insert into test values(1); 
hive> select * from test; 

3)在CRT窗口中开启另一个窗口开启Hive

[hyj@hadoop102 hive-3.1.2]$ bin/hive
hive> show databases; 
hive> show tables; 

返回顶部

使用元数据服务的方式访问Hive (远程模式)

1)在hive-site.xml文件中添加如下配置信息

<!-- 指定存储元数据要连接的地址/远程模式部署metastore 服务地址 -->  
<property>  
	<name>hive.metastore.uris</name>  
	<value>thrift://hadoop102:9083</value>  
</property> 

2)启动metastore
如果在远程模式下,直接运行hive服务,在执行操作的时候会报错.
在远程模式下,必须先启动Hive metastore服务才可以使用hive。因为metastore服务和hive server是两个单独的进程了

#前台启动  关闭ctrl+c
[hyj@hadoop102 hive-3.1.2]$ hive --service metastore

注意: 启动后窗口不能再操作,需打开一个新的shell窗口做别的操作
或:

#后台启动,进程挂起    关闭使用jps+kill
#输入命令回车执行 再次回车 进程将挂起后台
[hyj@hadoop102 hive-3.1.2]$ nohup hive --service metastore &
[1] 11804
[hyj@hadoop102 hive-3.1.2]$ nohup: 忽略输入并把输出追加到"nohup.out"

#前台启动开启debug日志(修改日志级别为debug)
[hyj@hadoop102 hive-3.1.2]$ hive --service metastore --hiveconf hive.root.logger=DEBUG,console

后台启动的输出日志信息,在$HIVE_HOME目录下,nohup.out。
在这里插入图片描述

3)启动 hive

[hyj@hadoop102 hive-3.1.2]$ bin/hive

返回顶部

使用JDBC方式访问Hive (远程模式)

1)在hive-site.xml文件中添加如下配置信息

<!-- 指定hiveserver2连接的host -->  
<property>  
	<name>hive.server2.thrift.bind.host</name> 
	<value>hadoop102</value>  
</property>   
<!-- 指定hiveserver2连接的端口号 --> 
<property>  
	 <name>hive.server2.thrift.port</name>  
 	 <value>10000</value>  
</property>

2)启动metastore

#前台启动
[hyj@hadoop102 hive-3.1.2]$ hive --service metastore
或

#后台启动,进程挂起    关闭使用jps+kill
#输入命令回车执行 再次回车 进程将挂起后台
[hyj@hadoop102 hive-3.1.2]$ nohup hive --service metastore &
[1] 14725
[hyj@hadoop102 hive-3.1.2]$ nohup: 忽略输入并把输出追加到"nohup.out"

3)启动hiveserver2

[hyj@hadoop102 hive-3.1.2]$ bin/hive --service hiveserver2
或
[hyj@hadoop102 hive-3.1.2]$ nohup bin/hive --service hiveserver2 &
[1] 14861
[hyj@hadoop102 hive-3.1.2]$ nohup: 忽略输入并把输出追加到"nohup.out"

4)启动beeline客户端(需要多等待一会才能启动beeline客户端)

[hyj@hadoop102 hive-3.1.2]$ bin/beeline -u jdbc:hive2://hadoop102:10000 -n hyj

要是报以下错误:

[hyj@hadoop102 hive-3.1.2]$ bin/beeline -u jdbc:hive2://hadoop102:10000 -n hyj
Connecting to jdbc:hive2://hadoop102:10000
2022-05-23 12:53:32,643 WARN  [main] jdbc.HiveConnection (HiveConnection.java:<init>(237)) - Failed to connect to hadoop102:10000
Error: Could not open client transport with JDBC Uri: jdbc:hive2://hadoop102:10000: Failed to open new session: java.lang.RuntimeException: org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.authorize.AuthorizationException): User: hyj is not allowed to impersonate hyj (state=08S01,code=0)
Beeline version 3.1.2 by Apache Hive

解决办法:则

  1. 在hadoop的core-site.xml文件中添加以下内容:
    (注意:将以下配置文件中出现的hyj改成自己的用户名)
<!-- 配置该hyj(superUser)允许通过代理访问的主机节点 -->
<property>
	<name>hadoop.proxyuser.hyj.hosts</name>
    <value>*</value>
</property>
<!-- 配置该hyj(superUser)允许通过代理用户所属组 -->
<property>
    <name>hadoop.proxyuser.hyj.groups</name>
    <value>*</value>
</property>

  1. 在hadoop的hdfs-site.xml文件中添加如下内容:
<property>
	<name>dfs.webhdfs.enabled</name>
    <value>true</value>
</property>
  1. 最后分发这两个文件,重新启动hadoop集群.

4)看到如下界面 (则成功)

Connecting to jdbc:hive2://hadoop102:10000
Connected to: Apache Hive (version 3.1.2)
Driver: Hive JDBC (version 3.1.2)
Transaction isolation: TRANSACTION_REPEATABLE_READ
Beeline version 3.1.2 by Apache Hive
0: jdbc:hive2://hadoop102:10000> 

[hyj@hadoop102 hive-3.1.2]$ bin/beeline

在这里插入图片描述

5)编写hive服务启动脚本(了解)
(1) 前台启动的方式导致需要打开多个shell窗口,可以使用如下方式后台方式启动
nohup: 放在命令开头,表示不挂起,也就是关闭终端进程也继续保持运行状态 .
/dev/null:是Linux文件系统中的一个文件,被称为黑洞,所有写入该文件的内容都会被自动丢弃 .
2>&1 : 表示将错误重定向到标准输出上 .
&: 放在命令结尾,表示后台运行 .
一般会组合使用: nohup [xxx命令操作]> file 2>&1 &,表示将xxx命令运行的结果输出到file中,并保持命令启动的进程在后台运行。
如上命令不要求掌握
(2) 为了方便使用,可以直接编写脚本来管理服务的启动和关闭

[hyj@hadoop102 hive-3.1.2]$ cd bin/
[hyj@hadoop102 bin]$ vim hiveservices.sh 

内容如下:此脚本的编写不要求掌握。直接拿来使用即可。

#!/bin/bash 
HIVE_LOG_DIR=$HIVE_HOME/logs 
if [ ! -d $HIVE_LOG_DIR ] 
then  
	mkdir -p $HIVE_LOG_DIR 
fi
#检查进程是否运行正常,参数1为进程名,参数2为进程端口 
function check_process() 
{  
	pid=$(ps -ef 2>/dev/null | grep -v grep | grep -i $1 | awk '{print 
$2}')  
	ppid=$(netstat -nltp 2>/dev/null | grep $2 | awk '{print $7}' | cut -
d '/' -f 1)  
	echo $pid  
	[[ "$pid" =~ "$ppid" ]] && [ "$ppid" ] && return 0 || return 1 
}  
function hive_start() 
{  
	metapid=$(check_process HiveMetastore 9083)  
	cmd="nohup hive --service metastore >$HIVE_LOG_DIR/metastore.log 2>&1 
&"  
	[ -z "$metapid" ] && eval $cmd || echo "Metastroe服务已启动"  
	server2pid=$(check_process HiveServer2 10000)  
	cmd="nohup hiveserver2 >$HIVE_LOG_DIR/hiveServer2.log 2>&1 &"  
	[ -z "$server2pid" ] && eval $cmd || echo "HiveServer2服务已启动" 
}  
function hive_stop() 
{ 
	metapid=$(check_process HiveMetastore 9083) 
	[ "$metapid" ] && kill $metapid || echo "Metastore服务未启动"  
	server2pid=$(check_process HiveServer2 10000)  
	[ "$server2pid" ] && kill $server2pid || echo "HiveServer2服务未启动" 
}  
case $1 in 
"start")  
	hive_start  
;; 
"stop")  
	hive_stop  
;; 
"restart")  
	hive_stop  
	sleep 2  
	hive_start 
;; 
"status")  
	check_process HiveMetastore 9083 >/dev/null && echo "Metastore服务运行
正常" || echo "Metastore服务运行异常"  
	check_process HiveServer2 10000 >/dev/null && echo "HiveServer2服务运
行正常" || echo "HiveServer2服务运行异常"  
;; 
*)  
	echo Invalid Args!  
	echo 'Usage: '$(basename $0)' start|stop|restart|status'  
;; 
esac 

3)添加执行权限

[hyj@hadoop102 bin]$ chmod +x hiveservices.sh

4)启动Hive后台服务

[hyj@hadoop102 bin]$ hiveservices.sh start

返回顶部

Hive客户端使用

Hive Client、Hive Beeline Client

当$HIVE_HOME/bin/hive与-e或-f选项一起运行时,它以批处理模式执行 SQL 命令;在没有-e或-f选项的情况下运行时,它将进入交互式 shell 模式

Hive发展至今,总共历经了两代客户端工具。

  1. 第一代客户端(deprecated不推荐使用):$HIVE_HOME/bin/hive, 是一个 shellUtil。主要功能:一是可用于以交互或批处理模式运行Hive查询;二是用于Hive相关服务的启动,比如metastore服务。
  2. 第二代客户端(recommended 推荐使用):$HIVE_HOME/bin/beeline,是一个JDBC客户端,是官方强烈推荐使用的Hive命令行工具,和第一代客户端相比,性能加强安全性提高。

Beeline Shell在嵌入式模式和远程模式下均可工作。在嵌入式模式下,它运行嵌入式 Hive(类似于Hive Client),而远程模式下beeline通过 Thrift 连接到单独的 HiveServer2 服务上,这也是官方推荐在生产环境中使用的模式。

beeline是二代新客户端,hive是一代旧客户端.
在这里插入图片描述

HiveServer、HiveServer2服务

HiveServer、HiveServer2都是Hive自带的两种服务,允许客户端在不启动CLI的情况下对Hive中的数据进行操作,且两个都允许远程客户端使用多种编程语言如java,python等向hive提交请求,取回结果。
但是,HiveServer不能处理多于一个客户端的并发请求。因此在Hive-0.11.0版本中重写了HiveServer代码得到了HiveServer2,进而解决了该问题。HiveServer已经被废弃。
HiveServer2支持多客户端的并发和身份认证,旨在为开放API客户端如JDBC、ODBC提供更好的支持。

Hive服务和客户端关系梳理

HiveServer2通过Metastore服务读写元数据。所以在远程模式下,启动HiveServer2之前必须先启动metastore服务。
特别注意:远程模式下,Beeline客户端只能通过HiveServer2服务访问Hive。而Hive Client是通过Metastore服务访问的
具体关系如下:
在这里插入图片描述

Hive Client使用

在hive安装包的bin目录下,有hive提供的第一代客户端 bin/hive。该客户端可以访问hive的metastore服务,从而达到操作hive的目的。
如果您是远程模式部署,请手动启动运行metastore服务。如果是内嵌模式和本地模式,直接运行bin/hive,metastore服务会内嵌一起启动。

  1. 可以直接在启动Hive metastore服务的机器上使用bin/hive客户端操作,此时不需要进行任何配置。
#远程模式 首先启动metastore服务
[hyj@hadoop102 hive-3.1.2]$ hive --service metastore
#克隆CRT会话窗口 使用hive client连接
[hyj@hadoop102 hive-3.1.2]$ bin/hive
  1. 如果需要在其他机器上通过bin/hive访问hive metastore服务,只需要在该机器的hive-site.xml配置中添加metastore服务地址即可。
#1.上传hive安装包到另一台机器的/opt/software目录下,比如hadoop103
[hyj@hadoop103 ~]$ cd /opt/software/
#2.解压apache-hive-3.1.2-bin.tar.gz到/opt/module/目录下
[hyj@hadoop103 software]$ tar -zxvf apache-hive-3.1.2-bin.tar.gz -C /opt/module/
[hyj@hadoop103 software]$ cd /opt/module/
#3.修改apache-hive-3.1.2-bin的名称为hive-3.1.2
[hyj@hadoop103 module]$ mv apache-hive-3.1.2-bin/ hive-3.1.2
#4.修改/etc/profile.d/my_env.sh,添加hive环境变量
[hyj@hadoop103 module]$ sudo vim /etc/profile.d/my_env.sh

#HIVE_HOME 
export HIVE_HOME=/opt/module/hive-3.1.2
export PATH=$PATH:$HIVE_HOME/bin 

#5.source一下,让环境变量生效
[hyj@hadoop102 module]$ source /etc/profile
#6.解决日志Jar包冲突
[hyj@hadoop103 lib]$ mv log4j-slf4j-impl-2.10.0.jar log4j-slf4j-impl-2.10.0.bak
#7.添加metastore服务地址
[hyj@hadoop103 lib]$ cd /opt/module/hive-3.1.2/conf/
[hyj@hadoop103 conf]$ vim hive-site.xml

<configuration>
<!-- 指定存储元数据要连接的地址/远程模式部署metastore 服务地址 -->
<property>  
        <name>hive.metastore.uris</name>  
        <value>thrift://hadoop102:9083</value>  
</property> 
</configuration>
#8.启动hive
[hyj@hadoop103 hive-3.1.2]$ bin/hive

Hive Beeline Client使用

hive经过发展,推出了第二代客户端beeline,但是beeline客户端不是直接访问metastore服务的,而是需要单独启动hiveserver2服务。
在hive运行的服务器上,先启动metastore服务,然后启动hiveserver2服务。
在hadoop103上使用beeline客户端进行连接访问。
需要注意hiveserver2服务启动之后需要稍等一会才可以对外提供服务。
Beeline是JDBC的客户端,通过JDBC协议和Hiveserver2服务进行通信,协议的地址是:jdbc:hive2://hadoop102:10000

#先启动metastore服务 然后启动hiveserver2服务
[hyj@hadoop102 hive-3.1.2]$ hive --service metastore
[hyj@hadoop102 hive-3.1.2]$ nohup bin/hive --service hiveserver2 &
[hyj@hadoop103 hive-3.1.2]$ bin/beeline -u jdbc:hive2://hadoop102:10000 -n hyj

或

[hyj@hadoop103 hive-3.1.2]$ bin/beeline
Beeline version 3.1.2 by Apache Hive
beeline> ! connect jdbc:hive2://hadoop102:10000  #访问hiveserver2协议
Connecting to jdbc:hive2://hadoop102:10000
Enter username for jdbc:hive2://hadoop102:10000: hyj   #用户名(要求具备hdfs权限)
Enter password for jdbc:hive2://hadoop102:10000:   #密码可为空
Connected to: Apache Hive (version 3.1.2)
Driver: Hive JDBC (version 3.1.2)
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://hadoop103:10000> 

返回顶部

Hive常用命令

$HIVE_HOME/bin/hive是一个shellUtil,通常称之为hive的第一代客户端或者旧客户端,主要功能有两个:

  1. 用于以交互式批处理模式运行Hive查询,注意,此时作为客户端,需要并且能够访问的是Hive metastore服务,而不是hiveserver2服务。
  2. 用于hive相关服务的启动,比如metastore服务。

可以通过运行hive -H或者hive --help来查看命令行选项。

[hyj@hadoop102 hive-3.1.2]$ bin/hive -help
2022-05-23 13:28:10,586 INFO  [main] conf.HiveConf (HiveConf.java:findConfigFile(187)) - Found configuration file file:/opt/module/hive-3.1.2/conf/hive-site.xml
Hive Session ID = 035ca1ed-5d88-4a7c-ad3a-b76c7331be43
2022-05-23 13:28:12,118 INFO  [main] SessionState (SessionState.java:printInfo(1227)) - Hive Session ID = 035ca1ed-5d88-4a7c-ad3a-b76c7331be43
usage: hive
 -d,--define <key=value>          Variable substitution to apply to Hive
                                  commands. e.g. -d A=B or --define A=B
    --database <databasename>     Specify the database to use
 -e <quoted-query-string>         SQL from command line
 -f <filename>                    SQL from files
 -H,--help                        Print help information
    --hiveconf <property=value>   Use value for given property
    --hivevar <key=value>         Variable substitution to apply to Hive
                                  commands. e.g. --hivevar A=B
 -i <filename>                    Initialization SQL file
 -S,--silent                      Silent mode in interactive shell
 -v,--verbose                     Verbose mode (echo executed SQL to the
                                  console)
选项说明
-e <quoted-query-string> 执行命令行-e参数后指定的sql语句,运行完退出
-f <filename>执行命令行-f参数后指定的sql文件,运行完退出
-H,- -help打印帮助信息
--hiveconf <property=value>设置参数
-S,- -silent静默模式,不打印MapReduce输出信息
-v,- -verbose详细模式,将执行sql回显到控制台
--service service_name启动hive的相关服务

当使用-e或-f选项运行$ HIVE_HOME / bin / hive时,它将以批处理模式执行SQL命令。所谓的批处理可以理解为一次性执行,执行完毕退出
所谓交互式模式可以理解为客户端和hive服务一直保持连接,除非手动退出客户端
1)“-e”不进入hive的交互窗口执行sql语句

[hyj@hadoop102 hive-3.1.2]$ bin/hive -e "create table student(id int,name string);"

我实在是忍不了:在使用hive shell时,会发现在查询命令中夹杂大量的日志信息,严重干扰查询结果显示.
解决办法:
在 Hive 安装目录的 conf 目录下创建出 log4j.properties 日志配置文件,添加如下内容:

log4j.rootLogger=WARN, CA
log4j.appender.CA=org.apache.log4j.ConsoleAppender
log4j.appender.CA.layout=org.apache.log4j.PatternLayout
log4j.appender.CA.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

然后重启hive后台服务:

[hyj@hadoop102 conf]$ hiveservices.sh restart

2)“-f”执行脚本中sql语句
(1)在/opt/module/hive-3.1.2/下创建datas目录并在datas目录下创建hivef.sql文件

[hyj@hadoop102 datas]$ vim hivef.sql 

(2)文件中写入正确的sql语句

select *from student; 

(3)执行文件中的sql语句

[hyj@hadoop102 hive-3.1.2]$ bin/hive -f /opt/module/hive-3.1.2/datas/hivef.sql

(4)执行文件中的sql语句并将结果写入文件中

[hyj@hadoop102 hive-3.1.2]$ bin/hive -f /opt/module/hive-3.1.2/datas/hivef.sql > /opt/module/hive-3.1.2/datas/hive_result.txt

3)"-S"静默模式,不打印MapReduce输出信息

[hyj@hadoop102 hive-3.1.2]$ bin/hive -S -e 'select count(*) from student;'

4)"-v"详细模式,将执行sql回显到控制台

[hyj@hadoop102 hive-3.1.2]$ bin/hive -S -v -e 'select count(*) from student;'
select count(*) from student --可以在控制台看到这句话

返回顶部

Hive其他命令操作

1)退出hive窗口:

hive> exit;
hive> quit;

2)在hive cli命令窗口中如何查看hdfs文件系统

hive> dfs -ls /;
drwxr-xr-x   - hyj supergroup          0 2022-04-09 14:07 /HBase
drwxr-xr-x   - hyj supergroup          0 2022-05-19 22:49 /flink
drwxr-xr-x   - hyj supergroup          0 2022-03-20 23:26 /input
drwxr-xr-x   - hyj supergroup          0 2022-03-27 22:53 /output
drwx------   - hyj supergroup          0 2022-03-26 16:56 /tmp
drwxr-xr-x   - hyj supergroup          0 2022-05-21 14:55 /user
hive> dfs -ls /flink;
Found 1 items
drwxr-xr-x   - hyj supergroup          0 2022-05-19 22:49 /flink/standalone

3)查看在hive中输入的所有历史命令
(1)进入到当前用户的根目录 /root或/home/hyj
(2)查看. hivehistory文件

[hyj@hadoop102 hive-3.1.2]$ cd
[hyj@hadoop102 ~]$ cat .hivehistory

返回顶部

Hive常见属性配置

  1. Hive运行日志信息配置
    1)Hive的log默认存放在/tmp/hyj/hive.log(当前用户名下)
    2)修改hive的log存放日志到/opt/module/hive-3.1.2/logs
    (1)修改/opt/module/hive-3.1.2/conf/hive-log4j2.properties.template文件名称为 hive-log4j2.properties
[hyj@hadoop102 conf]$ mv hive-log4j2.properties.template hive-log4j2.properties

(2)在hive-log4j2.properties文件中修改log存放位置

[hyj@hadoop102 conf]$ vim hive-log4j2.properties 
property.hive.log.dir = /opt/module/hive-3.1.2/logs
  1. 打印 当前库 和 表头
    在hive-site.xml中加入如下两个配置:
<property>  
	<name>hive.cli.print.header</name>  
	<value>true</value>  
</property>   
<property>  
	<name>hive.cli.print.current.db</name>  
	<value>true</value>  
</property> 

在这里插入图片描述

  1. 参数配置方式
    1)查看当前所有的配置信息
hive>set; 

2)参数的配置三种方式
(1)配置文件方式
默认配置文件:hive-default.xml
用户自定义配置文件:hive-site.xml
注意:用户自定义配置会覆盖默认配置。另外,Hive也会读入Hadoop的配置,因为Hive是作为Hadoop的客户端启动的,Hive的配置会覆盖Hadoop的配置。
配置文件的设定对本机启动的所有Hive进程都有效。
(2)命令行参数方式
启动Hive时,可以在命令行添加-hiveconf param=value来设定参数。
例如:

[hyj@hadoop102 hive-3.1.2]$ bin/hive -hiveconf mapred.reduce.tasks=10;

注意:仅对本次hive启动有效
查看参数设置:

hive (default)> set mapred.reduce.tasks;
mapred.reduce.tasks=10

(3)参数声明方式
在Hive CLI或Beeline中使用set命令为set命令之后的所有SQL语句设置配置参数,这个也是会话级别的。

hive (default)> set mapred.reduce.tasks=15;

查看参数设置 :

hive (default)> set mapred.reduce.tasks;
mapred.reduce.tasks=15

上述三种设定方式的优先级依次递增。即配置文件<命令行参数<参数声明。注意某些系统级的参数,例如log4j相关的设定,必须用前两种方式设定,因为那些参数的读取在会话建立以前已经完成了。
(4) 服务器特定的配置文件

  1. 您可以设置metastore的配置在hivemetastore-site.xml中,设置HiveServer2的配置在hiveserver2-site.xml中。
  2. Hive Metastore服务器会加载可用的hive-site.xml以及hivemetastore-site.xml配置文件
  3. HiveServer2读取会加载可用的hive-site.xml以及hiveserver2-site.xml
  4. 如果HiveServer2以嵌入式模式使用元存储,则还将加载hivemetastore-site.xml

    配置文件的优先顺序如下,后面的优先级越高:
    hive-site.xml-> hivemetastore-site.xml-> hiveserver2-site.xml-> -hiveconf命令行参数->set参数

返回顶部

Hive数据类型

基本数据类型

Hive SQL中,数据类型英文字母大小写不敏感; 在这里插入图片描述
对于Hive的String类型相当于数据库的varchar类型,该类型是一个可变的字符串,不过它不能声明其中最多能存储多少个字符,理论上它可以存储2GB的字符数。

Hive支持的原生数据类型如下:
在这里插入图片描述
官网链接:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types
注意:如果建表定义的数据类型和文件不一致,hive会尝试隐式转换,但是不保证成功。不成功显示null。

集合数据类型

在这里插入图片描述

Hive有三种复杂数据类型:array数组、map映射、struct结构。ARRAY和MAP与Java中的Array和Map类似,而STRUCT与C语言中的Struct类似,它封装了一个命名字段集合,复杂数据类型允许任意层次的嵌套。
1)案例实操
(1)假设某表有如下一行,我们用JSON格式来表示其数据结构。在Hive下访问的格式为

{  
	"name": "songsong",  
    "friends": ["bingbing" , "lili"] , //列表Array, 
    "children": { //键值Map, 
    "xiao song": 18 ,  
    "xiaoxiao song": 19  
    } 
    "address": { //结构Struct, 
    "street": "hui long guan",  
    "city": "beijing" 
    } 
} 

(2)基于上述数据结构,我们在Hive里创建对应的表,并导入数据。
在/opt/module/hive-3.1.2/datas目录下创建本地测试文件test.txt

[hyj@hadoop102 datas]$ vim test.txt

添加如下内容:

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 

注意:MAP,STRUCT和ARRAY里的元素间关系都可以用同一个字符表示,这里用_
(3)Hive上创建测试表test

hive (default)> create table test( 
              > name string, 
              > friends array<string>, 
              > children map<string, int>, 
              > address struct<street:string, city:string> ) 
              > row format delimited 
              > fields terminated by ',' 
              > collection items terminated by '_' 
              > map keys terminated by ':' 
              > lines terminated by '\n'; 

字段解释:
Hive建表时如果没有row format语法指定分隔符,则采用默认分隔符;
默认的分割符是’\001’,是一种特殊的字符,使用的是ASCII编码的值,键盘是打不出来的。

fields terminated by ',' 字段之间分隔符
collection items terminated by '_' MAP,STRUCT 和 ARRAY 的分隔符(集合元素之间分隔符)
map keys terminated by ':' MAP中的key与value的分隔符
lines terminated by '\n' 行分隔符

建表成功之后,在Hive的默认存储路径下就生成了表对应的文件夹;
把test.txt文件上传到对应的表文件夹下。
(4)执行命令把文件上传到HDFS表所对应的目录下

[hyj@hadoop102 datas]$ hadoop fs -put test.txt /user/hive/warehouse/test

(5)访问三种集合列里的数据,以下分别是ARRAY,MAP,STRUCT的访问方式

hive (default)> select friends[1],children['xiao song'],address.city from test where name="songsong";

_c0	_c1	city
lili	18	beijing 

返回顶部

类型转化

Hive的原生数据类型是可以进行隐式转换的,类似于Java的类型转换,例如某表达式使用INT类型,TINYINT会自动转换为INT类型,但是Hive不会进行反向转化,例如,某表达式使用TINYINT类型,INT不会自动转换为TINYINT类型,它会返回错误,除非使用CAST操作。

  1. 隐式类型转换规则如下
    (1)任何整数类型都可以隐式地转换为一个范围更广的类型,如TINYINT可以转换成INT,INT可以转换成BIGINT。
    (2)所有整数类型、FLOAT和STRING类型都可以隐式地转换成DOUBLE。
    (3)TINYINT、SMALLINT、INT都可以转换为FLOAT。
    (4)BOOLEAN类型不可以转换为任何其它的类型。
  2. 可以使用CAST操作显式进行数据类型转换
    例如CAST(‘1’ AS INT)将把字符串’1’ 转换成整数1;如果强制类型转换失败,如执行CAST(‘X’ AS INT),表达式返回空值 NULL。
hive (default)> select '1'+2,cast('1' as int)+2;
_c0	_c1
3.0	3

hive (default)> select cast('66.34' as int),cast('hive' as int);
_c0	_c1
66	NULL

返回顶部

Hive读写文件机制

SerDe是什么

SerDe是Serializer、Deserializer的简称,目的是用于序列化和反序列化。序列化是对象转化为字节码的过程;而反序列化是字节码转换为对象的过程。
Hive使用SerDe(和FileFormat)读取和写入行对象。
在这里插入图片描述

需要注意的是,“key”部分在读取时会被忽略,而在写入时key始终是常数。基本上行对象存储在“value”中
可以通过desc formatted tablename查看表的相关SerDe信息。默认如下:
在这里插入图片描述

Hive读写文件流程

  1. Hive读取文件机制:首先调用InputFormat(默认TextInputFormat),返回一条一条kv键值对记录(默认是一行对应一条记录)。然后调用SerDe(默认LazySimpleSerDe)的Deserializer,将一条记录中的value根据分隔符切分为各个字段。
  2. Hive写文件机制:将Row写入文件时,首先调用SerDe(默认LazySimpleSerDe)的Serializer将对象转换成字节序列,然后调用OutputFormat将数据写入HDFS文件中。

SerDe相关语法

在Hive的建表语句中,和SerDe相关的语法为:
在这里插入图片描述
其中ROW FORMAT是语法关键字,DELIMITED和SERDE二选其一。
如果使用delimited表示使用默认的LazySimpleSerDe类来处理数据。如果数据文件格式比较特殊可以使用ROW FORMAT SERDE serde_name指定其他的Serde类来处理数据,甚至支持用户自定义SerDe类。

LazySimpleSerDe分隔符指定

LazySimpleSerDe是Hive默认的序列化类,包含4种子语法,分别用于指定字段之间、集合元素之间、map映射 kv之间、换行的分隔符号。在建表的时候可以根据数据的特点灵活搭配使用。
在这里插入图片描述
返回顶部

默认分隔符

hive建表时如果没有row format语法。此时字段之间默认的分割符是'\001',是一种特殊的字符,使用的是ascii编码的值,键盘是打不出来的。

  1. 在vim编辑器中,先按下Ctrl+v,再按Ctrl+a即可输入’\001’ ,显示^A
  2. 在一些文本编辑器中将以SOH的形式显示

DDL数据定义

定义

数据定义语言 (Data Definition Language, DDL),是SQL语言集中对数据库内部的对象结构进行创建删除修改等的操作语言,这些数据库对象包括database(schema)、table、view、index等。核心语法由CREATEALTERDROP三个所组成。DDL并不涉及表内部数据的操作。

创建数据库

在Hive中, DATABASE和SCHEMA是可互换的,使用DATABASE或SCHEMA都可以。

CREATE DATABASE|SCHEMA [IF NOT EXISTS] database_name 
[COMMENT database_comment] 
[LOCATION hdfs_path] 
[WITH DBPROPERTIES (property_name=property_value, ...)]; 

COMMENT:数据库的注释说明语句
LOCATION:指定数据库在HDFS存储位置,默认/user/hive/warehouse
WITH DBPROPERTIES:用于指定一些数据库的属性配置。

hive (default)> create schema if not exists test
              > comment "this is my first database"
              > location '/test.db'
              > with dbproperties('createBy'='xiaohuo');

1)创建一个数据库,数据库在HDFS上的默认存储路径是/user/hive/warehouse/*.db。

hive (default)> create database db_hive;

2)避免要创建的数据库已经存在错误,增加if not exists判断。(标准写法)

hive (default)> create database db_hive;
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Database db_hive already exists
332699 [e82cef4c-275b-4f48-a005-22f94dfa44f0 main] ERROR org.apache.hadoop.hive.ql.Driver  - FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Database db_hive already exists
hive (default)> create database if not exists db_hive;
OK
Time taken: 0.029 seconds

3)创建一个数据库,指定数据库在HDFS上存放的位置

hive (default)> create database db_hive2 location '/db_hive2.db';

查询数据库

  1. 显示数据库
    1)显示所有的数据库
hive (default)> show databases;

2)过滤显示查询的数据库

hive (default)> show databases like 'db_hive*';
  1. 查看数据库详情
    Hive中的DESCRIBE DATABASE语句用于显示Hive中数据库的名称,其注释(如果已设置)及其在文件系统上的位置等信息
DESCRIBE DATABASE/SCHEMA [EXTENDED] db_name;

1)显示数据库信息

hive (default)> desc database test;
OK
db_name	comment	location	owner_name	owner_type	parameters
test	this is my first database	hdfs://hadoop102:8020/test.db	hyj	USER	

2)显示数据库详细信息,extended:用于显示更多信息。

hive (default)> desc database extended db_hive;
OK
db_name	comment	location	owner_name	owner_type	parameters
db_hive		hdfs://hadoop102:8020/user/hive/warehouse/db_hive.db	hyj	USER	
Time taken: 0.041 seconds, Fetched: 1 row(s)
hive (default)> desc database extended test;
OK
db_name	comment	location	owner_name	owner_type	parameters
test	this is my first database	hdfs://hadoop102:8020/test.db	hyj	USER	{createBy=xiaohuo}
Time taken: 0.019 seconds, Fetched: 1 row(s)
  1. 切换当前数据库
hive (default)> use db_hive;

返回顶部

查看当前使用的数据库

select current_database(); 

修改数据库

Hive中的ALTER DATABASE语句用于更改与Hive中的数据库关联的元数据

--更改数据库属性
ALTER (DATABASE|SCHEMA) database_name SET DBPROPERTIES (property_name=property_value, ...);

--更改数据库所有者
ALTER (DATABASE|SCHEMA) database_name SET OWNER [USER|ROLE] user_or_role;

--更改数据库位置
ALTER (DATABASE|SCHEMA) database_name SET LOCATION hdfs_path;

用户可以使用ALTER DATABASE命令为某个数据库的DBPROPERTIES设置键-值对属性值,来描述这个数据库的属性信息。

hive (default)> alter database db_hive set dbproperties('createtime'='20220523');

在hive中查看修改结果

Time taken: 0.078 seconds
hive (default)> desc database extended db_hive;
OK
db_name	comment	location	owner_name	owner_type	parameters
db_hive		hdfs://hadoop102:8020/user/hive/warehouse/db_hive.db	hyj	USER	{createtime=20220523}

hive (default)> desc database db_hive;
OK
db_name	comment	location	owner_name	owner_type	parameters
db_hive		hdfs://hadoop102:8020/user/hive/warehouse/db_hive.db	hyj	USER	
hive (default)> alter database test set dbproperties('createtime'='20220523');
OK
Time taken: 0.065 seconds
hive (default)> desc database extended test;
OK
db_name	comment	location	owner_name	owner_type	parameters
test	this is my first database	hdfs://hadoop102:8020/test.db	hyj	USER	{createBy=xiaohuo, createtime=20220523}
Time taken: 0.016 seconds, Fetched: 1 row(s)
hive (default)> alter database test set dbproperties('createtime'='20220721');
OK
Time taken: 0.039 seconds
hive (default)> desc database extended test;
OK
db_name	comment	location	owner_name	owner_type	parameters
test	this is my first database	hdfs://hadoop102:8020/test.db	hyj	USER	{createBy=xiaohuo, createtime=20220721}

更改数据库位置

hive (test)> alter database test set location 'hdfs://hadoop102:8020/user/hive/warehouse/test.db';

返回顶部

删除数据库

Hive中的DROP DATABASE语句用于删除数据库。
默认行为是RESTRICT,这意味着仅在数据库为空时才删除它。要删除带有表的数据库,我们可以使用CASCADE强制删除

DROP (DATABASE|SCHEMA) [IF EXISTS] database_name [RESTRICT|CASCADE];

1)删除空数据库

hive (default)> drop database db_hive;

2)如果删除的数据库不存在,最好采用 if exists判断数据库是否存在

hive (default)> drop database db_hive;
FAILED: SemanticException [Error 10072]: Database does not exist: db_hive
2563873 [e82cef4c-275b-4f48-a005-22f94dfa44f0 main] ERROR org.apache.hadoop.hive.ql.Driver  - FAILED: SemanticException [Error 10072]: Database does not exist: db_hive
hive (default)> drop database if exists db_hive;

3)如果数据库不为空,可以采用cascade命令,强制删除

hive (default)> drop database db_hive2;
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. InvalidOperationException(message:Database db_hive2 is not empty. One or more tables exist.)
2735221 [e82cef4c-275b-4f48-a005-22f94dfa44f0 main] ERROR org.apache.hadoop.hive.ql.Driver  - FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. InvalidOperationException(message:Database db_hive2 is not empty. One or more tables exist.)
hive (default)> drop database db_hive2 cascade;

创建表

  1. 建表语法
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name 
[(col_name data_type [COMMENT col_comment], ...)] 
[COMMENT table_comment] 
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)] 
[CLUSTERED BY (col_name, col_name, ...) 
[SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS] 
[ROW FORMAT row_format] 
[STORED AS file_format] 
[LOCATION hdfs_path] 
[TBLPROPERTIES (property_name=property_value, ...)] 
[AS select_statement] 
  1. 字段解释说明
    (1)CREATE TABLE 创建一个指定名字的表。如果相同名字的表已经存在,则抛出异常;用户可以用 IF NOT EXISTS 选项来忽略这个异常。
    (2)EXTERNAL关键字可以让用户创建一个外部表,在建表的同时可以指定一个指向实际数据的路径(LOCATION),在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据
    (3)COMMENT:为表和列添加注释。
    (4)PARTITIONED BY创建分区表
    (5)CLUSTERED BY创建分桶表
    (6)SORTED BY不常用,对桶中的一个或多个列另外排序
    (7)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。在建表的时候,用户还需要为表指定列,用户在指定表的列的同时也会指定自定义的SerDe,Hive通过SerDe确定表的具体的列的数据
    SerDe是Serialize/Deserilize的简称, hive使用Serde进行对象的序列与反序列化。
    (8)STORED AS指定存储文件类型
    常用的存储文件类型:SEQUENCEFILE(二进制序列文件)、TEXTFILE(文本)、RCFILE(列式存储格式文件) 如果文件数据是纯文本,可以使用STORED AS TEXTFILE。如果数据需要压缩,使用 STORED AS SEQUENCEFILE。
    (9)LOCATION :指定表在HDFS上的存储位置。
    (10)AS:后跟查询语句,根据查询结果创建表。
    (11)LIKE允许用户复制现有的表结构,但是不复制数据。

返回顶部

管理表

  1. 理论
    默认创建的表都是所谓的管理表,有时也被称为内部表。因为这种表,Hive会(或多或少地)控制着数据的生命周期。
    Hive中的表的数据在HDFS上的存储路径为:${hive.metastore.warehouse.dir}/databasename.db/tablename。
    当我们删除一个管理表时,Hive也会删除这个表中数据以及表的元数据。
    。管理表不适合和其他工具共享数据。
  2. 案例实操
    (0)原始数据
[hyj@hadoop102 datas]$ vim student.txt
1001 ss1 
1002 ss2 
1003 ss3 
1004 ss4 
1005 ss5 
1006 ss6 
1007 ss7 
1008 ss8 
1009 ss9 
1010 ss10 
1011 ss11 
1012 ss12 
1013 ss13 
1014 ss14 
1015 ss15 
1016 ss16 

(1)普通创建表

hive (default)> create table if not exists student(
              > id int,name string
              > )
              > row format delimited fields terminated by '\t'
              > stored as textfile
              > location '/user/hive/warehouse/student';

[hyj@hadoop102 datas]$ hadoop fs -put student.txt '/user/hive/warehouse/student'

(2)根据查询结果创建表(查询的结果会添加到新创建的表中)

hive (default)> create table if not exists student2 as select id,name from student;

(3)根据已经存在的表结构创建表

hive (default)> create table if not exists student3 like student;

(4)查询表的类型

hive (default)> desc formatted student2;

返回顶部

外部表

  1. 理论
    因为表是外部表,所以Hive并非认为其完全拥有这份数据。删除该表并不会删除掉这份数据,不过描述表的元数据信息会被删除掉
  2. 管理表和外部表的使用场景
    每天将收集到的网站日志定期流入HDFS文本文件。在外部表(原始日志表)的基础上做大量的统计分析,用到的中间表、结果表使用内部表存储,数据通过SELECT+INSERT进入内部表。
  3. 案例实操
    分别创建部门和员工外部表,并向表中导入数据。
10 ACCOUNTING 1700 
20 RESEARCH 1800 
30 SALES 1900 
40 OPERATIONS 1700 
7369 SMITH CLERK 7902 1980-12-17 800.00 20 
7499 ALLEN SALESMAN 7698 1981-2-20 1600.00 300.00 30 
7521 WARD SALESMAN 7698 1981-2-22 1250.00 500.00 30 
7566 JONES MANAGER 7839 1981-4-2 2975.00 20 
7654 MARTIN SALESMAN 7698 1981-9-28 1250.00 1400.00 30 
7698 BLAKE MANAGER 7839 1981-5-1 2850.00 30 
7782 CLARK MANAGER 7839 1981-6-9 2450.00 10 
7788 SCOTT ANALYST 7566 1987-4-19 3000.00 20 
7839 KING PRESIDENT 1981-11-17 5000.00 10 
7844 TURNER SALESMAN 7698 1981-9-8 1500.00 0.00 30 
7876 ADAMS CLERK 7788 1987-5-23 1100.00 20 
7900 JAMES CLERK 7698 1981-12-3 950.00 30 
7902 FORD ANALYST 7566 1981-12-3 3000.00 20
7934 MILLER CLERK 7782 1982-1-23 1300.00 10

(1)在HDFS的根目录下创建stu文件夹,将test.txt文件上传到/stu目录下

hive (default)> dfs -mkdir /stu;
hive (default)> dfs -put /opt/module/hive-3.1.2/datas/test.txt /stu;

(2)建表语句,创建外部表
创建部门表

hive (default)> create external table if not exists dept(
              > deptno int,
              > dname string,
              > loc int
              > )
              > row format delimited fields terminated by ' ';
hive (default)> create external table if not exists emp(
              > empno int,
              > ename string,
              > job string,
              > mgr int,
              > hiredate string,
              > sal double,
              > comm double,
              > deptno int)
              > row format delimited fields terminated by ' ';

将文件上传到HDFS上(表对应的文件夹)

[hyj@hadoop102 datas]$ hadoop fs -put ./dept.txt /user/hive/warehouse/dept
[hyj@hadoop102 datas]$ hadoop fs -put ./emp.txt /user/hive/warehouse/emp

(3)查看创建的表

hive (default)> show tables;

(4)查看表的类型

hive (default)> desc formatted dept;

(5)删除外部表

hive (default)> drop table dept;

外部表删除后,hdfs中的数据还在,但是metadata中dept的元数据已被删除

返回顶部

内部表、外部表差异

  1. 无论内部表还是外部表,Hive都在Hive Metastore中管理表定义及其分区信息。
  2. 删除内部表会从Metastore中删除表元数据,还会从HDFS中删除其所有数据/文件
  3. 删除外部表,只会从Metastore中删除表的元数据,并保持HDFS位置中的实际数据不变
    在这里插入图片描述
    返回顶部

管理表与外部表的互相转换

(1)查询表的类型

hive (default)> desc formatted student2;
Table Type:         	MANAGED_TABLE 

(2)修改内部表student2为外部表

hive (default)> alter table student2 set tblproperties('EXTERNAL'='true');

EXTERNAL一定要大写.
(3)查询表的类型

hive (default)> desc formatted student2;
Table Type:         	EXTERNAL_TABLE

(4)修改外部表student2为内部表

hive (default)> alter table student2 set tblproperties('EXTERNAL'='FALSE');

(5)查询表的类型

hive (default)> desc formatted student2;
Table Type:         	MANAGED_TABLE 

注意:('EXTERNAL'='TRUE')和('EXTERNAL'='FALSE')为固定写法,EXTERNAL必须大写!
返回顶部

修改表

--1、更改表名
ALTER TABLE table_name RENAME TO new_table_name;
--2、更改表属性
ALTER TABLE table_name SET TBLPROPERTIES (property_name = property_value, ... );
--更改表注释
ALTER TABLE student SET TBLPROPERTIES ('comment' = "new comment for student table");
--3、更改SerDe属性
ALTER TABLE table_name SET SERDE serde_class_name [WITH SERDEPROPERTIES (property_name = property_value, ... )];
ALTER TABLE table_name [PARTITION partition_spec] SET SERDEPROPERTIES serde_properties;
ALTER TABLE table_name SET SERDEPROPERTIES ('field.delim' = ',');  --字段分隔符
--移除SerDe属性
ALTER TABLE table_name [PARTITION partition_spec] UNSET SERDEPROPERTIES (property_name, ... );

--4、更改表的文件存储格式 该操作仅更改表元数据。现有数据的任何转换都必须在Hive之外进行。
ALTER TABLE table_name  SET FILEFORMAT file_format;
--5、更改表的存储位置路径
ALTER TABLE table_name SET LOCATION "new location";

--6、更改列名称/类型/位置/注释   
--经过几次试验,猜测:使用AFTER(将指定字段移动到某个字段后面)和FIRST(表示将这个字段移动到第一列的位置)来调整位置,必须要移动前后各个位置的原先数据类型要能隐式转换成新数据类型,否则报错.
CREATE TABLE test_change (a int, b int, c int);
// First change column a's name to a1.
ALTER TABLE test_change CHANGE a a1 INT;
// Next change column a1's name to a2, its data type to string, and put it after column b.
ALTER TABLE test_change CHANGE a1 a2 STRING AFTER b;
// The new table's structure is:  b int, a2 string, c int.
// Then change column c's name to c1, and put it as the first column.
ALTER TABLE test_change CHANGE c c1 INT FIRST; --报错
// The new table's structure is:  c1 int, b int, a2 string.
// Add a comment to column a1
ALTER TABLE test_change CHANGE a1 a1 INT COMMENT 'this is column a1';

--7、添加/替换列
--使用ADD COLUMNS,您可以将新列添加到现有列的末尾但在分区列之前。
--REPLACE COLUMNS 将删除所有现有列,并添加新的列集。
ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type,...);

  1. 重命名表
    1)语法
 ALTER TABLE table_name RENAME TO new_table_name 

2)实操案例

hive (default)> alter table student rename to stu;
  1. 增加/修改/替换列信息
    1)语法
    (1)更新列
ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name] 

(2)增加和替换列

ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...) 

注:ADD是代表新增一字段,字段位置在所有列后面(partition列前), REPLACE则是表示替换表中所有字段
2)实操案例
(1)查询表结构

hive (default)> desc student2;
OK
col_name	data_type	comment
id                  	int                 	                    
name                	string

(2)添加列

hive (default)> alter table student2 add columns(grade double);
hive (default)> alter table student2 add columns(address string,school string);

(3)查询表结构

hive (default)> desc student2;
col_name	data_type	comment
id                  	int                 	                    
name                	string              	                    
grade               	double              	                    
address             	string              	                    
school              	string

(4)更新列

hive (default)> alter table student2 change grade score double;

注意:更新列可以同时更新列名和数据类型,但是原先的数据类型要能隐式转换成新的数据类型,否则报错.
(5)替换列 (删除列)

hive (default)> alter table student2 replace columns(name string,score double,address string,school string); 
hive (default)> alter table student2 replace columns(name string,score double);          	                    

(6)查询表结构

hive (default)> desc student2;
OK
col_name	data_type	comment
name                	string              	                    
score               	double     

返回顶部

删除表

DROP TABLE [IF EXISTS] table_name [PURGE];  
  1. DROP TABLE删除该表的元数据和数据。如果已配置垃圾桶(且未指定PURGE),则该表对应的数据实际上将移动到.Trash/Current目录,而元数据完全丢失。
  2. 删除EXTERNAL表时,该表中的数据不会从文件系统中删除,只删除元数据。
  3. 如果指定了PURGE,则表数据不会进入.Trash/Current目录,跳过垃圾桶直接被删除。

Hadoop学习笔记(三)——HDFS垃圾桶机制

hive (default)> drop table dept; 

Describe table

Hive中的DESCRIBE table语句用于显示Hive中表的元数据信息

describe|desc [db_name.]table_name;

describe|desc formatted [db_name.]table_name;

describe|desc extended [db_name.]table_name;

如果指定了EXTENDED关键字,则它将以Thrift序列化形式显示表的所有元数据。如果指定了FORMATTED关键字,则它将以表格格式显示元数据。

--显示表/分区的扩展信息
SHOW TABLE EXTENDED [IN|FROM database_name] LIKE table_name;
show table extended like student;

显示所有的表

--显示当前数据库下所有的表/视图/物化视图/分区/索引
show tables;
SHOW TABLES [IN database_name]; --指定某个数据库

显示表中所有列

--显示表中的所有列,包括分区列。
SHOW COLUMNS (FROM|IN) table_name [(FROM|IN) db_name];
show columns  in student;

显示表的创建语句

--显示表、视图的创建语句
SHOW CREATE TABLE ([db_name.]table_name|view_name);
show create table student;

显示表的属性信息

--显示表的属性信息
SHOW TBLPROPERTIES table_name;
show tblproperties student;

返回顶部

DML数据操作

数据导入 (load)

  1. 向表中装载数据(Load)
    1)语法
load data [local] inpath 'filepath' [overwrite] into table student [partition (partcol1=val1,)]; 

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)] [INPUTFORMAT 'inputformat' SERDE 'serde'] (3.0 or later)

(1)load data:表示加载数据
(2)local:表示从本地加载数据到hive表;否则从HDFS加载数据到hive表
如果指定了LOCAL, load命令将在本地文件系统中查找文件路径。如果指定了相对路径,它将相对于用户的当前工作目录进行解释。(Local表示数据是位于本地文件系统还是HDFS文件系统。)
注意:如果对HiveServer2服务运行此命令。这里的本地文件系统指的是Hiveserver2服务所在机器的本地Linux文件系统,不是Hive客户端所在的本地文件系统,其它的则是Hive客户端所在的本地文件系统
如果没有指定LOCAL关键字,如果filepath指向的是一个完整的URI,hive会直接使用这个URI。 否则如果没有指定schema或者authority,Hive会使用在hadoop配置文件中定义的schema 和 authority,即参数fs.default.name指定的(不出意外,都是HDFS)。

(3)inpath:表示加载数据的路径
(4) filepath表示的待复制/移动数据的路径,可以引用一个文件(在这种情况下,Hive将文件复制/移动到表中),也可以是一个目录(在这种情况下,Hive将把该目录中的所有文件复制/移动到表中)。
(5)overwrite:表示覆盖表中已有数据,否则表示追加
(6)into table:表示加载到哪张表
(7)student:表示具体的表
(8)partition:表示上传到指定分区

2)实操案例
(0)数据

[hyj@hadoop102 datas]$ cat student.txt 
1 张三
2 李四
3 王五
4 刘六
5 琪琪
6 融融
7 敦敦

(1)创建一张表

hive (default)> create table student(id int,name string)
              > row format delimited
              > fields terminated by ' ';

(2)加载本地文件到hive 表(本质是hadoop fs -put上传操作)

hive (default)> load data local inpath '/opt/module/hive-3.1.2/datas/student.txt' into table default.student;

(3)加载HDFS文件到hive表中 (本质是hadoop fs -mv 移动操作)
上传文件到HDFS

hive (default)> dfs -put /opt/module/hive-3.1.2/datas/student.txt /user/hive/warehouse;

加载HDFS上student.txt文件中的数据到hive表中 (追加)

hive (default)> load data inpath '/user/hive/warehouse/student.txt' into table student;

注意:此时HDFS上/user/hive/warehouse目录下的student.txt文件移动到了/user/hive/warehouse/student目录下
(4)加载数据覆盖表中已有的数据
上传文件到HDFS

hive (default)> dfs -put /opt/module/hive-3.1.2/datas/student.txt /user/hive/warehouse;

加载数据覆盖表中已有的数据

hive (default)> load data inpath '/user/hive/warehouse/student.txt' overwrite into table student;

返回顶部

通过查询语句向表中插入数据(Insert)

1)创建一张表

hive (default)> create table student_par(id int,name string)
              > row format delimited fields terminated by ' ';

2)基本插入数据

hive (default)> insert into table student_par values(1,'张三'),(2,'李四');

3)insert + select插入
Hive中insert主要是结合select查询语句使用,将查询结果插入到表中

INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...) [IF NOT EXISTS]] select_statement1 FROM from_statement;

INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement;
hive (default)> insert overwrite table student_par select id,name from student where id>4;

insert into:以追加数据的方式插入到表或分区,原有数据不会删除
insert overwrite:会覆盖表中已存在的数据

如果select查询出来的数据类型和插入表中对应的列数据类型不一致,将会进行转换,但是不能保证转换一定成功,转换失败的数据将会为NULL。

返回顶部

multiple inserts多重插入

multiple inserts可以翻译成为多次插入,多重插入,核心是:一次扫描,多次插入。其功能也体现出来了就是减少扫描的次数

--当前库下已有一张表student
hive (default)> desc student;
OK
col_name	data_type	comment
id                  	int                 	                    
name                	string              	                    
--创建两张新表
hive (default)> create table student_insert1(sid int);
hive (default)> create table student_insert2(sname string);
--多重插入
hive (default)> from student
              >     insert overwrite table student_insert1
              > select id
              >     insert overwrite table student_insert2
              > select name;

查询语句中创建表并加载数据(As Select)

根据查询结果创建表(查询的结果会添加到新创建的表中)

hive (default)> create table if not exists student5 as select id,name from student;

创建表时通过Location指定加载数据路径

  1. 上传数据到hdfs上
hive (default)> dfs -mkdir /student;
hive (default)> dfs -put /opt/module/hive-3.1.2/datas/student.txt /student;
  1. 创建表,并指定在hdfs上的位置
hive (default)> create external table if not exists student6(
              > id int,name string
              > )
              > row format delimited fields terminated by ' '
              > location '/student';
  1. 查询数据
hive (default)> select * from student6;

Import数据到指定Hive表中

注意:先用export导出后,再将数据导入

返回顶部

修改配置文件使用直连方式访问Hive

为了每次启动hive都不用先启动metastore服务和hiveserver2服务,可以执行此步:

[hyj@hadoop102 ~]$ cd /opt/module/hive-3.1.2/conf/
[hyj@hadoop102 conf]$ vim hive-site.xml

修改hive-site.xml配置文件,将以下内容注释掉:

<!-- 指定存储元数据要连接的地址 -->  
<property>  
	<name>hive.metastore.uris</name>  
	<value>thrift://hadoop102:9083</value>  
</property> 
<!-- 指定hiveserver2连接的host -->  
<property>  
	<name>hive.server2.thrift.bind.host</name> 
	<value>hadoop102</value>  
</property>   
<!-- 指定hiveserver2连接的端口号 --> 
<property>  
	 <name>hive.server2.thrift.port</name>  
 	 <value>10000</value>  
</property> 

返回顶部

数据导出

insert + directory导出数据

注意,导出操作是一个OVERWRITE覆盖操作。慎重。

  1. 目录可以是完整的URI。如果未指定scheme或Authority,则Hive将使用hadoop配置变量fs.default.name中的方案和Authority,该变量指定Namenode URI。
  2. 如果使用LOCAL关键字,则Hive会将数据写入本地文件系统上的目录。
  3. 写入文件系统的数据被序列化为文本,列之间用^A隔开,行之间用换行符隔开。如果任何列都不是原生数据类型,那么这些列将序列化为JSON格式。也可以在导出的时候指定分隔符换行符和文件格式。

1)将查询的结果导出到本地

hive (default)> insert overwrite local directory '/opt/module/hive-3.1.2/datas/student5'
              > select * from student5;

2)将查询的结果格式化导出到本地 (导出时指定分隔符)

hive (default)> insert overwrite local directory
              > '/opt/module/hive-3.1.2/datas/student_5'
              > row format delimited fields terminated by ','
              > select * from student5;

3)将查询的结果导出到HDFS上(没有local)

hive (default)> insert overwrite directory '/user/hive/student5'
              > row format delimited fields terminated by '\t'
              > select * from student5;

Hadoop命令导出到本地

hive (default)> dfs -get /user/hive/warehouse/student5/000000_0 /opt/module/hive-3.1.2/datas/student1.txt;

Hive Shell 命令导出

基本语法:(hive -f/-e 执行语句或者脚本 > file)

[hyj@hadoop102 hive-3.1.2]$ bin/hive -e 'select * from student5;' > /opt/module/hive-3.1.2/datas/student5.txt

Export导出到HDFS上

hive (default)> export table student5
              > to '/student1';

Import数据到指定Hive表中(注意:student7表不存在)

hive (default)> import table student7 
              > from '/student1';

Import数据到指定Hive表中

hive (default)> create table student8(
              > id int,name string
              > )
              > row format delimited
              > fields terminated by ' ';

hive (default)> import table student8
              > from '/student1';

注意:import 导入数据到指定hive表(hive表为空表或者不存在),字段分隔符要一致才能导入
export和import主要用于两个Hadoop平台集群之间Hive表迁移。
返回顶部

Hive3.0 Load新特性

Hive 3.0及更高版本中,除了移动复制操作之外,还支持其他加载操作,因为Hive在内部在某些场合下会将加载重写为INSERT AS SELECT
比如,如果表具有分区,而load命令却没有指定分区,则会将load转换为INSERT AS SELECT,并假定最后一组列为分区列。如果文件不符合预期的架构,它将引发错误。

-------hive 3.0 load命令新特性------------------
CREATE TABLE if not exists tab1 (col1 int, col2 int)
PARTITIONED BY (col3 int)
row format delimited fields terminated by ',';

--正常情况下  数据格式如下
11,22
33,44
LOAD DATA LOCAL INPATH '/opt/module/hive-3.1.2/datas/tab1.txt' INTO TABLE tab1 partition(col3="1");

--在hive3.0之后 新特性可以帮助我们把load改写为insert as select
LOAD DATA LOCAL INPATH '/opt/module/hive-3.1.2/datas/tab1.txt' INTO TABLE tab1;

--tab1.txt内容如下
11,22,1
33,44,2

select * from tab1;

本来加载的时候没有指定分区,语句是报错的,但是文件的格式符合表的结构,前两个是col1,col2,最后一个是分区字段col3,则此时会将load语句转换成为insert as select语句。
在Hive3.0中,还支持使用inputformat、SerDe指定任何Hive输入格式,例如文本,ORC等。

返回顶部

清除表中数据(Truncate)

TRUNCATE [TABLE] table_name;

清空表的所有数据但是保留表的元数据结构。如果HDFS启用了垃圾桶,数据将被丢进垃圾桶,否则将被删除。
注意:Truncate只能删除管理表中的数据,不能删除外部表中的数据

hive (default)> truncate table student8;

查询

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Select
查询语句语法:

SELECT [ALL | DISTINCT] select_expr, select_expr, ...  
FROM table_reference  
[WHERE where_condition]  
[GROUP BY col_list]  
[ORDER BY col_list]  
[CLUSTER BY col_list  | [DISTRIBUTE BY col_list] [SORT BY col_list]  ]  
[LIMIT number]

ALL和DISTINCT选项指定是否应返回重复的行。如果没有给出这些选项,则默认值为ALL(返回所有匹配的行)。DISTINCT指定从结果集中删除重复的行。

全表和特定列查询

0)数据准备

[hyj@hadoop102 datas]$ vim dept.txt
10 ACCOUNTING 1700
20 RESEARCH 1800
30 SALES 1900
40 OPERATIONS 1700
[hyj@hadoop102 datas]$ vim emp.txt
7369,SMITH,CLERK,7902,1980-12-17,800.00,,20
7499,ALLEN,SALESMAN,7698,1981-2-20,1600.00,300.00,30
7521,WARD,SALESMAN,7698,1981-2-22,1250.00,500.00,30
7566,JONES,MANAGER,7839,1981-4-2,2975.00,,20
7654,MARTIN,SALESMAN,7698,1981-9-28,1250.00,1400.00,30
7698,BLAKE,MANAGER,7839,1981-5-1,2850.00,,30
7782,CLARK,MANAGER,7839,1981-6-9,2450.00,,10
7788,SCOTT,ANALYST,7566,1987-4-19,3000.00,,20
7839,KING,PRESIDENT,,1981-11-17,5000.00,,10
7844,TURNER,SALESMAN,7698,1981-9-8,1500.00,0.00,30
7876,ADAMS,CLERK,7788,1987-5-23,1100.00,,20
7900,JAMES,CLERK,7698,1981-12-3,950.00,,30
7902,FORD,ANALYST,7566,1981-12-3,3000.00,,20
7934,MILLER,CLERK,7782,1982-1-23,1300.00,,10                                                                          

(1)创建部门表

hive (default)> create table if not exists dept(
              > did int,
              > dname string,
              > loc int
              > )
              > row format delimited fields terminated by ' ';

(2)创建员工表

hive (default)> create table if not exists emp(
              > eid int,
              > ename string,
              > job string,
              > mgr int,
              > hiredate string,
              > sal double,
              > comm double,
              > did int)
              > row format delimited fields terminated by ',';

(3)导入数据

hive (default)> load data local inpath '/opt/module/hive-3.1.2/datas/dept.txt' into table dept;
hive (default)> load data local inpath '/opt/module/hive-3.1.2/datas/emp.txt' into table emp;

(4)全表查询

hive (default)> select * from emp;
hive (default)> select eid,ename,job,mgr,hiredate,sal,comm,did from emp;

(5)选择特定列查询

hive (default)> select ename,sal from emp;
SET hive.support.quoted.identifiers = none; --带反引号的名称被解释为正则表达式
select `^e.*`,sal from emp;

注意:
(1)SQL 语言大小写不敏感。
(2)SQL 可以写在一行或者多行
(3)关键字不能被缩写也不能分行
(4)各子句一般要分行写。
(5)使用缩进提高语句的可读性。

列别名

可以使用AS关键字重命名一个列 ,AS可省略不写.

hive (default)> select ename as name,sal as salary from emp;
hive (default)> select ename name,sal salary from emp;

返回顶部

算术运算符

在这里插入图片描述
案例实操:查询出所有员工的薪水加1000后显示。

hive (default)> select ename as name,sal+1000 from emp;

常用函数 (UDAF聚合函数)

1)求总行数(count)

--count(*):所有行进行统计,包括NULL行
--count(1):所有行进行统计,包括NULL行
--count(column):对column中非Null进行统计
create table tmp1(id int,name string);
insert into table tmp1 values(1,'zhangsan'),(2,"lisi"),(3,null),(null,null);
select * from tmp1;
select count(1) from tmp1; --4
select count(*) from tmp1; --4
select count(name) from tmp1; --2

2)求工资的最大值(max)

 hive (default)> select max(sal) max_sal from emp; 

3)求工资的最小值(min)

 hive (default)> select min(sal) min_sal from emp;

4)求工资的总和(sum)

hive (default)> select sum(sal) sum_sal from emp; 

create table tmp2(col_1 int,col_2 int);
insert into tmp2 values(111,76),(32,59),(66,null);
select * from tmp2;
--第三行数据(66,null) 在进行sum(col_1+col_2)的时候会被忽略
select sum(col_2), sum(col_1 + col_2) from tmp2; --135 278
--可以使用coalesce函数解决
desc function extended coalesce; --返回第一个非空参数
select
    sum(coalesce(col_2,0)),
    sum(coalesce(col_2,0) + col_1)
from tmp2;  -- 135 344

5)求工资的平均值(avg)

hive (default)> select avg(sal) avg_sal from emp; 

6)…

[hyj@hadoop102 datas]$ vim student.txt
95001,李勇,男,20,CS
95002,刘晨,女,19,IS
95003,王敏,女,22,MA
95004,张立,男,19,IS
95005,刘刚,男,18,MA
95006,孙庆,男,23,CS
95007,易思玲,女,19,MA
95008,李娜,女,18,CS
95009,梦圆圆,女,18,MA
95010,孔小涛,男,19,CS
95011,包小柏,男,18,MA
95012,孙花,女,20,CS
95013,冯伟,男,21,CS
95014,王小丽,\N,19,CS
95015,王君,男,18,MA
95016,钱国,男,21,MA
95017,王风娟,女,18,IS
95018,王一,女,19,IS
95019,邢小丽,女,19,IS
95020,赵钱,男,21,IS
95021,周二,男,17,MA
95022,郑明,男,20,MA
drop table if exists student;
create table student(
    num int,
    name string,
    sex string,
    age int,
    dept string)
row format delimited
fields terminated by ',';
--加载数据
load data local inpath '/opt/module/hive-3.1.2/datas/student.txt' into table student;

select * from student;
--此场景下,在编译期间会自动设置只启动一个reduce task处理数据  造成数据拥堵
select count(distinct sex) as cnt1 from student;
--可以先去重 再聚合 通过子查询完成
--因为先执行distinct的时候 可以使用多个reducetask来跑数据
select count(*) as gender_uni_cnt
from (select distinct sex from student) a;

--案例需求:找出student中男女学生年龄最大的及其名字
--这里使用了struct来构造数据 然后针对struct应用max找出最大元素 然后取值
select sex,
max(struct(age, name)).col1 as age,
max(struct(age, name)).col2 as name
from student
group by sex;

select struct(age, name) from student;
select struct(age, name).col1 from student; --col1列:age,col2列:name
select max(struct(age, name)) from student;
select * from student order by struct(age,num);

返回顶部

Limit语句

  1. 典型的查询会返回多行数据。LIMIT子句用于限制select语句返回的行数。
  2. LIMIT接受一个或两个数字参数,这两个参数都必须是非负整数常量。
    第一个参数指定要返回的第一行的偏移量(从 Hive 2.0.0开始),第二个参数指定要返回的最大行数。当给出单个参数时,它代表最大行数,并且偏移量默认为0。
hive (default)> select * from emp;
OK
emp.eid	emp.ename	emp.job	emp.mgr	emp.hiredate	emp.sal	emp.comm	emp.did
7369	SMITH	CLERK	7902	1980-12-17	800.0	NULL	20   #行0
7499	ALLEN	SALESMAN	7698	1981-2-20	1600.0	300.0	30   #行1
7521	WARD	SALESMAN	7698	1981-2-22	1250.0	500.0	30    #行2
7566	JONES	MANAGER	7839	1981-4-2	2975.0	NULL	20
7654	MARTIN	SALESMAN	7698	1981-9-28	1250.0	1400.0	30
7698	BLAKE	MANAGER	7839	1981-5-1	2850.0	NULL	30
7782	CLARK	MANAGER	7839	1981-6-9	2450.0	NULL	10
7788	SCOTT	ANALYST	7566	1987-4-19	3000.0	NULL	20
7839	KING	PRESIDENT	NULL	1981-11-17	5000.0	NULL	10
7844	TURNER	SALESMAN	7698	1981-9-8	1500.0	0.0	30
7876	ADAMS	CLERK	7788	1987-5-23	1100.0	NULL	20
7900	JAMES	CLERK	7698	1981-12-3	950.0	NULL	30
7902	FORD	ANALYST	7566	1981-12-3	3000.0	NULL	20
7934	MILLER	CLERK	7782	1982-1-23	1300.0	NULL	10
Time taken: 0.073 seconds, Fetched: 14 row(s)

从行0开始返回5行数据:

hive (default)> select * from emp limit 5;

从行3开始返回5行数据:

hive (default)> select * from emp limit 3,5;

返回顶部

Where语句

  1. 使用WHERE子句,将不满足条件的行过滤掉
  2. WHERE子句紧随FROM子句
  3. 不能在where子句中使用聚合函数,为什么呢?
    因为聚合函数要使用它的前提是结果集已经确定。而where子句还处于“确定”结果集的过程中,因而不能使用聚合函数。
  4. 案例实操
    查询出薪水大于1000的所有员工(注意:where子句中不能使用字段别名。 )
 hive (default)> select * from emp where sal >1000;

比较运算符(Between/In/ Is Null)

在这里插入图片描述
在这里插入图片描述
案例实操:
(1)查询出薪水等于5000的所有员工

 hive (default)> select * from emp where sal =5000; 

(2)查询工资在500到1000的员工信息

 hive (default)> select * from emp where sal between 500 and 1000; 

(3)查询comm为空的所有员工信息

hive (default)> select * from emp where comm is null; 

(4)查询工资是1500或5000的员工信息

hive (default)> select * from emp where sal IN (1500, 5000); 

返回顶部

Like和RLike

  1. 使用LIKE运算选择类似的值
  2. 选择条件可以包含字符或数字:
    % 代表零个或多个字符(任意个字符)。
    _ 代表一个字符。
  3. RLIKE子句
    RLIKE子句是Hive中这个功能的一个扩展,其可以通过Java的正则表达式这个更强大的语言来指定匹配条件。
  4. 案例实操
    (1)查找名字以A开头的员工信息
  hive (default)> select * from emp where ename LIKE 'A%'; 

查找名字不是以A开头的员工信息

select * from emp where not ename LIKE 'A%'; 

(2)查找名字中第二个字母为A的员工信息

hive (default)> select * from emp where ename LIKE '_A%'; 

(3)查找名字中带有A的员工信息

hive (default)> select * from emp where ename RLIKE '[A]'; 

(4)查找名字中有2个L的员工信息

hive (default)> select * from emp where ename RLIKE '[L]{2}'; 

(5)rlike和regexp

select 1 from emp where '123456aa' rlike '^\\d+$';
--regexp:功能与rlike相同 用于判断字符串是否匹配正则表达式
select 1 from emp where 'idhguyft' regexp '^i.*t$';

逻辑运算符(And/Or/Not)

在这里插入图片描述
非操作: NOT A 、!A
逻辑是否存在: [NOT] EXISTS (subquery)
(1)查询薪水大于1000,部门是30 的员工信息

hive (default)> select * from emp where sal>1000 and did=30; 

(2)查询除了20部门和30部门以外的员工信息

hive (default)> select * from emp where did not IN(30, 20); 
--非操作: NOT A 、!A   如果A为FALSE,则为TRUE;如果A为NULL,则为NULL。否则为FALSE。
select name from student where not 2>1;

select name from student where !2=1;
--逻辑是否存在: [NOT] EXISTS (subquery) 如果子查询返回至少一行,则为TRUE。
select * from dept d
where exists (select deptno from emp e where e.deptno= d.deptno);

返回顶部

算术运算符

加法操作+
减法操作-
乘法操作*
除法操作/
取整操作div
取余操作%
按位与&
按位取反~
按位或|
按位异或^
select 3/2;
select 10 div 3;

分组

Group By语句

  1. GROUP BY 语句用于结合聚合函数,根据一个或多个列对结果集进行分组。

  2. 注意:出现在GROUP BY中select_expr的字段:要么是GROUP BY分组的字段;要么是被聚合函数应用的字段

  3. 案例实操:
    (1)计算emp表每个部门的平均工资

hive (default)> select t.did, avg(t.sal) avg_sal from emp t group by t.did; 

(2)计算emp每个部门中每个岗位的最高薪水

hive (default)> select t.did, t.job, max(t.sal) max_sal from emp t group by  t.did, t.job;

返回顶部

Having语句

  1. having与where不同点
    (1)where后面不能使用聚合函数,而having后面可以使用聚合函数。
    (2)having只用于group by分组统计语句。
    (3)先group by 再having(先分组再过滤),先where再group by(先过滤再分组).
  2. HAVING子句可以让我们筛选分组后的各组数据,并且可以在Having中使用聚合函数,因为此时where,group by已经执行结束,结果集已经确定
  3. 案例实操
    (1)求每个部门的平均薪水大于2000的部门
    求每个部门的平均工资
hive (default)> select did, avg(sal) from emp group by did; 

求每个部门的平均薪水大于2000的部门

hive (default)> select did, avg(sal) avg_sal from emp group by did having avg_sal > 2000;
drop table if exists t_usa_covid19;
CREATE TABLE t_usa_covid19(
       count_date string,
       county string,
       state string,
       fips int,
       cases int,
       deaths int)
row format delimited fields terminated by ",";
--将源数据load加载到t_usa_covid19表对应的路径下
load data local inpath '/opt/module/hive-3.1.2/datas/us-covid19-counties.dat' into table t_usa_covid19;

select * from t_usa_covid19;
--创建一张分区表 基于count_date日期,state州进行分区
CREATE TABLE t_usa_covid19_p(
     county string,
     fips int,
     cases int,
     deaths int)
partitioned by(count_date string,state string)
row format delimited fields terminated by ",";

--使用动态分区插入将数据导入t_usa_covid19_p中
set hive.exec.dynamic.partition.mode = nonstrict;

insert into table t_usa_covid19_p partition (count_date,state)
select county,fips,cases,deaths,count_date,state from t_usa_covid19;

--先where分组前过滤(此处是分区裁剪),再进行group by分组, 分组后每个分组结果集确定 再使用having过滤
--所谓分区裁剪指的是:对分区表进行查询时,会检查WHERE子句或JOIN中的ON子句中是否存在对分区字段的过滤,如果存在,则仅访问查询符合条件的分区,即裁剪掉没必要访问的分区。
select state,sum(deaths)
from t_usa_covid19_p
where count_date = "2021-01-28"
group by state
having sum(deaths) > 10000;

--这样写更好 即在group by的时候聚合函数已经作用得出结果 having直接引用结果过滤 不需要再单独计算一次了
select state,sum(deaths) as cnts
from t_usa_covid19_p
where count_date = "2021-01-28"
group by state
having cnts> 10000;

返回顶部

Hive SQL查询执行顺序

在查询过程中执行顺序:from>where>join on>select(select中的字段与group by中的不一致就会有)>group by(含聚合)>select(为having准备数据,因而having中可以使用select别名)>having>select(过滤后的结果集)>distinct>order by>limit>union

所以聚合语句(sum,min,max,avg,count)要比having子句优先执行,而where子句在查询过程中执行优先级别优先于聚合语句(sum,min,max,avg,count)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值