Hive 是建立在 Hadoop 之上的数据仓库基础架构,它提供了类似于 SQL 的查询语言 Hive SQL(也称为 HQL),用于对存储在 Hadoop 分布式文件系统(HDFS)中的大规模数据进行数据查询和分析。Hive 将 SQL 查询转换为 MapReduce、Tez 或 Spark 等分布式计算任务,使得不熟悉 Java 编程的数据分析人员也能方便地处理大规模数据。
在使用 Hive SQL 之前,需要确保 Hadoop 集群和 Hive 已经正确安装和配置。启动 Hadoop 服务(如 HDFS、YARN)后,启动 Hive 服务。通常可以通过以下命令启动 Hive 客户端:
bash
hive
sql
CREATE DATABASE IF NOT EXISTS my_database;
IF NOT EXISTS
是可选的,用于避免在数据库已经存在时抛出错误。
sql
USE my_database;
sql
SHOW DATABASES;
sql
DROP DATABASE IF EXISTS my_database;
如果数据库中有表,需要使用 CASCADE
关键字强制删除:
sql
DROP DATABASE IF EXISTS my_database CASCADE;
sql
CREATE TABLE IF NOT EXISTS employees (
id INT,
name STRING,
age INT,
salary DOUBLE
) ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS TEXTFILE;
这里创建了一个名为 employees
的内部表,字段之间用逗号分隔,数据以文本文件形式存储。
sql
CREATE EXTERNAL TABLE IF NOT EXISTS external_employees (
id INT,
name STRING,
age INT,
salary DOUBLE
) ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
LOCATION '/user/hive/external_data';
外部表使用 EXTERNAL
关键字,数据存储在指定的 LOCATION
目录下,删除外部表时不会删除数据文件。
sql
SHOW TABLES;
sql
DESCRIBE employees;
sql
DROP TABLE IF EXISTS employees;
sql
LOAD DATA LOCAL INPATH '/path/to/local/data.csv' INTO TABLE employees;
sql
LOAD DATA INPATH '/user/hdfs/data.csv' INTO TABLE employees;
sql
INSERT INTO TABLE employees VALUES (1, 'John', 30, 5000.0);
sql
SELECT * FROM employees;
可以使用 WHERE
子句进行条件查询:
sql
SELECT * FROM employees WHERE age > 25;
Hive 不支持直接的 UPDATE
和 DELETE
操作,通常可以通过创建新表并插入符合条件的数据来实现类似功能。例如,删除 age
小于 20 的记录:
sql
CREATE TABLE new_employees AS
SELECT * FROM employees WHERE age >= 20;
sql
SELECT e.id, e.name, d.dept_name
FROM employees e
JOIN departments d
ON e.dept_id = d.dept_id;
sql
SELECT e.id, e.name, d.dept_name
FROM employees e
LEFT JOIN departments d
ON e.dept_id = d.dept_id;
sql
SELECT dept_id, AVG(salary)
FROM employees
GROUP BY dept_id;
可以使用 HAVING
子句对分组结果进行过滤:
sql
SELECT dept_id, AVG(salary)
FROM employees
GROUP BY dept_id
HAVING AVG(salary) > 5000;
sql
SELECT *
FROM employees
WHERE dept_id IN (SELECT dept_id FROM departments WHERE dept_name = 'Sales');
UPPER
、LOWER
、SUBSTRING
等。sql
SELECT UPPER(name) FROM employees;
SUM
、AVG
、COUNT
等。sql
SELECT SUM(salary) FROM employees;
YEAR
、MONTH
、DAY
等。sql
SELECT YEAR(hire_date) FROM employees;
可以编写自定义函数来满足特定的业务需求。以下是一个简单的 Java 自定义函数示例:
java
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
public class MyUDF extends UDF {
public Text evaluate(Text input) {
if (input == null) return null;
return new Text(input.toString().toUpperCase());
}
}
将上述代码编译打包成 JAR 文件,然后在 Hive 中注册并使用:
sql
ADD JAR /path/to/myudf.jar;
CREATE TEMPORARY FUNCTION my_udf AS 'com.example.MyUDF';
SELECT my_udf(name) FROM employees;
分区表可以根据指定的列(如日期、地区等)对数据进行分区,提高查询效率。
sql
CREATE TABLE partitioned_employees (
id INT,
name STRING,
age INT,
salary DOUBLE
) PARTITIONED BY (dept_id INT)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ',';
加载数据到指定分区:
sql
LOAD DATA INPATH '/user/hdfs/dept1_data.csv' INTO TABLE partitioned_employees PARTITION (dept_id = 1);
分桶表将数据按照指定列的哈希值进行分桶存储,常用于提高数据抽样和连接操作的效率。
sql
CREATE TABLE bucketed_employees (
id INT,
name STRING,
age INT,
salary DOUBLE
) CLUSTERED BY (id) INTO 4 BUCKETS
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ',';
窗口函数用于在查询结果的特定窗口内进行计算,常见的窗口函数有 ROW_NUMBER()
、RANK()
、DENSE_RANK()
等。
sql
SELECT id, name, salary,
ROW_NUMBER() OVER (ORDER BY salary DESC) as rank
FROM employees;
DISTRIBUTE BY
和 SORT BY
:在数据插入或查询时,合理使用 DISTRIBUTE BY
和 SORT BY
可以避免数据倾斜。sql
INSERT OVERWRITE TABLE bucketed_employees
DISTRIBUTE BY id
SORT BY id;
根据数据的特点和查询需求,合理设计分区表和分桶表,减少不必要的数据扫描。
SELECT *
,只选择需要的列。JOIN
顺序,将小表放在前面。EXISTS
代替 IN
子查询。根据集群资源和数据量,调整 Hive 的相关参数,如 hive.auto.convert.join
、mapred.reduce.tasks
等。