Hive 快速指南



Hive - 简介

术语“大数据”用于指代包含海量数据、高速数据和种类繁多的数据集的集合,这些数据日益增多。使用传统的数据管理系统很难处理大数据。因此,Apache 软件基金会引入了一个名为 Hadoop 的框架来解决大数据管理和处理的挑战。

Hadoop

Hadoop 是一个开源框架,用于在分布式环境中存储和处理大数据。它包含两个模块,一个是 MapReduce,另一个是 Hadoop 分布式文件系统 (HDFS)。

  • MapReduce:它是一种并行编程模型,用于在大型商品硬件集群上处理大量结构化、半结构化和非结构化数据。

  • HDFS:Hadoop 分布式文件系统是 Hadoop 框架的一部分,用于存储和处理数据集。它提供了一个容错文件系统,可在商品硬件上运行。

Hadoop 生态系统包含不同的子项目(工具),例如 Sqoop、Pig 和 Hive,这些工具用于帮助 Hadoop 模块。

  • Sqoop:它用于在 HDFS 和 RDBMS 之间导入和导出数据。

  • Pig:它是一个过程语言平台,用于开发用于 MapReduce 操作的脚本。

  • Hive:它是一个平台,用于开发 SQL 类型脚本以执行 MapReduce 操作。

注意:执行 MapReduce 操作有多种方法

  • 使用 Java MapReduce 程序处理结构化、半结构化和非结构化数据的传统方法。
  • 使用 Pig 处理结构化和半结构化数据的 MapReduce 脚本方法。
  • 使用 Hive 处理结构化数据的 MapReduce 的 Hive 查询语言 (HiveQL 或 HQL)。

什么是 Hive

Hive 是一个数据仓库基础架构工具,用于处理 Hadoop 中的结构化数据。它位于 Hadoop 的顶部,用于汇总大数据,并简化查询和分析。

Hive 最初由 Facebook 开发,后来 Apache 软件基金会接手并将其进一步开发为一个名为 Apache Hive 的开源项目。它被不同的公司使用。例如,亚马逊在 Amazon Elastic MapReduce 中使用它。

Hive 不是

  • 关系型数据库
  • 联机事务处理 (OLTP) 的设计
  • 用于实时查询和行级更新的语言

Hive 的特性

  • 它将模式存储在数据库中,并将处理后的数据存储在 HDFS 中。
  • 它专为 OLAP 设计。
  • 它提供了一种名为 HiveQL 或 HQL 的 SQL 类型查询语言。
  • 它熟悉、快速、可扩展且可扩展。

Hive 的架构

以下组件图描绘了 Hive 的架构

Hive Architecture

此组件图包含不同的单元。下表描述了每个单元

单元名称 操作
用户界面 Hive 是一种数据仓库基础架构软件,可以创建用户与 HDFS 之间的交互。Hive 支持的用户界面包括 Hive Web UI、Hive 命令行和 Hive HD Insight(在 Windows 服务器中)。
元数据存储 Hive 选择相应的数据库服务器来存储表的模式或元数据、数据库、表中的列、它们的数据类型以及 HDFS 映射。
HiveQL 处理引擎 HiveQL 类似于 SQL,用于查询元数据存储上的模式信息。它是传统 MapReduce 程序方法的替代方法之一。我们可以编写 MapReduce 作业的查询并对其进行处理,而不是用 Java 编写 MapReduce 程序。
执行引擎 HiveQL 处理引擎和 MapReduce 的连接部分是 Hive 执行引擎。执行引擎处理查询并生成与 MapReduce 结果相同的结果。它使用 MapReduce 的风格。
HDFS 或 HBASE Hadoop 分布式文件系统或 HBASE 是将数据存储到文件系统中的数据存储技术。

Hive 的工作原理

下图描绘了 Hive 和 Hadoop 之间的工作流程。

How Hive Works

下表定义了 Hive 如何与 Hadoop 框架交互

步骤号 操作
1 执行查询

Hive 接口(例如命令行或 Web UI)将查询发送到驱动程序(任何数据库驱动程序,例如 JDBC、ODBC 等)以执行。

2 获取计划

驱动程序借助查询编译器来解析查询,以检查语法和查询计划或查询的要求。

3 获取元数据

编译器向元数据存储(任何数据库)发送元数据请求。

4 发送元数据

元数据存储将元数据作为响应发送到编译器。

5 发送计划

编译器检查需求并将计划重新发送到驱动程序。到此为止,查询的解析和编译已完成。

6 执行计划

驱动程序将执行计划发送到执行引擎。

7 执行作业

在内部,执行作业的过程是一个 MapReduce 作业。执行引擎将作业发送到 JobTracker(位于 Name 节点中),它将此作业分配给 TaskTracker(位于 Data 节点中)。在这里,查询执行 MapReduce 作业。

7.1 元数据操作

同时在执行过程中,执行引擎可以与元数据存储执行元数据操作。

8 获取结果

执行引擎从 Data 节点接收结果。

9 发送结果

执行引擎将这些结果值发送到驱动程序。

10 发送结果

驱动程序将结果发送到 Hive 接口。

Hive - 安装

所有 Hadoop 子项目(如 Hive、Pig 和 HBase)都支持 Linux 操作系统。因此,您需要安装任何 Linux 风格的操作系统。Hive 安装执行以下简单步骤

步骤 1:验证 JAVA 安装

在安装 Hive 之前,必须在您的系统上安装 Java。让我们使用以下命令验证 java 安装

$ java –version

如果您的系统上已安装 Java,您将看到以下响应

java version "1.7.0_71" 
Java(TM) SE Runtime Environment (build 1.7.0_71-b13) 
Java HotSpot(TM) Client VM (build 25.0-b02, mixed mode)

如果您的系统中未安装 java,则按照以下步骤安装 java。

安装 Java

步骤 I

通过访问以下链接下载 java(JDK <最新版本> - X64.tar.gz)http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html.

然后 jdk-7u71-linux-x64.tar.gz 将下载到您的系统上。

步骤 II

通常您会在 Downloads 文件夹中找到下载的 java 文件。验证它并使用以下命令解压缩 jdk-7u71-linux-x64.gz 文件。

$ cd Downloads/
$ ls
jdk-7u71-linux-x64.gz
$ tar zxf jdk-7u71-linux-x64.gz
$ ls
jdk1.7.0_71 jdk-7u71-linux-x64.gz

步骤 III

要使所有用户都可以使用 java,您必须将其移动到“/usr/local/”位置。打开 root,然后键入以下命令。

$ su
password:
# mv jdk1.7.0_71 /usr/local/
# exit

步骤 IV

要设置 PATH 和 JAVA_HOME 变量,请将以下命令添加到 ~/.bashrc 文件中。

export JAVA_HOME=/usr/local/jdk1.7.0_71
export PATH=PATH:$JAVA_HOME/bin

现在使用终端中说明的命令 java -version 验证安装。

步骤 2:验证 Hadoop 安装

在安装 Hive 之前,必须在您的系统上安装 Hadoop。让我们使用以下命令验证 Hadoop 安装

$ hadoop version

如果您的系统上已安装 Hadoop,则您将收到以下响应

Hadoop 2.4.1 Subversion https://svn.apache.org/repos/asf/hadoop/common -r 1529768 
Compiled by hortonmu on 2013-10-07T06:28Z 
Compiled with protoc 2.5.0 
From source with checksum 79e53ce7994d1628b240f09af91e1af4

如果您的系统上未安装 Hadoop,则继续执行以下步骤

下载 Hadoop

使用以下命令从 Apache 软件基金会下载并解压缩 Hadoop 2.4.1。

$ su
password:
# cd /usr/local
# wget http://apache.claz.org/hadoop/common/hadoop-2.4.1/
hadoop-2.4.1.tar.gz
# tar xzf hadoop-2.4.1.tar.gz
# mv hadoop-2.4.1/* to hadoop/
# exit

以伪分布式模式安装 Hadoop

以下步骤用于以伪分布式模式安装 Hadoop 2.4.1。

步骤 I:设置 Hadoop

您可以通过将以下命令追加到~/.bashrc 文件中来设置 Hadoop 环境变量。

export HADOOP_HOME=/usr/local/hadoop 
export HADOOP_MAPRED_HOME=$HADOOP_HOME 
export HADOOP_COMMON_HOME=$HADOOP_HOME 
export HADOOP_HDFS_HOME=$HADOOP_HOME 
export YARN_HOME=$HADOOP_HOME
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native export
PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin

现在将所有更改应用到当前运行的系统中。

$ source ~/.bashrc

步骤 II:Hadoop 配置

您可以在“$HADOOP_HOME/etc/hadoop”位置找到所有 Hadoop 配置文件。您需要根据您的 Hadoop 基础架构对这些配置文件进行适当的更改。

$ cd $HADOOP_HOME/etc/hadoop

为了使用 java 开发 Hadoop 程序,您必须通过用系统中 java 的位置替换JAVA_HOME 值来重置hadoop-env.sh 文件中的 java 环境变量。

export JAVA_HOME=/usr/local/jdk1.7.0_71

以下是您必须编辑以配置 Hadoop 的文件列表。

core-site.xml

core-site.xml 文件包含诸如 Hadoop 实例使用的端口号、分配给文件系统的内存、存储数据的内存限制以及读/写缓冲区大小等信息。

打开 core-site.xml,并在<configuration>和</configuration>标签之间添加以下属性。

<configuration>

   <property> 
      <name>fs.default.name</name> 
      <value>hdfs://127.0.0.1:9000</value> 
   </property>
   
</configuration>

hdfs-site.xml

hdfs-site.xml 文件包含诸如复制数据的值、namenode 路径以及本地文件系统的 datanode 路径等信息。这意味着您要存储 Hadoop 基础架构的位置。

让我们假设以下数据。

dfs.replication (data replication value) = 1

(In the following path /hadoop/ is the user name.
hadoopinfra/hdfs/namenode is the directory created by hdfs file system.)

namenode path = //home/hadoop/hadoopinfra/hdfs/namenode

(hadoopinfra/hdfs/datanode is the directory created by hdfs file system.)
datanode path = //home/hadoop/hadoopinfra/hdfs/datanode

打开此文件,并在该文件的<configuration>、</configuration>标签之间添加以下属性。

<configuration>

   <property> 
      <name>dfs.replication</name> 
      <value>1</value> 
   </property> 
   <property> 
      <name>dfs.name.dir</name> 
      <value>file:///home/hadoop/hadoopinfra/hdfs/namenode </value> 
   </property> 
   <property> 
      <name>dfs.data.dir</name>
      <value>file:///home/hadoop/hadoopinfra/hdfs/datanode </value > 
   </property>
   
</configuration>

注意:在上面的文件中,所有属性值都是用户定义的,您可以根据您的 Hadoop 基础架构进行更改。

yarn-site.xml

此文件用于将 yarn 配置到 Hadoop 中。打开 yarn-site.xml 文件,并在该文件的<configuration>、</configuration>标签之间添加以下属性。

<configuration>

   <property> 
      <name>yarn.nodemanager.aux-services</name> 
      <value>mapreduce_shuffle</value> 
   </property>
   
</configuration>

mapred-site.xml

此文件用于指定我们正在使用的 MapReduce 框架。默认情况下,Hadoop 包含一个 yarn-site.xml 模板。首先,您需要使用以下命令将文件从 mapred-site.xml.template 复制到 mapred-site.xml 文件。

$ cp mapred-site.xml.template mapred-site.xml

打开mapred-site.xml文件,并在该文件中的 <configuration>、</configuration> 标签之间添加以下属性。

<configuration>

   <property> 
      <name>mapreduce.framework.name</name> 
      <value>yarn</value> 
   </property>

</configuration>

验证 Hadoop 安装

以下步骤用于验证 Hadoop 安装。

步骤一:Name Node 设置

使用命令“hdfs namenode -format”设置 namenode,如下所示。

$ cd ~
$ hdfs namenode -format

预期结果如下。

10/24/14 21:30:55 INFO namenode.NameNode: STARTUP_MSG: 
/************************************************************ 
STARTUP_MSG: Starting NameNode 
STARTUP_MSG: host = localhost/192.168.1.11 
STARTUP_MSG: args = [-format] 
STARTUP_MSG: version = 2.4.1 
... 
... 
10/24/14 21:30:56 INFO common.Storage: Storage directory 
/home/hadoop/hadoopinfra/hdfs/namenode has been successfully formatted. 
10/24/14 21:30:56 INFO namenode.NNStorageRetentionManager: Going to 
retain 1 images with txid >= 0 
10/24/14 21:30:56 INFO util.ExitUtil: Exiting with status 0
10/24/14 21:30:56 INFO namenode.NameNode: SHUTDOWN_MSG: 
/************************************************************ 
SHUTDOWN_MSG: Shutting down NameNode at localhost/192.168.1.11
 ************************************************************/

步骤二:验证 Hadoop dfs

以下命令用于启动 dfs。执行此命令将启动您的 Hadoop 文件系统。

$ start-dfs.sh

预期输出如下

10/24/14 21:37:56 
Starting namenodes on [localhost] 
localhost: starting namenode, logging to /home/hadoop/hadoop-2.4.1/logs/hadoop-hadoop-namenode-localhost.out 
localhost: starting datanode, logging to /home/hadoop/hadoop-2.4.1/logs/hadoop-hadoop-datanode-localhost.out 
Starting secondary namenodes [0.0.0.0]

步骤三:验证 Yarn 脚本

以下命令用于启动 yarn 脚本。执行此命令将启动您的 yarn 守护进程。

$ start-yarn.sh

预期输出如下

starting yarn daemons 
starting resourcemanager, logging to /home/hadoop/hadoop-2.4.1/logs/yarn-hadoop-resourcemanager-localhost.out 
localhost: starting nodemanager, logging to /home/hadoop/hadoop-2.4.1/logs/yarn-hadoop-nodemanager-localhost.out

步骤四:在浏览器中访问 Hadoop

访问 Hadoop 的默认端口号为 50070。使用以下 URL 在浏览器上获取 Hadoop 服务。

https://127.0.0.1:50070/
Hadoop Browser

步骤五:验证集群的所有应用程序

访问集群所有应用程序的默认端口号为 8088。使用以下 URL 访问此服务。

https://127.0.0.1:8088/
All Applications

步骤 3:下载 Hive

在本教程中,我们使用 hive-0.14.0。您可以通过访问以下链接下载它 http://apache.petsads.us/hive/hive-0.14.0/. 假设它下载到 /Downloads 目录。在这里,我们为本教程下载名为“apache-hive-0.14.0-bin.tar.gz”的 Hive 归档文件。以下命令用于验证下载

$ cd Downloads
$ ls

下载成功后,您将看到以下响应

apache-hive-0.14.0-bin.tar.gz

步骤 4:安装 Hive

在您的系统上安装 Hive 需要以下步骤。假设 Hive 归档文件已下载到 /Downloads 目录。

解压缩和验证 Hive 归档文件

以下命令用于验证下载并解压缩 hive 归档文件

$ tar zxvf apache-hive-0.14.0-bin.tar.gz
$ ls

下载成功后,您将看到以下响应

apache-hive-0.14.0-bin apache-hive-0.14.0-bin.tar.gz

将文件复制到 /usr/local/hive 目录

我们需要从超级用户“su -”复制文件。以下命令用于将文件从解压缩的目录复制到 /usr/local/hive”目录。

$ su -
passwd:

# cd /home/user/Download
# mv apache-hive-0.14.0-bin /usr/local/hive
# exit

设置 Hive 的环境

您可以通过将以下行追加到~/.bashrc文件来设置 Hive 环境

export HIVE_HOME=/usr/local/hive
export PATH=$PATH:$HIVE_HOME/bin
export CLASSPATH=$CLASSPATH:/usr/local/Hadoop/lib/*:.
export CLASSPATH=$CLASSPATH:/usr/local/hive/lib/*:.

以下命令用于执行 ~/.bashrc 文件。

$ source ~/.bashrc

步骤 5:配置 Hive

要将 Hive 与 Hadoop 配合使用,您需要编辑hive-env.sh文件,该文件位于$HIVE_HOME/conf目录中。以下命令重定向到 Hive config 文件夹并复制模板文件

$ cd $HIVE_HOME/conf
$ cp hive-env.sh.template hive-env.sh

通过追加以下行编辑hive-env.sh文件

export HADOOP_HOME=/usr/local/hadoop

Hive 安装已成功完成。现在您需要一个外部数据库服务器来配置元存储。我们使用 Apache Derby 数据库。

步骤 6:下载和安装 Apache Derby

请按照以下步骤下载和安装 Apache Derby

下载 Apache Derby

以下命令用于下载 Apache Derby。下载需要一些时间。

$ cd ~
$ wget http://archive.apache.org/dist/db/derby/db-derby-10.4.2.0/db-derby-10.4.2.0-bin.tar.gz

以下命令用于验证下载

$ ls

下载成功后,您将看到以下响应

db-derby-10.4.2.0-bin.tar.gz

解压缩和验证 Derby 归档文件

以下命令用于解压缩和验证 Derby 归档文件

$ tar zxvf db-derby-10.4.2.0-bin.tar.gz
$ ls

下载成功后,您将看到以下响应

db-derby-10.4.2.0-bin db-derby-10.4.2.0-bin.tar.gz

将文件复制到 /usr/local/derby 目录

我们需要从超级用户“su -”复制。以下命令用于将文件从解压缩的目录复制到 /usr/local/derby 目录

$ su -
passwd:
# cd /home/user
# mv db-derby-10.4.2.0-bin /usr/local/derby
# exit

设置 Derby 的环境

您可以通过将以下行追加到~/.bashrc文件来设置 Derby 环境

export DERBY_HOME=/usr/local/derby
export PATH=$PATH:$DERBY_HOME/bin
Apache Hive
18
export CLASSPATH=$CLASSPATH:$DERBY_HOME/lib/derby.jar:$DERBY_HOME/lib/derbytools.jar

以下命令用于执行~/.bashrc文件

$ source ~/.bashrc

创建目录以存储元存储

在 $DERBY_HOME 目录中创建一个名为 data 的目录以存储元存储数据。

$ mkdir $DERBY_HOME/data

Derby 安装和环境设置现已完成。

步骤 7:配置 Hive 的元存储

配置元存储意味着向 Hive 指定数据库存储位置。您可以通过编辑 hive-site.xml 文件来实现此目的,该文件位于 $HIVE_HOME/conf 目录中。首先,使用以下命令复制模板文件

$ cd $HIVE_HOME/conf
$ cp hive-default.xml.template hive-site.xml

编辑hive-site.xml并在 <configuration> 和 </configuration> 标签之间追加以下行

<property>
   <name>javax.jdo.option.ConnectionURL</name>
   <value>jdbc:derby://127.0.0.1:1527/metastore_db;create=true </value>
   <description>JDBC connect string for a JDBC metastore </description>
</property>

创建一个名为 jpox.properties 的文件并在其中添加以下行

javax.jdo.PersistenceManagerFactoryClass =

org.jpox.PersistenceManagerFactoryImpl
org.jpox.autoCreateSchema = false
org.jpox.validateTables = false
org.jpox.validateColumns = false
org.jpox.validateConstraints = false
org.jpox.storeManagerType = rdbms
org.jpox.autoCreateSchema = true
org.jpox.autoStartMechanismMode = checked
org.jpox.transactionIsolation = read_committed
javax.jdo.option.DetachAllOnCommit = true
javax.jdo.option.NontransactionalRead = true
javax.jdo.option.ConnectionDriverName = org.apache.derby.jdbc.ClientDriver
javax.jdo.option.ConnectionURL = jdbc:derby://hadoop1:1527/metastore_db;create = true
javax.jdo.option.ConnectionUserName = APP
javax.jdo.option.ConnectionPassword = mine

步骤 8:验证 Hive 安装

在运行 Hive 之前,您需要创建/tmp文件夹和 HDFS 中的单独 Hive 文件夹。这里,我们使用/user/hive/warehouse文件夹。您需要为这些新创建的文件夹设置写入权限,如下所示

chmod g+w

现在在验证 Hive 之前在 HDFS 中设置它们。使用以下命令

$ $HADOOP_HOME/bin/hadoop fs -mkdir /tmp 
$ $HADOOP_HOME/bin/hadoop fs -mkdir /user/hive/warehouse
$ $HADOOP_HOME/bin/hadoop fs -chmod g+w /tmp 
$ $HADOOP_HOME/bin/hadoop fs -chmod g+w /user/hive/warehouse

以下命令用于验证 Hive 安装

$ cd $HIVE_HOME
$ bin/hive

Hive 成功安装后,您将看到以下响应

Logging initialized using configuration in jar:file:/home/hadoop/hive-0.9.0/lib/hive-common-0.9.0.jar!/hive-log4j.properties 
Hive history file=/tmp/hadoop/hive_job_log_hadoop_201312121621_1494929084.txt
………………….
hive>

以下示例命令用于显示所有表

hive> show tables; 
OK 
Time taken: 2.798 seconds 
hive>

Hive - 数据类型

本章将引导您了解 Hive 中的不同数据类型,这些数据类型参与表创建。Hive 中的所有数据类型分为四种类型,如下所示

  • 列类型
  • 文字
  • 空值
  • 复杂类型

列类型

列类型用作 Hive 的列数据类型。它们如下所示

整型

整数类型数据可以使用整型数据类型 INT 指定。当数据范围超出 INT 的范围时,您需要使用 BIGINT,如果数据范围小于 INT,则使用 SMALLINT。TINYINT 小于 SMALLINT。

下表显示了各种 INT 数据类型

类型 后缀 示例
TINYINT Y 10Y
SMALLINT S 10S
INT - 10
BIGINT L 10L

字符串类型

字符串类型数据类型可以使用单引号 (' ') 或双引号 (" ") 指定。它包含两种数据类型:VARCHAR 和 CHAR。Hive 遵循 C 类型转义字符。

下表显示了各种 CHAR 数据类型

数据类型 长度
VARCHAR 1 到 65355
CHAR 255

时间戳

它支持传统 UNIX 时间戳,并具有可选的纳秒精度。它支持 java.sql.Timestamp 格式“YYYY-MM-DD HH:MM:SS.fffffffff”和格式“yyyy-mm-dd hh:mm:ss.ffffffffff”。

日期

DATE 值以年/月/日格式表示,格式为 {{YYYY-MM-DD}}。

小数

Hive 中的 DECIMAL 类型与 Java 的 Big Decimal 格式相同。它用于表示不可变的任意精度。语法和示例如下

DECIMAL(precision, scale)
decimal(10,0)

联合类型

Union 是异构数据类型的集合。您可以使用create union创建实例。语法和示例如下

UNIONTYPE<int, double, array<string>, struct<a:int,b:string>>

{0:1} 
{1:2.0} 
{2:["three","four"]} 
{3:{"a":5,"b":"five"}} 
{2:["six","seven"]} 
{3:{"a":8,"b":"eight"}} 
{0:9} 
{1:10.0}

文字

Hive 中使用以下文字

浮点类型

浮点类型不过是带有小数点的数字。通常,此类型的数据由 DOUBLE 数据类型组成。

十进制类型

十进制类型数据不过是比 DOUBLE 数据类型范围更大的浮点值。十进制类型的范围大约为 -10-308 到 10308

空值

缺失值由特殊值 NULL 表示。

复杂类型

Hive 复杂数据类型如下

数组

Hive 中的数组与在 Java 中的使用方式相同。

语法:ARRAY<data_type>

映射

Hive 中的映射类似于 Java 映射。

语法:MAP<primitive_type, data_type>

结构体

Hive 中的结构体类似于使用带注释的复杂数据。

语法:STRUCT<col_name : data_type [COMMENT col_comment], ...>

Hive - 创建数据库

Hive 是一种数据库技术,可以定义数据库和表以分析结构化数据。结构化数据分析的主题是以表格方式存储数据,并传递查询以对其进行分析。本章说明如何创建 Hive 数据库。Hive 包含一个名为default的默认数据库。

创建数据库语句

Create Database 是一个用于在 Hive 中创建数据库的语句。Hive 中的数据库是命名空间或表的集合。此语句的语法如下

CREATE DATABASE|SCHEMA [IF NOT EXISTS] <database name>

这里,IF NOT EXISTS 是一个可选子句,它通知用户已经存在一个同名数据库。我们可以在此命令中使用 SCHEMA 代替 DATABASE。以下查询用于创建一个名为userdb的数据库

hive> CREATE DATABASE [IF NOT EXISTS] userdb;

hive> CREATE SCHEMA userdb;

以下查询用于验证数据库列表

hive> SHOW DATABASES;
default
userdb

JDBC 程序

创建数据库的 JDBC 程序如下所示。

import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet; 4. CREATE DATABASE
import java.sql.Statement;
import java.sql.DriverManager;

public class HiveCreateDb {
   private static String driverName =
   "org.apache.hadoop.hive.jdbc.HiveDriver";
   public static void main(String[] args) throws SQLException {
      // Register driver and create driver instance
      Class.forName(driverName);
      // get connection
      Connection con = DriverManager.
      getConnection("jdbc:hive://127.0.0.1:10000/default", "", "");
      Statement stmt = con.createStatement();
      stmt.executeQuery("CREATE DATABASE userdb");
      System.out.println(“Database userdb created successfully.”);
      con.close();
   }
}

将程序保存在名为 HiveCreateDb.java 的文件中。以下命令用于编译和执行此程序。

$ javac HiveCreateDb.java
$ java HiveCreateDb

输出

Database userdb created successfully.

Hive - 删除数据库

本章介绍如何在 Hive 中删除数据库。SCHEMA 和 DATABASE 的用法相同。

删除数据库语句

Drop Database 是一个删除所有表并删除数据库的语句。其语法如下

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

以下查询用于删除数据库。假设数据库名为userdb

hive> DROP DATABASE IF EXISTS userdb;

以下查询使用CASCADE删除数据库。这意味着在删除数据库之前先删除相应的表。

hive> DROP DATABASE IF EXISTS userdb CASCADE;

以下查询使用SCHEMA删除数据库。

hive> DROP SCHEMA userdb;

此子句是在 Hive 0.6 中添加的。

JDBC 程序

删除数据库的 JDBC 程序如下所示。

import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager; 5. DROP DATABASE

public class HiveDropDb {
   private static String driverName =
   "org.apache.hadoop.hive.jdbc.HiveDriver";
   public static void main(String[] args) throws SQLException {
      // Register driver and create driver instance
      Class.forName(driverName);
      // get connection
      Connection con = DriverManager.
      getConnection("jdbc:hive://127.0.0.1:10000/default", "", "");
      Statement stmt = con.createStatement();
      stmt.executeQuery("DROP DATABASE userdb");
      System.out.println(“Drop userdb database successful.”);
      con.close();
   }
}

将程序保存在名为 HiveDropDb.java 的文件中。以下是编译和执行此程序的命令。

$ javac HiveDropDb.java
$ java HiveDropDb

输出

Drop userdb database successful.

Hive - 创建表

本章说明如何创建表以及如何向其中插入数据。在 HIVE 中创建表的约定与使用 SQL 创建表非常相似。

创建表语句

Create Table 是一个用于在 Hive 中创建表的语句。语法和示例如下

语法

CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.] table_name

[(col_name data_type [COMMENT col_comment], ...)]
[COMMENT table_comment]
[ROW FORMAT row_format]
[STORED AS file_format]

示例

假设您需要使用CREATE TABLE语句创建一个名为employee的表。下表列出了 employee 表中的字段及其数据类型

序号 字段名称 数据类型
1 Eid int
2 Name String
3 Salary Float
4 Designation string

以下数据是注释,行格式化字段,如字段分隔符、行分隔符和存储的文件类型。

COMMENT ‘Employee details’
FIELDS TERMINATED BY ‘\t’
LINES TERMINATED BY ‘\n’
STORED IN TEXT FILE

以下查询使用上述数据创建一个名为employee的表。

hive> CREATE TABLE IF NOT EXISTS employee ( eid int, name String,
> salary String, destination String)
> COMMENT ‘Employee details’
> ROW FORMAT DELIMITED
> FIELDS TERMINATED BY ‘\t’
> LINES TERMINATED BY ‘\n’
> STORED AS TEXTFILE;

如果您添加 IF NOT EXISTS 选项,则如果表已存在,Hive 将忽略该语句。

表创建成功后,您将看到以下响应

OK
Time taken: 5.905 seconds
hive>

JDBC 程序

创建表的 JDBC 程序示例。

import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;

public class HiveCreateTable {
   private static String driverName =
   "org.apache.hadoop.hive.jdbc.HiveDriver";
   public static void main(String[] args) throws SQLException {
      // Register driver and create driver instance
      Class.forName(driverName);
      // get connection
      Connection con = DriverManager.
      getConnection("jdbc:hive://127.0.0.1:10000/userdb", "", "");
      // create statement
      Statement stmt = con.createStatement();
      // execute statement
      stmt.executeQuery("CREATE TABLE IF NOT EXISTS "
      +" employee ( eid int, name String, "
      +" salary String, destignation String)"
      +" COMMENT ‘Employee details’"
      +" ROW FORMAT DELIMITED"
      +" FIELDS TERMINATED BY ‘\t’"
      +" LINES TERMINATED BY ‘\n’"
      +" STORED AS TEXTFILE;");
      System.out.println(“ Table employee created.”);
      con.close();
   }
}

将程序保存在名为 HiveCreateDb.java 的文件中。以下命令用于编译和执行此程序。

$ javac HiveCreateDb.java
$ java HiveCreateDb

输出

Table employee created.

加载数据语句

通常,在 SQL 中创建表后,我们可以使用 Insert 语句插入数据。但在 Hive 中,我们可以使用 LOAD DATA 语句插入数据。

在将数据插入 Hive 时,最好使用 LOAD DATA 存储批量记录。加载数据有两种方法:一种是从本地文件系统加载,另一种是从 Hadoop 文件系统加载。

语法

加载数据的语法如下

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename 
[PARTITION (partcol1=val1, partcol2=val2 ...)]
  • LOCAL 是用于指定本地路径的标识符。它是可选的。
  • OVERWRITE 是可选的,用于覆盖表中的数据。
  • PARTITION 是可选的。

示例

我们将以下数据插入表中。它是一个名为sample.txt的文本文件,位于/home/user目录中。

1201  Gopal       45000    Technical manager
1202  Manisha     45000    Proof reader
1203  Masthanvali 40000    Technical writer
1204  Krian       40000    Hr Admin
1205  Kranthi     30000    Op Admin

以下查询将给定的文本加载到表中。

hive> LOAD DATA LOCAL INPATH '/home/user/sample.txt'
> OVERWRITE INTO TABLE employee;

下载成功后,您将看到以下响应

OK
Time taken: 15.905 seconds
hive>

JDBC 程序

以下是将给定数据加载到表的 JDBC 程序。

import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;

public class HiveLoadData {
   private static String driverName =
   "org.apache.hadoop.hive.jdbc.HiveDriver";
   public static void main(String[] args) throws SQLException {
      // Register driver and create driver instance
      Class.forName(driverName);
      // get connection
      Connection con = DriverManager.
      getConnection("jdbc:hive://127.0.0.1:10000/userdb", "", "");
      // create statement
      Statement stmt = con.createStatement();
      // execute statement
      stmt.executeQuery("LOAD DATA LOCAL INPATH '/home/user/sample.txt'"
      +"OVERWRITE INTO TABLE employee;");
      System.out.println("Load Data into employee successful");
      con.close();
   }
}

将程序保存在名为 HiveLoadData.java 的文件中。使用以下命令编译和执行此程序。

$ javac HiveLoadData.java
$ java HiveLoadData

输出

Load Data into employee successful

Hive - 修改表

本章说明如何更改表的属性,例如更改表名、更改列名、添加列以及删除或替换列。

更改表语句

它用于更改 Hive 中的表。

语法

根据我们希望修改表中的哪些属性,该语句采用以下任何语法。

ALTER TABLE name RENAME TO new_name
ALTER TABLE name ADD COLUMNS (col_spec[, col_spec ...])
ALTER TABLE name DROP [COLUMN] column_name
ALTER TABLE name CHANGE column_name new_name new_type
ALTER TABLE name REPLACE COLUMNS (col_spec[, col_spec ...])

重命名为...语句

以下查询将表从employee重命名为emp

hive> ALTER TABLE employee RENAME TO emp;

JDBC 程序

重命名表的 JDBC 程序如下所示。

import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet; 
import java.sql.Statement;
import java.sql.DriverManager;

public class HiveAlterRenameTo {
   private static String driverName =
   "org.apache.hadoop.hive.jdbc.HiveDriver";
   public static void main(String[] args) throws SQLException {
      // Register driver and create driver instance
      Class.forName(driverName);
      // get connection
      Connection con = DriverManager.
      getConnection("jdbc:hive://127.0.0.1:10000/userdb", "", "");
      // create statement
      Statement stmt = con.createStatement();
      // execute statement
      stmt.executeQuery("ALTER TABLE employee RENAME TO emp;");
      System.out.println("Table Renamed Successfully");
      con.close();
   }
}

将程序保存到名为 HiveAlterRenameTo.java 的文件中。使用以下命令编译并执行此程序。

$ javac HiveAlterRenameTo.java
$ java HiveAlterRenameTo

输出

Table renamed successfully.

更改语句

下表包含 **employee** 表的字段,并显示要更改的字段(以粗体显示)。

字段名称 从数据类型转换 更改字段名称 转换为数据类型
eid int eid int
name String ename String
salary Float salary Double
designation String designation String

以下查询使用上述数据重命名列名和列数据类型

hive> ALTER TABLE employee CHANGE name ename String;
hive> ALTER TABLE employee CHANGE salary salary Double;

JDBC 程序

下面是更改列的 JDBC 程序。

import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;

public class HiveAlterChangeColumn {
   private static String driverName =
   "org.apache.hadoop.hive.jdbc.HiveDriver";
   public static void main(String[] args) throws SQLException {
      // Register driver and create driver instance
      Class.forName(driverName);
      // get connection
      Connection con = DriverManager.
      getConnection("jdbc:hive://127.0.0.1:10000/userdb", "", "");
      // create statement
      Statement stmt = con.createStatement();
      // execute statement
      stmt.executeQuery("ALTER TABLE employee CHANGE name ename String;");
      stmt.executeQuery("ALTER TABLE employee CHANGE salary salary Double;");
      System.out.println("Change column successful.");
      con.close();
   }
}

将程序保存到名为 HiveAlterChangeColumn.java 的文件中。使用以下命令编译并执行此程序。

$ javac HiveAlterChangeColumn.java
$ java HiveAlterChangeColumn

输出

Change column successful.

添加列语句

以下查询向 employee 表中添加一个名为 dept 的列。

hive> ALTER TABLE employee ADD COLUMNS ( 
   > dept STRING COMMENT 'Department name');

JDBC 程序

向表中添加列的 JDBC 程序如下所示。

import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;

public class HiveAlterAddColumn {
   private static String driverName =
   "org.apache.hadoop.hive.jdbc.HiveDriver";
   public static void main(String[] args) throws SQLException {
      // Register driver and create driver instance
      Class.forName(driverName);
      // get connection
      Connection con = DriverManager.
      getConnection("jdbc:hive://127.0.0.1:10000/userdb", "", "");
     // create statement
     Statement stmt = con.createStatement();
     // execute statement
     stmt.executeQuery("ALTER TABLE employee ADD COLUMNS "
     +" (dept STRING COMMENT 'Department name');");
     System.out.prinln("Add column successful.");
     con.close();
   }
}

将程序保存到名为 HiveAlterAddColumn.java 的文件中。使用以下命令编译并执行此程序。

$ javac HiveAlterAddColumn.java
$ java HiveAlterAddColumn

输出

Add column successful.

替换语句

以下查询删除 **employee** 表中的所有列,并将其替换为 **emp** 和 **name** 列

hive> ALTER TABLE employee REPLACE COLUMNS ( 
   > eid INT empid Int, 
   > ename STRING name String);

JDBC 程序

下面是将 **eid** 列替换为 **empid** 和 **ename** 列替换为 **name** 的 JDBC 程序。

import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;

public class HiveAlterReplaceColumn {
   private static String driverName =
   "org.apache.hadoop.hive.jdbc.HiveDriver";
   public static void main(String[] args) throws SQLException {
      // Register driver and create driver instance
      Class.forName(driverName);
      // get connection
      Connection con = DriverManager.
      getConnection("jdbc:hive://127.0.0.1:10000/userdb", "", "");
      // create statement
      Statement stmt = con.createStatement();
      // execute statement
      stmt.executeQuery("ALTER TABLE employee REPLACE COLUMNS "
      +" (eid INT empid Int,"
      +" ename STRING name String);");
      System.out.println(" Replace column successful");
      con.close();
   }
}

将程序保存到名为 HiveAlterReplaceColumn.java 的文件中。使用以下命令编译并执行此程序。

$ javac HiveAlterReplaceColumn.java
$ java HiveAlterReplaceColumn

输出

Replace column successful.

Hive - 删除表

本章介绍如何在 Hive 中删除表。当您从 Hive Metastore 中删除表时,它会删除表/列数据及其元数据。它可以是普通表(存储在 Metastore 中)或外部表(存储在本地文件系统中);Hive 对两者采用相同的方式处理,无论其类型如何。

删除表语句

语法如下

DROP TABLE [IF EXISTS] table_name;

以下查询删除名为 **employee** 的表

hive> DROP TABLE IF EXISTS employee;

查询成功执行后,您将看到以下响应

OK
Time taken: 5.3 seconds
hive>

JDBC 程序

以下 JDBC 程序删除 employee 表。

import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;

public class HiveDropTable {
   private static String driverName =
   "org.apache.hadoop.hive.jdbc.HiveDriver";
   public static void main(String[] args) throws SQLException {
      // Register driver and create driver instance
      Class.forName(driverName);
      // get connection
      Connection con = DriverManager.
      getConnection("jdbc:hive://127.0.0.1:10000/userdb", "", "");
      // create statement
      Statement stmt = con.createStatement();
      // execute statement
      stmt.executeQuery("DROP TABLE IF EXISTS employee;");
     System.out.println("Drop table successful.");
     con.close();
   }
}

将程序保存到名为 HiveDropTable.java 的文件中。使用以下命令编译并执行此程序。

$ javac HiveDropTable.java
$ java HiveDropTable

输出

Drop table successful

以下查询用于验证表列表

hive> SHOW TABLES;
emp
ok
Time taken: 2.1 seconds
hive>

Hive - 分区

Hive 将表组织成分区。它是根据分区列(如日期、城市和部门)的值将表划分为相关部分的一种方式。使用分区,可以轻松查询一部分数据。

表或分区细分为 **桶**,为数据提供额外的结构,可用于更有效的查询。分桶基于表中某些列的哈希函数的值。

例如,名为 **Tab1** 的表包含员工数据,例如 id、name、dept 和 yoj(即入职年份)。假设您需要检索 2012 年入职的所有员工的详细信息。查询会搜索整个表以获取所需的信息。但是,如果您使用年份对员工数据进行分区并将其存储在单独的文件中,则可以减少查询处理时间。以下示例显示了如何对文件及其数据进行分区

以下文件包含 employeedata 表。

/tab1/employeedata/file1

id, name, dept, yoj

1, gopal, TP, 2012

2, kiran, HR, 2012

3, kaleel,SC, 2013

4, Prasanth, SC, 2013

 

上述数据使用年份划分为两个文件。

/tab1/employeedata/2012/file2

1, gopal, TP, 2012

2, kiran, HR, 2012

 

/tab1/employeedata/2013/file3

3, kaleel,SC, 2013

4, Prasanth, SC, 2013

添加分区

我们可以通过更改表来向表中添加分区。假设我们有一个名为 **employee** 的表,其字段包括 Id、Name、Salary、Designation、Dept 和 yoj。

语法

ALTER TABLE table_name ADD [IF NOT EXISTS] PARTITION partition_spec
[LOCATION 'location1'] partition_spec [LOCATION 'location2'] ...;

partition_spec:
: (p_column = p_col_value, p_column = p_col_value, ...)

以下查询用于向 employee 表中添加分区。

hive> ALTER TABLE employee
> ADD PARTITION (year=’2012’)
> location '/2012/part2012';

重命名分区

此命令的语法如下。

ALTER TABLE table_name PARTITION partition_spec RENAME TO PARTITION partition_spec;

以下查询用于重命名分区

hive> ALTER TABLE employee PARTITION (year=’1203’)
   > RENAME TO PARTITION (Yoj=’1203’);

删除分区

以下语法用于删除分区

ALTER TABLE table_name DROP [IF EXISTS] PARTITION partition_spec, PARTITION partition_spec,...;

以下查询用于删除分区

hive> ALTER TABLE employee DROP [IF EXISTS]
   > PARTITION (year=’1203’);

Hive - 内置运算符

本章介绍 Hive 的内置运算符。Hive 中有四种类型的运算符

  • 关系运算符
  • 算术运算符
  • 逻辑运算符
  • 复杂运算符

关系运算符

这些运算符用于比较两个操作数。下表描述了 Hive 中可用的关系运算符

运算符 操作数 描述
A = B 所有基本类型 如果表达式 A 等于表达式 B,则为 TRUE,否则为 FALSE。
A != B 所有基本类型 如果表达式 A 不等于表达式 B,则为 TRUE,否则为 FALSE。
A < B 所有基本类型 如果表达式 A 小于表达式 B,则为 TRUE,否则为 FALSE。
A <= B 所有基本类型 如果表达式 A 小于或等于表达式 B,则为 TRUE,否则为 FALSE。
A > B 所有基本类型 如果表达式 A 大于表达式 B,则为 TRUE,否则为 FALSE。
A >= B 所有基本类型 如果表达式 A 大于或等于表达式 B,则为 TRUE,否则为 FALSE。
A IS NULL 所有类型 如果表达式 A 评估结果为 NULL,则为 TRUE,否则为 FALSE。
A IS NOT NULL 所有类型 如果表达式 A 评估结果为 NULL,则为 FALSE,否则为 TRUE。
A LIKE B 字符串 如果字符串模式 A 与 B 匹配,则为 TRUE,否则为 FALSE。
A RLIKE B 字符串 如果 A 或 B 为 NULL,则为 NULL;如果 A 的任何子字符串与 Java 正则表达式 B 匹配,则为 TRUE,否则为 FALSE。
A REGEXP B 字符串 与 RLIKE 相同。

示例

假设 **employee** 表由名为 Id、Name、Salary、Designation 和 Dept 的字段组成,如下所示。生成一个查询以检索 Id 为 1205 的员工详细信息。

+-----+--------------+--------+---------------------------+------+
| Id  | Name         | Salary | Designation               | Dept |
+-----+--------------+------------------------------------+------+
|1201 | Gopal        | 45000  | Technical manager         | TP   |
|1202 | Manisha      | 45000  | Proofreader               | PR   |
|1203 | Masthanvali  | 40000  | Technical writer          | TP   |
|1204 | Krian        | 40000  | Hr Admin                  | HR   |
|1205 | Kranthi      | 30000  | Op Admin                  | Admin|
+-----+--------------+--------+---------------------------+------+

执行以下查询以使用上表检索员工详细信息

hive> SELECT * FROM employee WHERE Id=1205;

查询成功执行后,您将看到以下响应

+-----+-----------+-----------+----------------------------------+
| ID  | Name      | Salary    | Designation              | Dept  |
+-----+---------------+-------+----------------------------------+
|1205 | Kranthi   | 30000     | Op Admin                 | Admin |
+-----+-----------+-----------+----------------------------------+

执行以下查询以检索薪水大于或等于 40000 元的员工详细信息。

hive> SELECT * FROM employee WHERE Salary>=40000;

查询成功执行后,您将看到以下响应

+-----+------------+--------+----------------------------+------+
| ID  | Name       | Salary | Designation                | Dept |
+-----+------------+--------+----------------------------+------+
|1201 | Gopal      | 45000  | Technical manager          | TP   |
|1202 | Manisha    | 45000  | Proofreader                | PR   |
|1203 | Masthanvali| 40000  | Technical writer           | TP   |
|1204 | Krian      | 40000  | Hr Admin                   | HR   |
+-----+------------+--------+----------------------------+------+

算术运算符

这些运算符支持操作数上的各种常用算术运算。它们都返回数字类型。下表描述了 Hive 中可用的算术运算符

运算符 操作数 描述
A + B 所有数字类型 给出 A 和 B 相加的结果。
A - B 所有数字类型 给出从 A 中减去 B 的结果。
A * B 所有数字类型 给出 A 和 B 相乘的结果。
A / B 所有数字类型 给出从 A 中除以 B 的结果。
A % B 所有数字类型 给出 A 除以 B 产生的余数。
A & B 所有数字类型 给出 A 和 B 按位与的结果。
A | B 所有数字类型 给出 A 和 B 按位或的结果。
A ^ B 所有数字类型 给出 A 和 B 按位异或的结果。
~A 所有数字类型 给出 A 按位非的结果。

示例

以下查询将两个数字 20 和 30 相加。

hive> SELECT 20+30 ADD FROM temp;

查询成功执行后,您将看到以下响应

+--------+
|   ADD  |
+--------+
|   50   |
+--------+

逻辑运算符

运算符是逻辑表达式。它们都返回 TRUE 或 FALSE。

运算符 操作数 描述
A AND B 布尔值 如果 A 和 B 都为 TRUE,则为 TRUE,否则为 FALSE。
A && B 布尔值 与 A AND B 相同。
A OR B 布尔值 如果 A 或 B 或两者都为 TRUE,则为 TRUE,否则为 FALSE。
A || B 布尔值 与 A OR B 相同。
NOT A 布尔值 如果 A 为 FALSE,则为 TRUE,否则为 FALSE。
!A 布尔值 与 NOT A 相同。

示例

以下查询用于检索部门为 TP 且薪水超过 40000 元的员工详细信息。

hive> SELECT * FROM employee WHERE Salary>40000 && Dept=TP;

查询成功执行后,您将看到以下响应

+------+--------------+-------------+-------------------+--------+
| ID   | Name         | Salary      | Designation       | Dept   |
+------+--------------+-------------+-------------------+--------+
|1201  | Gopal        | 45000       | Technical manager | TP     |
+------+--------------+-------------+-------------------+--------+

复杂运算符

这些运算符提供一个表达式来访问复杂类型的元素。

运算符 操作数 描述
A[n] A 是一个数组,n 是一个整数 它返回数组 A 中的第 n 个元素。第一个元素的索引为 0。
M[key] M 是一个 Map<K, V>,key 的类型为 K 它返回映射中对应于键的值。
S.x S 是一个结构体 它返回 S 的 x 字段。

Hiveql Select...Where

Hive 查询语言 (HiveQL) 是 Hive 用于处理和分析元数据中结构化数据的查询语言。本章介绍如何将 SELECT 语句与 WHERE 子句一起使用。

SELECT 语句用于从表中检索数据。WHERE 子句的工作原理类似于条件。它使用条件过滤数据,并为您提供有限的结果。内置运算符和函数生成一个表达式,该表达式满足条件。

语法

下面是 SELECT 查询的语法

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

示例

让我们以 SELECT…WHERE 子句为例。假设我们有如下所示的 employee 表,字段名为 Id、Name、Salary、Designation 和 Dept。生成一个查询以检索薪水超过 30000 元的员工详细信息。

+------+--------------+-------------+-------------------+--------+
| ID   | Name         | Salary      | Designation       | Dept   |
+------+--------------+-------------+-------------------+--------+
|1201  | Gopal        | 45000       | Technical manager | TP     |
|1202  | Manisha      | 45000       | Proofreader       | PR     |
|1203  | Masthanvali  | 40000       | Technical writer  | TP     |
|1204  | Krian        | 40000       | Hr Admin          | HR     |
|1205  | Kranthi      | 30000       | Op Admin          | Admin  | 
+------+--------------+-------------+-------------------+--------+

以下查询使用上述场景检索员工详细信息

hive> SELECT * FROM employee WHERE salary>30000;

查询成功执行后,您将看到以下响应

+------+--------------+-------------+-------------------+--------+
| ID   | Name         | Salary      | Designation       | Dept   |
+------+--------------+-------------+-------------------+--------+
|1201  | Gopal        | 45000       | Technical manager | TP     |
|1202  | Manisha      | 45000       | Proofreader       | PR     |
|1203  | Masthanvali  | 40000       | Technical writer  | TP     |
|1204  | Krian        | 40000       | Hr Admin          | HR     |
+------+--------------+-------------+-------------------+--------+

JDBC 程序

为给定示例应用 where 子句的 JDBC 程序如下所示。

import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;

public class HiveQLWhere {
   private static String driverName =
   "org.apache.hadoop.hive.jdbc.HiveDriver";
   public static void main(String[] args) throws SQLException {
      // Register driver and create driver instance
      Class.forName(driverName);
      // get connection
      Connection con = DriverManager.
      getConnection("jdbc:hive://127.0.0.1:10000/userdb", "", "");
      // create statement
      Statement stmt = con.createStatement();
      // execute statement
      Resultset res = stmt.executeQuery("SELECT * FROM employee WHERE
      salary>30000;");
      System.out.println("Result:");
      System.out.println(" ID \t Name \t Salary \t Designation \t Dept ");
      while (res.next()) {
         System.out.println(res.getInt(1)+" "+ res.getString(2)+" "+
         res.getDouble(3)+" "+ res.getString(4)+" "+ res.getString(5));
      }
      con.close();
   }
}

将程序保存到名为 HiveQLWhere.java 的文件中。使用以下命令编译并执行此程序。

$ javac HiveQLWhere.java
$ java HiveQLWhere

输出

ID       Name           Salary      Designation          Dept
1201     Gopal          45000       Technical manager    TP
1202     Manisha        45000       Proofreader          PR
1203     Masthanvali    40000       Technical writer     TP
1204     Krian          40000       Hr Admin             HR

Hiveql Select...Order By

本章介绍如何在 SELECT 语句中使用 ORDER BY 子句。ORDER BY 子句用于根据一列检索详细信息,并按升序或降序对结果集进行排序。

语法

下面是 ORDER BY 子句的语法

SELECT [ALL | DISTINCT] select_expr, select_expr, ... 
FROM table_reference 
[WHERE where_condition] 
[GROUP BY col_list] 
[HAVING having_condition] 
[ORDER BY col_list]] 
[LIMIT number];

示例

让我们以 SELECT...ORDER BY 子句为例。假设 employee 表如下所示,字段名为 Id、Name、Salary、Designation 和 Dept。生成一个查询,以使用部门名称按顺序检索员工详细信息。

+------+--------------+-------------+-------------------+--------+
| ID   | Name         | Salary      | Designation       | Dept   |
+------+--------------+-------------+-------------------+--------+
|1201  | Gopal        | 45000       | Technical manager | TP     |
|1202  | Manisha      | 45000       | Proofreader       | PR     |
|1203  | Masthanvali  | 40000       | Technical writer  | TP     |
|1204  | Krian        | 40000       | Hr Admin          | HR     |
|1205  | Kranthi      | 30000       | Op Admin          | Admin  |
+------+--------------+-------------+-------------------+--------+

以下查询使用上述场景检索员工详细信息

hive> SELECT Id, Name, Dept FROM employee ORDER BY DEPT;

查询成功执行后,您将看到以下响应

+------+--------------+-------------+-------------------+--------+
| ID   | Name         | Salary      | Designation       | Dept   |
+------+--------------+-------------+-------------------+--------+
|1205  | Kranthi      | 30000       | Op Admin          | Admin  |
|1204  | Krian        | 40000       | Hr Admin          | HR     |
|1202  | Manisha      | 45000       | Proofreader       | PR     |
|1201  | Gopal        | 45000       | Technical manager | TP     |
|1203  | Masthanvali  | 40000       | Technical writer  | TP     |
+------+--------------+-------------+-------------------+--------+

JDBC 程序

以下是为给定示例应用 Order By 子句的 JDBC 程序。

import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;

public class HiveQLOrderBy {
   private static String driverName =
   "org.apache.hadoop.hive.jdbc.HiveDriver";
   public static void main(String[] args) throws SQLException {
      // Register driver and create driver instance
      Class.forName(driverName);
      // get connection
      Connection con = DriverManager.
      getConnection("jdbc:hive://127.0.0.1:10000/userdb", "", "");
      // create statement 
      Statement stmt = con.createStatement();
      // execute statement
      Resultset res = stmt.executeQuery("SELECT * FROM employee ORDER BY
      DEPT;");
      System.out.println(" ID \t Name \t Salary \t Designation \t Dept ");
      while (res.next()) {
         System.out.println(res.getInt(1)+" "+ res.getString(2)+" "+
         res.getDouble(3)+" "+ res.getString(4)+" "+ res.getString(5));
      }
      con.close();
   }
}

将程序保存到名为 HiveQLOrderBy.java 的文件中。使用以下命令编译并执行此程序。

$ javac HiveQLOrderBy.java
$ java HiveQLOrderBy

输出

ID       Name           Salary      Designation          Dept
1205     Kranthi        30000       Op Admin             Admin
1204     Krian          40000       Hr Admin             HR
1202     Manisha        45000       Proofreader          PR
1201     Gopal          45000       Technical manager    TP
1203     Masthanvali    40000       Technical writer     TP
1204     Krian          40000       Hr Admin             HR

Hiveql Group By

本章详细介绍了 SELECT 语句中 GROUP BY 子句的细节。GROUP BY 子句用于使用特定集合列对结果集中的所有记录进行分组。它用于查询一组记录。

语法

GROUP BY 子句的语法如下

SELECT [ALL | DISTINCT] select_expr, select_expr, ... 
FROM table_reference 
[WHERE where_condition] 
[GROUP BY col_list] 
[HAVING having_condition] 
[ORDER BY col_list]] 
[LIMIT number];

示例

让我们以 SELECT…GROUP BY 子句为例。假设 employee 表如下所示,字段为 Id、Name、Salary、Designation 和 Dept。生成一个查询以检索每个部门的员工人数。

+------+--------------+-------------+-------------------+--------+ 
| ID   | Name         | Salary      | Designation       | Dept   |
+------+--------------+-------------+-------------------+--------+ 
|1201  | Gopal        | 45000       | Technical manager | TP     | 
|1202  | Manisha      | 45000       | Proofreader       | PR     | 
|1203  | Masthanvali  | 40000       | Technical writer  | TP     | 
|1204  | Krian        | 45000       | Proofreader       | PR     | 
|1205  | Kranthi      | 30000       | Op Admin          | Admin  |
+------+--------------+-------------+-------------------+--------+

以下查询使用上述场景检索员工详细信息。

hive> SELECT Dept,count(*) FROM employee GROUP BY DEPT;

查询成功执行后,您将看到以下响应

+------+--------------+ 
| Dept | Count(*)     | 
+------+--------------+ 
|Admin |    1         | 
|PR    |    2         | 
|TP    |    3         | 
+------+--------------+

JDBC 程序

下面是为给定示例应用 Group By 子句的 JDBC 程序。

import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;

public class HiveQLGroupBy {
   private static String driverName =
   "org.apache.hadoop.hive.jdbc.HiveDriver";
   public static void main(String[] args) throws SQLException {
      // Register driver and create driver instance
      Class.forName(driverName);
      // get connection
      Connection con = DriverManager.
      getConnection("jdbc:hive://127.0.0.1:10000/userdb", "", "");
      // create statement
      Statement stmt = con.createStatement();
      // execute statement
      Resultset res = stmt.executeQuery(“SELECT Dept,count(*) ”
      +“FROM employee GROUP BY DEPT; ”);
      System.out.println(" Dept \t count(*)");
      while (res.next()) {
         System.out.println(res.getString(1)+" "+ res.getInt(2)); 
      }
      con.close();
   }
}

将程序保存到名为 HiveQLGroupBy.java 的文件中。使用以下命令编译并执行此程序。

$ javac HiveQLGroupBy.java
$ java HiveQLGroupBy

输出

 Dept     Count(*)
 Admin       1
 PR          2
 TP          3

Hiveql Joins

JOINS 是一个用于通过使用每个表共有的值来组合来自两个表的特定字段的子句。它用于组合数据库中两个或多个表中的记录。

语法

join_table:

   table_reference JOIN table_factor [join_condition]
   | table_reference {LEFT|RIGHT|FULL} [OUTER] JOIN table_reference
   join_condition
   | table_reference LEFT SEMI JOIN table_reference join_condition
   | table_reference CROSS JOIN table_reference [join_condition]

示例

我们将在本章中使用以下两个表。请考虑以下名为 CUSTOMERS 的表..

+----+----------+-----+-----------+----------+ 
| ID | NAME     | AGE | ADDRESS   | SALARY   | 
+----+----------+-----+-----------+----------+ 
| 1  | Ramesh   | 32  | Ahmedabad | 2000.00  |  
| 2  | Khilan   | 25  | Delhi     | 1500.00  |  
| 3  | kaushik  | 23  | Kota      | 2000.00  | 
| 4  | Chaitali | 25  | Mumbai    | 6500.00  | 
| 5  | Hardik   | 27  | Bhopal    | 8500.00  | 
| 6  | Komal    | 22  | MP        | 4500.00  | 
| 7  | Muffy    | 24  | Indore    | 10000.00 | 
+----+----------+-----+-----------+----------+

再考虑另一个名为 ORDERS 的表

+-----+---------------------+-------------+--------+ 
|OID  | DATE                | CUSTOMER_ID | AMOUNT | 
+-----+---------------------+-------------+--------+ 
| 102 | 2009-10-08 00:00:00 |           3 | 3000   | 
| 100 | 2009-10-08 00:00:00 |           3 | 1500   | 
| 101 | 2009-11-20 00:00:00 |           2 | 1560   | 
| 103 | 2008-05-20 00:00:00 |           4 | 2060   | 
+-----+---------------------+-------------+--------+

以下是不同类型的连接

  • JOIN
  • LEFT OUTER JOIN
  • RIGHT OUTER JOIN
  • FULL OUTER JOIN

JOIN

JOIN 子句用于组合和检索来自多个表的记录。JOIN 与 SQL 中的 OUTER JOIN 相同。JOIN 条件需要使用表的 primary keys 和 foreign keys 来提出。

以下查询在 CUSTOMER 和 ORDER 表上执行 JOIN,并检索记录

hive> SELECT c.ID, c.NAME, c.AGE, o.AMOUNT 
   > FROM CUSTOMERS c JOIN ORDERS o 
   > ON (c.ID = o.CUSTOMER_ID);

查询成功执行后,您将看到以下响应

+----+----------+-----+--------+ 
| ID | NAME     | AGE | AMOUNT | 
+----+----------+-----+--------+ 
| 3  | kaushik  | 23  | 3000   | 
| 3  | kaushik  | 23  | 1500   | 
| 2  | Khilan   | 25  | 1560   | 
| 4  | Chaitali | 25  | 2060   | 
+----+----------+-----+--------+

LEFT OUTER JOIN

HiveQL LEFT OUTER JOIN 返回左侧表中的所有行,即使右侧表中没有匹配项也是如此。这意味着,如果 ON 子句在右侧表中匹配 0(零)条记录,则 JOIN 仍会在结果中返回一行,但在右侧表中的每一列中都为 NULL。

LEFT JOIN 返回左侧表中的所有值,加上右侧表中匹配的值,或者在没有匹配的 JOIN 谓词的情况下为 NULL。

以下查询演示了 CUSTOMER 和 ORDER 表之间的 LEFT OUTER JOIN

hive> SELECT c.ID, c.NAME, o.AMOUNT, o.DATE 
   > FROM CUSTOMERS c 
   > LEFT OUTER JOIN ORDERS o 
   > ON (c.ID = o.CUSTOMER_ID);

查询成功执行后,您将看到以下响应

+----+----------+--------+---------------------+ 
| ID | NAME     | AMOUNT | DATE                | 
+----+----------+--------+---------------------+ 
| 1  | Ramesh   | NULL   | NULL                | 
| 2  | Khilan   | 1560   | 2009-11-20 00:00:00 | 
| 3  | kaushik  | 3000   | 2009-10-08 00:00:00 | 
| 3  | kaushik  | 1500   | 2009-10-08 00:00:00 | 
| 4  | Chaitali | 2060   | 2008-05-20 00:00:00 | 
| 5  | Hardik   | NULL   | NULL                | 
| 6  | Komal    | NULL   | NULL                | 
| 7  | Muffy    | NULL   | NULL                | 
+----+----------+--------+---------------------+

RIGHT OUTER JOIN

HiveQL RIGHT OUTER JOIN 返回右侧表中的所有行,即使左侧表中没有匹配项。如果 ON 子句在左侧表中匹配 0(零)条记录,则 JOIN 仍会在结果中返回一行,但在左侧表的每一列中都填充 NULL。

RIGHT JOIN 返回右侧表中的所有值,以及左侧表中匹配的值,或者在没有匹配联接谓词的情况下返回 NULL。

以下查询演示了 CUSTOMER 和 ORDER 表之间的 RIGHT OUTER JOIN。

hive> SELECT c.ID, c.NAME, o.AMOUNT, o.DATE 
   > FROM CUSTOMERS c 
   > RIGHT OUTER JOIN ORDERS o 
   > ON (c.ID = o.CUSTOMER_ID);

查询成功执行后,您将看到以下响应

+------+----------+--------+---------------------+ 
| ID   | NAME     | AMOUNT | DATE                | 
+------+----------+--------+---------------------+ 
| 3    | kaushik  | 3000   | 2009-10-08 00:00:00 | 
| 3    | kaushik  | 1500   | 2009-10-08 00:00:00 | 
| 2    | Khilan   | 1560   | 2009-11-20 00:00:00 | 
| 4    | Chaitali | 2060   | 2008-05-20 00:00:00 | 
+------+----------+--------+---------------------+

FULL OUTER JOIN

HiveQL FULL OUTER JOIN 组合了满足 JOIN 条件的左侧和右侧外部表两者的记录。联接表包含来自两个表的所有记录,或者为任一侧缺少的匹配项填充 NULL 值。

以下查询演示了 CUSTOMER 和 ORDER 表之间的 FULL OUTER JOIN

hive> SELECT c.ID, c.NAME, o.AMOUNT, o.DATE 
   > FROM CUSTOMERS c 
   > FULL OUTER JOIN ORDERS o 
   > ON (c.ID = o.CUSTOMER_ID);

查询成功执行后,您将看到以下响应

+------+----------+--------+---------------------+ 
| ID   | NAME     | AMOUNT | DATE                | 
+------+----------+--------+---------------------+ 
| 1    | Ramesh   | NULL   | NULL                | 
| 2    | Khilan   | 1560   | 2009-11-20 00:00:00 | 
| 3    | kaushik  | 3000   | 2009-10-08 00:00:00 | 
| 3    | kaushik  | 1500   | 2009-10-08 00:00:00 | 
| 4    | Chaitali | 2060   | 2008-05-20 00:00:00 | 
| 5    | Hardik   | NULL   | NULL                | 
| 6    | Komal    | NULL   | NULL                |
| 7    | Muffy    | NULL   | NULL                |  
| 3    | kaushik  | 3000   | 2009-10-08 00:00:00 | 
| 3    | kaushik  | 1500   | 2009-10-08 00:00:00 | 
| 2    | Khilan   | 1560   | 2009-11-20 00:00:00 | 
| 4    | Chaitali | 2060   | 2008-05-20 00:00:00 | 
+------+----------+--------+---------------------+

Hive - 内置函数

本章解释了 Hive 中可用的内置函数。除了用法之外,这些函数看起来与 SQL 函数非常相似。

内置函数

Hive 支持以下内置函数

返回类型 签名 描述
BIGINT round(double a) 它返回 double 的四舍五入后的 BIGINT 值。
BIGINT floor(double a) 它返回等于或小于 double 的最大 BIGINT 值。
BIGINT ceil(double a) 它返回等于或大于 double 的最小 BIGINT 值。
double rand(), rand(int seed) 它返回一个随机数,该随机数随行而异。
string concat(string A, string B,...) 它返回将 B 连接到 A 后形成的字符串。
string substr(string A, int start) 它返回从起始位置到字符串 A 末尾的 A 的子字符串。
string substr(string A, int start, int length) 它返回从起始位置开始,长度为给定长度的 A 的子字符串。
string upper(string A) 它返回将 A 的所有字符转换为大写后形成的字符串。
string ucase(string A) 与上面相同。
string lower(string A) 它返回将 B 的所有字符转换为小写后形成的字符串。
string lcase(string A) 与上面相同。
string trim(string A) 它返回从 A 的两端去除空格后形成的字符串。
string ltrim(string A) 它返回从 A 的开头(左侧)去除空格后形成的字符串。
string rtrim(string A) rtrim(string A) 它返回从 A 的末尾(右侧)去除空格后形成的字符串。
string regexp_replace(string A, string B, string C) 它返回用 C 替换 B 中与 Java 正则表达式语法匹配的所有子字符串后形成的字符串。
int size(Map<K.V>) 它返回映射类型中元素的数量。
int size(Array<T>) 它返回数组类型中元素的数量。
<type> 的值 cast(<expr> as <type>) 它将表达式 expr 的结果转换为 <type>,例如 cast('1' as BIGINT) 将字符串 '1' 转换为其整数表示。如果转换不成功,则返回 NULL。
string from_unixtime(int unixtime) 将自 Unix 纪元(1970-01-01 00:00:00 UTC)以来的秒数转换为表示当前系统时区中该时刻时间戳的字符串,格式为“1970-01-01 00:00:00”
string to_date(string timestamp) 它返回时间戳字符串的日期部分:to_date("1970-01-01 00:00:00") = "1970-01-01"
int year(string date) 它返回日期或时间戳字符串的年份部分:year("1970-01-01 00:00:00") = 1970,year("1970-01-01") = 1970
int month(string date) 它返回日期或时间戳字符串的月份部分:month("1970-11-01 00:00:00") = 11,month("1970-11-01") = 11
int day(string date) 它返回日期或时间戳字符串的日期部分:day("1970-11-01 00:00:00") = 1,day("1970-11-01") = 1
string get_json_object(string json_string, string path) 它根据指定的 json 路径从 json 字符串中提取 json 对象,并返回提取的 json 对象的 json 字符串。如果输入的 json 字符串无效,则返回 NULL。

示例

以下查询演示了一些内置函数

round() 函数

hive> SELECT round(2.6) from temp;

查询成功执行后,您将看到以下响应

3.0

floor() 函数

hive> SELECT floor(2.6) from temp;

查询成功执行后,您将看到以下响应

2.0

ceil() 函数

hive> SELECT ceil(2.6) from temp;

查询成功执行后,您将看到以下响应

3.0

聚合函数

Hive 支持以下内置聚合函数。这些函数的用法与 SQL 聚合函数相同。

返回类型 签名 描述
BIGINT count(*), count(expr), count(*) - 返回检索到的行总数。
DOUBLE sum(col), sum(DISTINCT col) 它返回组中元素的总和或组中列的不同值的总和。
DOUBLE avg(col), avg(DISTINCT col) 它返回组中元素的平均值或组中列的不同值的平均值。
DOUBLE min(col) 它返回组中列的最小值。
DOUBLE max(col) 它返回组中列的最大值。

Hive - 视图和索引

本章介绍如何创建和管理视图。视图是根据用户需求生成的。您可以将任何结果集数据保存为视图。Hive 中视图的用法与 SQL 中的视图相同。这是一个标准的 RDBMS 概念。我们可以在视图上执行所有 DML 操作。

创建视图

您可以在执行 SELECT 语句时创建视图。语法如下

CREATE VIEW [IF NOT EXISTS] view_name [(column_name [COMMENT column_comment], ...) ]
[COMMENT table_comment]
AS SELECT ...

示例

让我们以视图为例。假设员工表如下所示,字段为 Id、Name、Salary、Designation 和 Dept。生成一个查询以检索薪资超过 30000 元的员工详细信息。我们将结果存储在名为emp_30000的视图中。

+------+--------------+-------------+-------------------+--------+
| ID   | Name         | Salary      | Designation       | Dept   |
+------+--------------+-------------+-------------------+--------+
|1201  | Gopal        | 45000       | Technical manager | TP     |
|1202  | Manisha      | 45000       | Proofreader       | PR     |
|1203  | Masthanvali  | 40000       | Technical writer  | TP     |
|1204  | Krian        | 40000       | Hr Admin          | HR     |
|1205  | Kranthi      | 30000       | Op Admin          | Admin  |
+------+--------------+-------------+-------------------+--------+

以下查询使用上述场景检索员工详细信息

hive> CREATE VIEW emp_30000 AS
   > SELECT * FROM employee
   > WHERE salary>30000;

删除视图

使用以下语法删除视图

DROP VIEW view_name

以下查询删除名为 emp_30000 的视图

hive> DROP VIEW emp_30000;

创建索引

索引只不过是指向表特定列的指针。创建索引意味着在表的特定列上创建指针。其语法如下

CREATE INDEX index_name
ON TABLE base_table_name (col_name, ...)
AS 'index.handler.class.name'
[WITH DEFERRED REBUILD]
[IDXPROPERTIES (property_name=property_value, ...)]
[IN TABLE index_table_name]
[PARTITIONED BY (col_name, ...)]
[
   [ ROW FORMAT ...] STORED AS ...
   | STORED BY ...
]
[LOCATION hdfs_path]
[TBLPROPERTIES (...)]

示例

让我们以索引为例。使用我们之前使用过的相同的员工表,字段为 Id、Name、Salary、Designation 和 Dept。在员工表的 salary 列上创建一个名为 index_salary 的索引。

以下查询创建了一个索引

hive> CREATE INDEX inedx_salary ON TABLE employee(salary)
   > AS 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler';

它是 salary 列的指针。如果修改了该列,则使用索引值存储更改。

删除索引

以下语法用于删除索引

DROP INDEX <index_name> ON <table_name>

以下查询删除名为 index_salary 的索引

hive> DROP INDEX index_salary ON employee;
广告