Hive 简明教程
Hive - Introduction
“大数据”一词用于海量数据集的集合,包含海量数据、高速和随日益增加的各种数据。使用传统的数据管理系统很难处理大数据。因此,Apache 软件基金会引入了一个称为 Hadoop 的框架来解决大数据管理和处理难题。
Hadoop
Hadoop 是一个开源框架,用于在分布式环境中存储和处理大数据。它包含两个模块,一个是 MapReduce,另一个是 Hadoop 分布式文件系统 (HDFS)。
-
MapReduce: 它是一款并行编程模型,用于在大量的商品硬件集群上处理大量结构化、半结构化和非结构化数据。
-
*HDFS:*Hadoop 分布式文件系统是 Hadoop 框架的一部分,用于存储和处理数据集。它提供了一个基于商品硬件上运行的、容错的文件系统。
Hadoop 生态系统包含不同的子项目(工具),例如 Sqoop、Pig 和 Hive,可用于对 Hadoop 模块提供帮助。
-
Sqoop: 用于在 HDFS 和 RDBMS 之间导入和导出数据。
-
Pig: 是用于为 MapReduce 操作开发脚本的程序语言平台。
-
Hive: 是用于开发 SQL 类型脚本以执行 MapReduce 操作的平台。
Note: 有多种执行 MapReduce 操作的方式:
-
使用 Java MapReduce 程序针对结构化、半结构化和非结构化数据采用的传统方式。
-
使用 Pig 针对结构化和半结构化数据处理 MapReduce 的脚本方式。
-
用于使用 Hive 处理结构化数据的 MapReduce 的 Hive 查询语言(HiveQL 或 HQL)。
What is Hive
Hive 是用于处理 Hadoop 中结构化数据的数据库基础架构工具。它立足于 Hadoop 之上,用于对大数据进行汇总,并使查询和分析变得容易。
Hive 最初由 Facebook 开发,后由 Apache 软件基金会接手并以开源形式进一步开发,名为 Apache Hive。它被不同公司所使用。例如,Amazon 在 Amazon Elastic MapReduce 中使用它。
Features of Hive
-
它将架构存储在数据库中并将经过处理的数据压入 HDFS。
-
它专为 OLAP 而设计。
-
它为查询提供了名为 HiveQL 或 HQL 的 SQL 类型语言。
-
它很熟悉、快速、可扩展且可拓展。
Architecture of Hive
以下组件图解显示了 Hive 的架构:
该组件图解包含不同的单元。下表描述了每个单元:
Unit Name |
Operation |
User Interface |
Hive 是一种数据仓库基础架构软件,它能够在用户和 HDFS 之间创建交互。Hive 支持的用户界面包括 Hive Web UI、Hive 命令行和 Hive HD Insight(在 Windows 服务器中)。 |
Meta Store |
Hive 选择各自的数据库服务器来存储数据库、表中的列、其数据类型和 HDFS 映射的架构或元数据。 |
HiveQL Process Engine |
HiveQL 类似于 SQL,用于查询元数据中的架构信息。它是传统的 MapReduce 程序方法的替代方法之一。我们可以编写 MapReduce 作业和处理它的查询,而不是在 Java 中编写 MapReduce 程序。 |
Execution Engine |
HiveQL 处理引擎和 MapReduce 的结合部分是 Hive 执行引擎。执行引擎处理查询并生成与 MapReduce 结果相同的结果。它使用 MapReduce 的代码风格。 |
HDFS or HBASE |
Hadoop 分布式文件系统或 HBASE 是将数据存储到文件系统中的数据存储技术。 |
Working of Hive
下图描述了 Hive 和 Hadoop 之间的工作流程。
下表定义了 Hive 如何与 Hadoop 框架交互:
Step No. |
Operation |
1 |
*Execute Query*Hive 接口(例如命令行或 Web UI)将查询发送给驱动程序(任何数据库驱动程序,例如 JDBC、ODBC 等)以执行。 |
2 |
*Get Plan*驱动程序在查询编译器的帮助下对查询进行解析,以检查语法和查询计划或查询需求。 |
3 |
*Get Metadata*编译器向元数据存储(任何数据库)发送元数据请求。 |
4 |
*Send Metadata*元数据存储向编译器发送元数据作为响应。 |
5 |
*Send Plan*编译器检查需求并将计划重新发送给驱动程序。到此,查询的解析和编译过程完成。 |
6 |
*Execute Plan*驱动程序将执行计划发送给执行引擎。 |
7 |
*Execute Job*在内部,执行作业的过程是一个 MapReduce 作业。执行引擎将作业发送给 Name 节点中的 JobTracker,它将作业分配给 Data 节点中的 TaskTracker。在此,查询会执行 MapReduce 作业。 |
7.1 |
*Metadata Ops*同时在执行过程中,执行引擎可对元数据存储执行元数据操作。 |
8 |
*Fetch Result*执行引擎从 Data 节点接收结果。 |
9 |
*Send Results*执行引擎将这些结果值发送给驱动程序。 |
10 |
*Send Results*驱动程序将结果发送给 Hive 接口。 |
Hive - Installation
Hive、Pig 和 HBase 等所有 Hadoop 子项目都支持 Linux 操作系统。因此,你需要安装任何 Linux 操作系统。对于 Hive 安装,执行以下简单步骤:
Step 1: Verifying JAVA Installation
在安装 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。
Installing Java
Step I:
通过访问以下链接下载 java (JDK <最新版本> - X64.tar.gz) [role="bare"] [role="bare"]http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.htmlhttp://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html .
然后系统将会下载 jdk-7u71-linux-x64.tar.gz。
Step II:
通常,您将在下载文件夹中找到下载的 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
Step 2: Verifying Hadoop Installation
在安装 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,那么请执行以下步骤:
Downloading 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
Installing Hadoop in Pseudo Distributed Mode
以下步骤用于在伪分布模式下安装 Hadoop 2.4.1。
Step I: Setting up 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
Step II: Hadoop Configuration
您可以在位置 “$HADOOP_HOME/etc/hadoop” 中找到所有 Hadoop 配置文件。根据您的 Hadoop 基础架构,您需要在这些配置文件中进行适当的更改。
$ cd $HADOOP_HOME/etc/hadoop
为了使用 Java 开发 Hadoop 程序,您必须通过将 JAVA_HOME 值替换为您系统中 Java 的位置来在 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://localhost:9000</value>
</property>
</configuration>
hdfs-site.xml
hdfs-site.xml 文件包含信息,例如,本地文件系统的复制数据的值、名称节点路径和数据节点路径。这意味着您要存储 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>
Note: 在上述文件中,所有属性值都是用户定义的,可以根据 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 Framework。默认情况下,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>
Verifying Hadoop Installation
以下步骤用于验证 Hadoop 安装。
Step I: Name Node Setup
使用命令 “hdfs namenode -format” 设置名称节点,如下所示。
$ 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
************************************************************/
Step II: Verifying 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]
Step III: Verifying Yarn Script
以下命令用于启动 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
Step IV: Accessing Hadoop on Browser
访问 Hadoop 的默认端口号为 50070。使用以下 URL 在浏览器上获取 Hadoop 服务。
http://localhost:50070/
Step V: Verify all applications for cluster
访问集群所有应用程序的默认端口号为 8088。使用以下网址访问此服务。
http://localhost:8088/
Step 3: Downloading 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
Step 4: Installing Hive
需要执行以下步骤来在系统上安装 Hive。假设 Hive 归档下载到了 /Downloads 目录。
Extracting and verifying Hive Archive
以下命令用于验证下载并提取 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
Step 5: Configuring Hive
要使用 Hadoop 配置 Hive,您需要编辑 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 安装。现在,您需要一个外部数据库服务器来配置 Metastore。我们使用 Apache Derby 数据库。
Step 6: Downloading and Installing Apache Derby
执行以下步骤下载并安装 Apache Derby:
Downloading 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
Extracting and verifying Derby archive
使用以下命令解压并验证 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
Copying files to /usr/local/derby directory
我们需要从超级用户“su -”进行复制。使用以下命令从解压后的目录复制文件到 /usr/local/derby 目录:
$ su -
passwd:
# cd /home/user
# mv db-derby-10.4.2.0-bin /usr/local/derby
# exit
Step 7: Configuring Metastore of Hive
配置 Metastore 意味着向 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://localhost: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
Step 8: Verifying Hive Installation
在运行 Hive 之前,您需要在 HDFS 中创建 /tmp 文件夹和一个单独的 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 - Data Types
本章将介绍 Hive 中的各种数据类型,这些数据类型都参与表创建。Hive 中的所有数据类型都分为以下四类:
-
Column Types
-
Literals
-
Null Values
-
Complex Types
Column Types
列类型用作 Hive 的列数据类型。如下所示:
Integral Types
整型数据类型可以使用整数数据类型 INT 指定。当数据范围超过INT的范围时,您需要使用BIGINT,如果数据范围小于INT,则可以使用SMALLINT。TINYINT小于SMALLINT。
下表描绘了各种 INT 数据类型:
Type |
Postfix |
Example |
TINYINT |
Y |
10Y |
SMALLINT |
S |
10S |
INT |
- |
10 |
BIGINT |
L |
10L |
String Types
字符串类型数据类型可以使用单引号(')或双引号(")指定。它包含两种数据类型:VARCHAR 和 CHAR。Hive 遵循 C 类型转义字符。
下表列出了各种 CHAR 数据类型:
Data Type |
Length |
VARCHAR |
1 to 65355 |
CHAR |
255 |
Timestamp
它支持传统的 UNIX 时间戳,并具有可选的纳秒精度。它支持 java.sql.Timestamp 格式“YYYY-MM-DD HH:MM:SS.fffffffff”和格式“yyyy-mm-dd hh:mm:ss.ffffffffff”。
Hive - Create Database
Hive 是一种数据库技术,用于定义可分析结构化数据的数据库和数据表。结构化数据分析的主题是将数据以表格形式进行存储,并传递查询以进行分析。本章解释了如何创建 Hive 数据库。Hive 包含一个名为 default 的默认数据库。
Create Database Statement
Create Database 是一款用于在 Hive 中创建数据库的语句。Hive 中的数据库是 namespace 或一系列数据表。此语句的 syntax 如下:
CREATE DATABASE|SCHEMA [IF NOT EXISTS] <database name>
此处,IF NOT EXISTS 是一个可选项,用于通知用户是否已存在同名数据库。我们可以在此命令中使用 SCHEMA 代替 DATABASE。执行以下查询可创建名为 userdb 的数据库:
hive> CREATE DATABASE [IF NOT EXISTS] userdb;
or
hive> CREATE SCHEMA userdb;
使用以下查询可验证数据库列表:
hive> SHOW DATABASES;
default
userdb
JDBC Program
以下为创建数据库的 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://localhost: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
Hive - Drop Database
本章介绍如何在 Hive 中删除数据库。SCHEMA 和 DATABASE 的用法相同。
Drop Database Statement
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 Program
以下为删除数据库的 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://localhost: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
Hive - Create Table
本章说明了如何创建表以及如何向其中插入数据。在 HIVE 中创建表的约定与使用 SQL 创建表非常相似。
Create Table Statement
Create Table 是一款用于在 Hive 中创建表的语句。语法和示例如下:
Syntax
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]
Example
让我们假设您需要使用 CREATE TABLE 语句创建一个名为 employee 的表。下表列出了员工表中的字段及其数据类型:
Sr.No |
Field Name |
Data Type |
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 Program
下面给出了创建表的 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://localhost: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
Load Data Statement
通常,在 SQL 中创建表之后,我们可以使用 Insert 语句插入数据。但在 Hive 中,我们可以使用 LOAD DATA 语句插入数据。
在将数据插入 Hive 时,最好使用 LOAD DATA 存储大量记录。有两种方法可以加载数据:一种是来自本地文件系统,另一种是来自 Hadoop 文件系统。
Syntex
加载数据的语法如下:
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename
[PARTITION (partcol1=val1, partcol2=val2 ...)]
-
LOCAL 是指定本地路径的标识符。它是可选的。
-
OVERWRITE 可选,可覆盖表中的数据。
-
PARTITION is optional.
Example
我们将向表中插入以下数据。它是一个文本文件,名为 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 Program
下面给出了将给定数据加载到表中的 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://localhost: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
Hive - Alter Table
本章介绍如何修改表的属性,例如更改表名、更改列名、添加列以及删除或替换列。
Rename To… Statement
以下查询将表从 employee 重命名为 emp 。
hive> ALTER TABLE employee RENAME TO emp;
JDBC Program
用于重命名表的 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://localhost: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
Change Statement
下表包含 employee 表的字段,并显示要更改的字段(以粗体显示)。
Field Name |
Convert from Data Type |
Change Field Name |
Convert to Data Type |
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 Program
以下是用于更改列的 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://localhost: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
Add Columns Statement
以下查询向 employee 表中添加一个名为 dept 的列。
hive> ALTER TABLE employee ADD COLUMNS (
> dept STRING COMMENT 'Department name');
JDBC Program
用于向表中添加列的 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://localhost: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
Replace Statement
以下查询从 employee 表中删除所有列,并用 emp 和 name 列替换。
hive> ALTER TABLE employee REPLACE COLUMNS (
> eid INT empid Int,
> ename STRING name String);
JDBC Program
以下是用于用 empid 和 ename *column with *name 替换 eid 列的 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://localhost: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
Hive - Drop Table
本章介绍如何在 Hive 中删除数据表。在从 Hive Metastore 中删除数据表时,它将删除该数据表/列数据及其元数据。它可以是常规数据表(存储在 Metastore 中)或外部数据表(存储在本地文件系统中);与它们的类型无关,Hive 会将两者以相同的方式进行处理。
Drop Table Statement
语法如下:
DROP TABLE [IF EXISTS] table_name;
以下查询删除名为 employee 的数据表:
hive> DROP TABLE IF EXISTS employee;
在成功执行查询后,您可以看到以下响应:
OK
Time taken: 5.3 seconds
hive>
JDBC Program
以下 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://localhost: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
Hive - Partitioning
Hive 会将表组织成分区。这是一种基于分区列(如日期、城市和部门)的值将表分成相关部分的方法。使用分区可以轻松地查询部分数据。
表或分区被细分 buckets, 以便向数据提供额外结构,这些结构可用于更有效的查询。分桶基于表某些列的哈希函数值进行工作。
例如,名为 Tab1 的表包含诸如 id、名称、部门和 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
我无法使用 Gemini 翻译任何内容。
上面数据使用年份分成两个文件。
/tab1/employeedata/2012/file2
1、gopal、TP、2012
2、kiran、HR、2012
我无法使用 Gemini 翻译任何内容。
/tab1/employeedata/2013/file3
3、kaleel、SC、2013
4、Prasanth、SC、2013
Adding a Partition
我们可以通过更改表格来向表格添加分区。让我们假设我们有一个名为 employee 的表格,其中包含诸如Id、姓名、工资、职务、部门和yoj等字段。
Syntax:
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';
Hive - Built-in Operators
本章解释了 Hive 的内置运算符。Hive 中有四种类型的运算符:
-
Relational Operators
-
Arithmetic Operators
-
Logical Operators
-
Complex Operators
Relational Operators
这些运算符用于比较两个操作数。下表描述了 Hive 中可用的关系运算符:
Operator |
Operand |
Description |
A = B |
all primitive types |
如果表达式 A 等效于表达式 B,则为 TRUE,否则为 FALSE。 |
A != B |
all primitive types |
如果表达式 A 不等效于表达式 B,则为 TRUE,否则为 FALSE。 |
A < B |
all primitive types |
如果表达式 A 小于表达式 B,则为 TRUE,否则为 FALSE。 |
A ⇐ B |
all primitive types |
如果表达式 A 小于或等于表达式 B,则为 TRUE,否则为 FALSE。 |
A > B |
all primitive types |
如果表达式 A 大于表达式 B,则为 TRUE,否则为 FALSE。 |
A >= B |
all primitive types |
如果表达式 A 大于或等于表达式 B,则为 TRUE,否则为 FALSE。 |
A IS NULL |
all types |
如果表达式 A 求值为 NULL,则为 TRUE,否则为 FALSE。 |
A IS NOT NULL |
all types |
如果表达式 A 求值为 NULL,则为 FALSE,否则为 TRUE。 |
A LIKE B |
Strings |
如果字符串模式 A 与 B 匹配,则为 TRUE,否则为 FALSE。 |
A RLIKE B |
Strings |
如果 A 或 B 为 NULL,则为 NULL,如果 A 的任何子串与 Java 正则表达式 B 匹配,则为 TRUE,否则为 FALSE。 |
A REGEXP B |
Strings |
Same as RLIKE. |
Example
让我们假设 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 |
+-----+------------+--------+----------------------------+------+
Arithmetic Operators
这些运算符支持操作数上的各种常见算术运算。它们都返回数字类型。下表描述了 Hive 中可用的算术运算符:
Operators |
Operand |
Description |
A + B |
all number types |
给出 A 和 B 相加的结果。 |
A - B |
all number types |
给出从 A 中减去 B 的结果。 |
A * B |
all number types |
给出 A 和 B 相乘的结果。 |
A / B |
all number types |
给出 B 从 A 中除的结果。 |
A % B |
all number types |
给出 A 除以 B 的余数。 |
A & B |
all number types |
给出 A 和 B 按位与的结果。 |
A |
B |
all number types |
给出 A 和 B 按位或的结果。 |
A ^ B |
all number types |
给出 A 和 B 按位异或的结果。 |
~A |
all number types |
Logical Operators
运算符是逻辑表达式。它们都返回 TRUE 或 FALSE。
Operators |
Operands |
Description |
A AND B |
boolean |
如果 A 和 B 都为 TRUE,则为 TRUE,否则为 FALSE。 |
A && B |
boolean |
与 A AND B 相同。 |
A OR B |
boolean |
如果 A 或 B 或两者都为 TRUE,则为 TRUE,否则为 FALSE。 |
A |
B |
|
boolean |
与 A OR B 相同。 |
NOT A |
boolean |
如果 A 为 FALSE,则为 TRUE,否则为 FALSE。 |
!A |
Example
以下查询用于检索部门为 TP 且薪水大于 40000 卢比的员工详细信息。
hive> SELECT * FROM employee WHERE Salary>40000 && Dept=TP;
在成功执行查询后,您可以看到以下响应:
+------+--------------+-------------+-------------------+--------+
| ID | Name | Salary | Designation | Dept |
+------+--------------+-------------+-------------------+--------+
|1201 | Gopal | 45000 | Technical manager | TP |
+------+--------------+-------------+-------------------+--------+
Hiveql Select…Where
Hive 查询语言 (HiveQL) 是 Hive 处理和分析 Metastore 中结构化数据的查询语言。本章解释了如何将 SELECT 语句与 WHERE 子句结合使用。
SELECT 语句用于从表中检索数据。WHERE 子句类似于一个条件。它使用条件过滤数据,并为你提供有限的结果。内置运算符和函数生成一个表达式,该表达式满足条件。
Syntax
下面给出了 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];
Example
我们以一个 SELECT…WHERE 子句的示例为例。假设我们有如下的雇员表,其中字段名为 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 Program
以下 JDBC 程序将 where 子句应用于给定示例。
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://localhost: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
Hiveql Select…Order By
本章解释了如何在 SELECT 语句中使用 ORDER BY 从句。ORDER BY 从句用于基于一列检索详细信息,并按升序或降序对结果集进行排序。
Syntax
下面是 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];
Example
我们来看一个 SELECT…ORDER BY 从句的示例。假设员工表如下所示,其中有 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 Program
以下是用于为给定示例应用 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://localhost: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
Hiveql Group By
本章解释了 SELECT 语句中 GROUP BY 从句的详细信息。GROUP BY 从句用于使用特定收集列对结果集汇总所有记录。它用于查询一组记录。
Syntax
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];
Example
我们来看一个 SELECT…GROUP BY 从句的示例。假设员工表如下所示,其中有 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 Program
下面是将 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://localhost: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
Hiveql Joins
JOINS 是一个子句,用于通过使用每张表中重复的值组合来自两张表的特定字段。它用于组合来自数据库中两张或更多表的记录。
Syntax
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]
Example
我们在本章中将使用以下两张表。考虑名为 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 条件应使用表的键和外键创建。
以下查询对 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 返回右表中的全部值以及左表中的匹配值,如果匹配 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 - Built-in Functions
本章解释了 Hive 中可用的内建函数。这些函数除了用法外,都与 SQL 函数十分相似。
Built-In Functions
Hive 支持以下内建函数:
Return Type |
Signature |
Description |
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) |
Same as above. |
string |
lower(string A) |
它返回将 B 中所有字符转换为小写后的结果串。 |
string |
lcase(string A) |
Same as above. |
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) |
它返回将 B 中所有与 Java 正则表达式语法匹配的子串替换为 C 后的结果串。 |
int |
size(Map<K.V>) |
它返回 map 类型的元素数量。 |
int |
size(Array<T>) |
它返回 array 类型的元素数量。 |
value of <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。 |
Aggregate Functions
Hive 支持以下内置 aggregate functions 。这些函数的使用与 SQL 聚合函数相同。
Return Type |
Signature |
Description |
BIGINT |
count(*), count(expr), |
count(*) - 返回检索到的总行数。 |
DOUBLE |
sum(col), sum(DISTINCT col) |
返回组中元素的总和或组中列的唯一值总和。 |
DOUBLE |
avg(col), avg(DISTINCT col) |
返回组中元素的平均值或组中列的唯一值平均值。 |
DOUBLE |
min(col) |
返回组中列的最小值。 |
DOUBLE |
max(col) |
返回组中列的最大值。 |
Hive - View and Indexes
本章介绍如何创建和管理视图。视图是根据用户需求生成的。你可以将任何结果集数据另存为视图。视图在 Hive 中的使用与视图在 SQL 中的使用相同。它是一种标准的 RDBMS 概念。我们可以在视图上执行所有 DML 操作。
Creating a View
执行 SELECT 语句时,可以创建一个视图。语法如下:
CREATE VIEW [IF NOT EXISTS] view_name [(column_name [COMMENT column_comment], ...) ]
[COMMENT table_comment]
AS SELECT ...
Example
我们以视图为例。假设员工表如下所示,其中有 Id、Name、Salary、Designation 和 Dept 字段。生成一个查询,以检索获得超过 INR 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;
Creating an Index
索引只是指向表中的特定列的一个指针。创建索引意味着在表中的特定列上创建指针。其语法如下:
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 (...)]