HiveQL 与 SQL 深度对比

HiveQL 是 Hive 的查询语言,脱胎于 SQL-92 标准,语法上与 MySQL、PostgreSQL 等关系型数据库的 SQL 高度相似。对于熟悉 SQL 的工程师,上手 HiveQL 的成本很低——大部分 SELECT 语句几乎可以直接复用。但 HiveQL 并非标准 SQL 的完整实现,它在某些方面有所限制,同时又针对大数据场景做了大量扩展。本文系统梳理两者的相同点与差异,帮助你在迁移或学习时少踩坑。

相同点

HiveQL 与标准 SQL 在核心查询语法上高度一致,以下这些特性在两者中的行为基本相同。

基础查询语法

SELECT、FROM、WHERE、GROUP BY、HAVING、ORDER BY、LIMIT 的语法和语义与标准 SQL 完全一致:

-- 以下语句在 HiveQL 和标准 SQL 中行为完全相同
SELECT
    user_id,
    COUNT(*)        AS order_cnt,
    SUM(amount)     AS total_amount,
    AVG(amount)     AS avg_amount
FROM orders
WHERE status = 'paid'
  AND create_time >= '2026-01-01'
GROUP BY user_id
HAVING COUNT(*) > 5
ORDER BY total_amount DESC
LIMIT 100;

JOIN 语法

HiveQL 支持与标准 SQL 相同的 JOIN 类型:INNER JOIN、LEFT OUTER JOIN、RIGHT OUTER JOIN、FULL OUTER JOIN、CROSS JOIN。ON 条件的写法也完全一致:

-- INNER JOIN
SELECT a.user_id, a.username, b.order_id, b.amount
FROM user_profile a
INNER JOIN orders b ON a.user_id = b.user_id;

-- LEFT JOIN(保留左表所有行)
SELECT a.user_id, a.username, b.order_id
FROM user_profile a
LEFT JOIN orders b ON a.user_id = b.user_id;

-- FULL OUTER JOIN
SELECT COALESCE(a.user_id, b.user_id) AS user_id
FROM table_a a
FULL OUTER JOIN table_b b ON a.user_id = b.user_id;

子查询

HiveQL 支持 FROM 子句中的子查询(派生表)和 WHERE 子句中的 IN/EXISTS 子查询(Hive 0.13+):

-- FROM 子查询(派生表)
SELECT t.user_id, t.cnt
FROM (
    SELECT user_id, COUNT(*) AS cnt
    FROM orders
    GROUP BY user_id
) t
WHERE t.cnt > 10;

-- IN 子查询(Hive 0.13+)
SELECT user_id, username
FROM user_profile
WHERE user_id IN (
    SELECT DISTINCT user_id FROM orders WHERE amount > 1000
);

-- EXISTS 子查询(Hive 0.13+)
SELECT a.user_id
FROM user_profile a
WHERE EXISTS (
    SELECT 1 FROM orders b WHERE b.user_id = a.user_id AND b.amount > 1000
);

窗口函数

HiveQL 对窗口函数的支持相当完整,OVER()、PARTITION BY、ORDER BY、ROWS/RANGE BETWEEN 的语法与标准 SQL 一致,常用的窗口函数(ROW_NUMBER、RANK、DENSE_RANK、LAG、LEAD、SUM/AVG/COUNT OVER)全部支持:

-- 以下窗口函数语法在 HiveQL 和标准 SQL 中行为一致
SELECT
    user_id,
    order_date,
    amount,
    ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY order_date)  AS rn,
    RANK()        OVER (PARTITION BY user_id ORDER BY amount DESC) AS rnk,
    LAG(amount, 1, 0) OVER (PARTITION BY user_id ORDER BY order_date) AS prev_amount,
    SUM(amount)   OVER (PARTITION BY user_id ORDER BY order_date
                        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cum_amount
FROM orders;

聚合函数

COUNT、SUM、AVG、MIN、MAX、COUNT(DISTINCT ...)、GROUP_CONCAT(Hive 中为 COLLECT_LIST/COLLECT_SET)等聚合函数的行为与标准 SQL 一致。CASE WHEN ... THEN ... ELSE ... END 表达式语法也完全相同:

-- CASE WHEN 语法完全一致
SELECT
    user_id,
    SUM(CASE WHEN action_type = 'buy'  THEN 1 ELSE 0 END) AS buy_cnt,
    SUM(CASE WHEN action_type = 'view' THEN 1 ELSE 0 END) AS view_cnt
FROM user_actions
GROUP BY user_id;

CTE(WITH 子句)

Hive 0.13+ 支持 WITH ... AS ... 的 CTE(公共表表达式)语法,写法与标准 SQL 相同:

WITH active_users AS (
    SELECT DISTINCT user_id
    FROM user_actions
    WHERE dt = '2026-04-17' AND action_type = 'login'
),
high_value_orders AS (
    SELECT user_id, SUM(amount) AS total
    FROM orders
    WHERE dt = '2026-04-17'
    GROUP BY user_id
    HAVING SUM(amount) > 1000
)
SELECT a.user_id, h.total
FROM active_users a
JOIN high_value_orders h ON a.user_id = h.user_id;

常用内置函数

字符串函数(CONCAT、SUBSTR/SUBSTRING、TRIM、UPPER、LOWER、LENGTH、REPLACE、REGEXP_REPLACE)、数值函数(ROUND、FLOOR、CEIL、ABS、MOD)、日期函数(DATE_FORMAT、DATEDIFF、DATE_ADD)、NULL 处理函数(COALESCE、NULLIF、NVL)的语法和语义与主流 SQL 数据库基本一致。

核心差异

HiveQL 与标准 SQL 的差异主要体现在以下几个方面,这些是从 SQL 迁移到 Hive 时最容易踩坑的地方。

事务与 DML 限制

这是 HiveQL 与标准 SQL 最根本的差异。标准 SQL 数据库(MySQL、PostgreSQL)支持完整的 ACID 事务,可以随时 INSERT 单行、UPDATE 任意行、DELETE 任意行。HiveQL 在 Hive 3.0 之前不支持行级 UPDATE 和 DELETE,即使 Hive 3.x 引入了 ACID 事务,也有严格限制:

  • 必须使用 ORC 格式存储
  • 必须开启事务相关配置(hive.support.concurrency=true
  • 表必须声明为 TBLPROPERTIES('transactional'='true')
  • UPDATE/DELETE 性能远不如关系型数据库,不适合高频小批量修改
-- 标准 SQL(MySQL/PostgreSQL):完全支持,高效
UPDATE orders SET status = 'cancelled' WHERE order_id = '12345';
DELETE FROM orders WHERE create_time < '2020-01-01';

-- HiveQL(Hive 3.x ACID 表):支持但有条件,性能差
-- 需要先建 ACID 表
CREATE TABLE orders_acid (
    order_id  STRING,
    user_id   BIGINT,
    status    STRING,
    amount    DECIMAL(10,2)
)
STORED AS ORC
TBLPROPERTIES ('transactional'='true');

-- 然后才能执行
UPDATE orders_acid SET status = 'cancelled' WHERE order_id = '12345';

-- HiveQL 常见替代方案:用 INSERT OVERWRITE 全量覆盖
INSERT OVERWRITE TABLE orders PARTITION (dt='2026-04-17')
SELECT
    order_id,
    user_id,
    CASE WHEN order_id = '12345' THEN 'cancelled' ELSE status END AS status,
    amount
FROM orders
WHERE dt = '2026-04-17';

INSERT 语义差异

标准 SQL 的 INSERT 是追加单行或少量行;HiveQL 的 INSERT 通常是批量写入,且有 INSERT INTO(追加)和 INSERT OVERWRITE(覆盖)两种模式。HiveQL 没有标准 SQL 的 INSERT INTO ... VALUES (...) 单行插入模式(Hive 0.14+ 虽然支持,但极少使用,性能极差,每次都启动一个 MapReduce 作业)。

-- 标准 SQL:单行插入,高效
INSERT INTO orders (order_id, user_id, amount) VALUES ('abc', 1001, 99.9);

-- HiveQL 推荐写法:从另一张表批量写入
INSERT INTO TABLE orders PARTITION (dt='2026-04-17')
SELECT order_id, user_id, amount
FROM orders_staging
WHERE dt = '2026-04-17';

-- INSERT OVERWRITE:覆盖目标表/分区(HiveQL 特有,标准 SQL 没有)
INSERT OVERWRITE TABLE orders PARTITION (dt='2026-04-17')
SELECT order_id, user_id, amount
FROM orders_new
WHERE dt = '2026-04-17';

-- 多目标插入(HiveQL 特有,一次扫描写多张表)
FROM orders_raw
INSERT OVERWRITE TABLE orders_detail PARTITION (dt='2026-04-17')
    SELECT order_id, user_id, amount WHERE dt = '2026-04-17'
INSERT OVERWRITE TABLE orders_summary PARTITION (dt='2026-04-17')
    SELECT user_id, SUM(amount) WHERE dt = '2026-04-17' GROUP BY user_id;

DDL 扩展:分区与分桶

HiveQL 在 CREATE TABLE 语句上做了大量扩展,这些是标准 SQL 没有的:

-- 标准 SQL 的建表(PostgreSQL)
CREATE TABLE orders (
    order_id  VARCHAR(64) PRIMARY KEY,
    user_id   BIGINT NOT NULL,
    amount    DECIMAL(10,2),
    status    VARCHAR(20),
    dt        DATE
);

-- HiveQL 的建表:更多子句,无 PRIMARY KEY 约束
CREATE EXTERNAL TABLE orders (
    order_id  STRING,           -- 无 VARCHAR 长度限制
    user_id   BIGINT,
    amount    DECIMAL(10,2),
    status    STRING
    -- 注意:分区列 dt 不在这里定义!
)
COMMENT '订单表'
PARTITIONED BY (dt STRING)          -- HiveQL 特有:分区声明
CLUSTERED BY (user_id) INTO 32 BUCKETS  -- HiveQL 特有:分桶声明
ROW FORMAT DELIMITED                -- HiveQL 特有:行格式
    FIELDS TERMINATED BY '\t'
    LINES TERMINATED BY '\n'
STORED AS ORC                       -- HiveQL 特有:存储格式
LOCATION '/warehouse/orders/'       -- HiveQL 特有:HDFS 路径
TBLPROPERTIES ('orc.compress'='SNAPPY');  -- HiveQL 特有:表属性

关键差异点:

  • 无主键约束:HiveQL 不支持 PRIMARY KEY、FOREIGN KEY、UNIQUE 约束(即使语法上可以声明,也不会强制执行)
  • 无 NOT NULL 强制:HiveQL 的 NOT NULL 是提示性的,不会在写入时校验
  • 分区列不在列定义中:分区列通过 PARTITIONED BY 单独声明,查询时分区列像普通列一样使用
  • EXTERNAL 关键字:外部表 DROP 时不删除数据,内部表 DROP 时同时删除 HDFS 数据

数据类型差异

HiveQL 的数据类型与标准 SQL 有所不同,主要体现在:

HiveQL 特有类型

  • STRING:变长字符串,无需指定长度,等价于 TEXT,是 Hive 中最常用的字符串类型
  • ARRAY<T>:数组类型,如 ARRAY<STRING>,可存储同类型元素的有序集合
  • MAP<K,V>:映射类型,如 MAP<STRING, INT>,键值对集合
  • STRUCT<field:type,...>:结构体类型,类似 JSON 对象,可嵌套
  • UNIONTYPE:联合类型(较少使用)
-- HiveQL 复杂类型示例
CREATE TABLE user_profile (
    user_id     BIGINT,
    username    STRING,
    tags        ARRAY<STRING>,               -- 用户标签列表
    extra_info  MAP<STRING, STRING>,         -- 扩展属性键值对
    address     STRUCT<
                    province: STRING,
                    city:     STRING,
                    district: STRING
                >
);

-- 访问复杂类型
SELECT
    user_id,
    tags[0]                    AS first_tag,      -- 数组下标访问(从 0 开始)
    extra_info['phone']        AS phone,           -- Map 键访问
    address.city               AS city,            -- Struct 字段访问
    SIZE(tags)                 AS tag_count,       -- 数组长度
    ARRAY_CONTAINS(tags, 'vip') AS is_vip          -- 数组包含判断
FROM user_profile;

-- 展开数组:LATERAL VIEW EXPLODE(标准 SQL 没有,类似 unnest)
SELECT user_id, tag
FROM user_profile
LATERAL VIEW EXPLODE(tags) tmp AS tag;

类型映射对比

  • 标准 SQL 的 VARCHAR(n) → HiveQL 中用 STRING(无需长度)或 VARCHAR(n)(Hive 0.12+)
  • 标准 SQL 的 TEXT → HiveQL 的 STRING
  • 标准 SQL 的 BOOLEAN → HiveQL 同样支持 BOOLEAN
  • 标准 SQL 的 DATETIME → HiveQL 的 TIMESTAMP
  • 标准 SQL 的 JSON 类型 → HiveQL 没有原生 JSON 类型,通常用 STRING 存储,配合 get_json_object 函数解析

JOIN 限制与扩展

HiveQL 的 JOIN 在早期版本有一些限制,理解这些差异有助于避免踩坑:

-- 标准 SQL 支持:JOIN ON 条件中使用不等式
SELECT a.user_id, b.order_id
FROM users a
JOIN orders b ON a.user_id = b.user_id AND b.amount > a.credit_limit;
-- HiveQL 早期版本不支持 ON 条件中的不等式,需要改写为 WHERE

-- 标准 SQL 支持:隐式 JOIN(逗号语法)
SELECT a.user_id FROM users a, orders b WHERE a.user_id = b.user_id;
-- HiveQL 0.13 之前不支持隐式 JOIN,必须写显式 JOIN

-- HiveQL 特有:MAPJOIN hint(标准 SQL 没有)
SELECT /*+ MAPJOIN(dim) */ a.user_id, dim.city_name
FROM orders a
JOIN dim_city dim ON a.city_id = dim.city_id;

-- HiveQL 特有:SEMI JOIN(标准 SQL 用 EXISTS 实现)
-- 等价于:SELECT * FROM a WHERE EXISTS (SELECT 1 FROM b WHERE b.id = a.id)
SELECT a.user_id FROM user_profile a
LEFT SEMI JOIN orders b ON a.user_id = b.user_id;

子查询限制

早期 HiveQL(0.12 及以前)对子查询的支持非常有限,很多在标准 SQL 中常见的子查询写法无法直接使用:

-- 标准 SQL 支持:WHERE 子句中的标量子查询
SELECT user_id FROM orders
WHERE amount > (SELECT AVG(amount) FROM orders);
-- HiveQL 0.12 不支持此写法,需改为 JOIN

-- 改写为 HiveQL 兼容写法
SELECT a.user_id
FROM orders a
JOIN (SELECT AVG(amount) AS avg_amount FROM orders) b
ON a.amount > b.avg_amount;

-- 标准 SQL 支持:NOT IN 子查询
SELECT user_id FROM users
WHERE user_id NOT IN (SELECT user_id FROM blacklist);
-- HiveQL 0.13+ 支持,但早期版本需改为 LEFT JOIN + IS NULL

-- 改写为 LEFT JOIN 反连接(通用写法,HiveQL 各版本兼容)
SELECT a.user_id
FROM users a
LEFT JOIN blacklist b ON a.user_id = b.user_id
WHERE b.user_id IS NULL;

ORDER BY 与 SORT BY

HiveQL 有四种排序关键字,这是标准 SQL 没有的概念:

-- ORDER BY:全局排序,只有一个 Reducer,数据量大时极慢
-- 等价于标准 SQL 的 ORDER BY
SELECT user_id, amount FROM orders ORDER BY amount DESC;

-- SORT BY(HiveQL 特有):每个 Reducer 内部排序,结果不是全局有序的
-- 多个 Reducer 时,每个 Reducer 的输出是有序的,但整体无序
SELECT user_id, amount FROM orders SORT BY amount DESC;

-- DISTRIBUTE BY(HiveQL 特有):控制数据如何分发到 Reducer(类似 GROUP BY 的 Shuffle)
-- 相同 user_id 的数据会发到同一个 Reducer
SELECT user_id, amount FROM orders DISTRIBUTE BY user_id;

-- CLUSTER BY(HiveQL 特有):DISTRIBUTE BY + SORT BY 的简写
-- 等价于:DISTRIBUTE BY user_id SORT BY user_id
SELECT user_id, amount FROM orders CLUSTER BY user_id;

-- 实际场景:每个用户的订单在同一 Reducer 内按时间排序
SELECT user_id, order_time, amount
FROM orders
DISTRIBUTE BY user_id
SORT BY user_id, order_time;

LIMIT 与采样

-- 标准 SQL:LIMIT + OFFSET 分页
SELECT * FROM orders LIMIT 10 OFFSET 20;

-- HiveQL:支持 LIMIT,但 OFFSET 需要 Hive 2.0+
-- 早期版本分页通常用 ROW_NUMBER() 实现
SELECT * FROM (
    SELECT *, ROW_NUMBER() OVER (ORDER BY create_time) AS rn FROM orders
) t WHERE rn BETWEEN 21 AND 30;

-- HiveQL 特有:TABLESAMPLE 表采样(标准 SQL 没有)
-- 按桶采样(分桶表)
SELECT * FROM orders_bucketed TABLESAMPLE (BUCKET 1 OUT OF 10 ON user_id);

-- 按百分比采样
SELECT * FROM orders TABLESAMPLE (10 PERCENT);

-- 按数据量采样
SELECT * FROM orders TABLESAMPLE (1000 ROWS);

函数体系差异

HiveQL 特有函数

HiveQL 提供了大量针对大数据场景的内置函数,这些在标准 SQL 中没有对应:

集合操作函数

-- COLLECT_LIST:将分组内的值收集为数组(保留重复值)
-- 类似 MySQL 的 GROUP_CONCAT
SELECT user_id, COLLECT_LIST(product_id) AS product_list
FROM orders GROUP BY user_id;

-- COLLECT_SET:收集为集合(去重)
SELECT user_id, COLLECT_SET(category) AS categories
FROM orders GROUP BY user_id;

-- EXPLODE:将数组/Map 展开为多行(配合 LATERAL VIEW 使用)
SELECT user_id, tag
FROM user_profile
LATERAL VIEW EXPLODE(tags) t AS tag;

-- POSEXPLODE:展开数组,同时返回下标
SELECT user_id, pos, tag
FROM user_profile
LATERAL VIEW POSEXPLODE(tags) t AS pos, tag;

JSON 解析函数(标准 SQL 数据库通常有原生 JSON 类型,Hive 用函数处理):

-- get_json_object:从 JSON 字符串中提取字段(JSONPath 语法)
SELECT
    get_json_object(extra_info, '$.phone')    AS phone,
    get_json_object(extra_info, '$.address')  AS address
FROM user_profile;

-- json_tuple:一次提取多个字段,效率更高
SELECT user_id, phone, address
FROM user_profile
LATERAL VIEW json_tuple(extra_info, 'phone', 'address') t AS phone, address;

字符串处理扩展

-- SPLIT:按分隔符拆分字符串为数组
SELECT SPLIT('a,b,c', ',');  -- 返回 ["a","b","c"]

-- REGEXP_EXTRACT:正则提取
SELECT REGEXP_EXTRACT('order_20260417_001', 'order_(\\d+)_(\\d+)', 1);  -- 返回 20260417

-- PARSE_URL:解析 URL 各组成部分
SELECT PARSE_URL('https://www.example.com/path?k=v', 'HOST');  -- 返回 www.example.com

-- STR_TO_MAP:将 key1:val1,key2:val2 格式字符串转为 Map
SELECT STR_TO_MAP('a:1,b:2', ',', ':');  -- 返回 {"a":"1","b":"2"}

日期函数差异

-- 标准 SQL(PostgreSQL)
SELECT EXTRACT(YEAR FROM NOW());
SELECT DATE_TRUNC('month', NOW());
SELECT NOW() - INTERVAL '7 days';

-- HiveQL 等价写法
SELECT YEAR(CURRENT_TIMESTAMP);
SELECT TRUNC(CURRENT_DATE, 'MM');           -- 截断到月初
SELECT DATE_SUB(CURRENT_DATE, 7);          -- 当前日期减 7 天
SELECT DATEDIFF('2026-04-17', '2026-04-01'); -- 日期差(天数)
SELECT FROM_UNIXTIME(unix_timestamp);       -- Unix 时间戳转日期字符串
SELECT UNIX_TIMESTAMP('2026-04-17', 'yyyy-MM-dd');  -- 日期字符串转时间戳

UDF 扩展机制

HiveQL 和标准 SQL 都支持用户自定义函数(UDF),但 Hive 的 UDF 体系更丰富,专门针对大数据场景设计了三种类型:

  • UDF(User Defined Function):一进一出,如 my_upper(STRING) → STRING,等价于标准 SQL 的 UDF
  • UDAF(User Defined Aggregate Function):多进一出,如自定义聚合函数,等价于标准 SQL 的聚合 UDF
  • UDTF(User Defined Table-generating Function):一进多出(生成多行),如 EXPLODE,标准 SQL 没有直接对应
-- 注册并使用 UDF(Java 实现)
ADD JAR /path/to/my-udf.jar;
CREATE TEMPORARY FUNCTION my_func AS 'com.example.MyUDF';
SELECT my_func(column_name) FROM my_table;

-- 永久注册(Hive 1.1+)
CREATE FUNCTION db_name.my_func AS 'com.example.MyUDF'
USING JAR 'hdfs:///jars/my-udf.jar';

SQL 兼容性版本演进

HiveQL 对标准 SQL 的兼容性随版本持续提升,了解版本差异有助于判断哪些特性可以使用:

  • Hive 0.11:引入窗口函数和分析函数,补齐了与标准 SQL 的重要差距
  • Hive 0.12:支持 VARCHAR、CHAR 类型,提升类型兼容性
  • Hive 0.13:支持 WHERE 子句子查询(IN/EXISTS/NOT IN/NOT EXISTS),支持隐式 JOIN,引入 CBO 优化器
  • Hive 0.14:引入 ACID 事务(INSERT/UPDATE/DELETE),但仅支持 ORC 格式的 Bucket 表
  • Hive 2.0:LLAP(Live Long and Process)模式,支持低延迟交互式查询;LIMIT OFFSET 分页
  • Hive 3.0:完善 ACID 事务支持,支持物化视图(Materialized View),改进 SQL 标准兼容性

迁移建议

将标准 SQL 迁移到 HiveQL,或反向迁移时,需要注意以下几点:

从标准 SQL 迁移到 HiveQL

  1. 去掉 UPDATE/DELETE,改用 INSERT OVERWRITE:这是最大的思维转变,Hive 是写一次读多次(WORM)模型,数据修改通过全量覆盖实现
  2. 去掉主键和唯一约束:Hive 不强制约束,数据质量需要在 ETL 流程中保证
  3. VARCHAR 改为 STRING:Hive 中 STRING 更通用,无需指定长度
  4. NOT IN 子查询改为 LEFT JOIN + IS NULL:更兼容,且性能通常更好
  5. 添加分区列:将时间字段(如 dt)改为分区列,是 Hive 性能优化的基础
  6. ORDER BY 谨慎使用:全局 ORDER BY 在 Hive 中只有一个 Reducer,数据量大时非常慢;如果只需要 TopN,用 ORDER BY ... LIMIT N 即可

从 HiveQL 迁移到标准 SQL

  1. ARRAY/MAP/STRUCT 类型:标准 SQL 没有这些类型,需要拆表或用 JSON 类型替代
  2. LATERAL VIEW EXPLODE:改用标准 SQL 的 UNNEST(PostgreSQL)或 JSON_TABLE(MySQL 8.0)
  3. INSERT OVERWRITE:改为 TRUNCATE + INSERTMERGE INTO
  4. DISTRIBUTE BY / SORT BY:标准 SQL 没有对应语法,通常不需要(关系型数据库有自己的查询优化器)
  5. 分区表:标准 SQL 用 PARTITION BY RANGE 实现,但语法和用途有差异

总结

HiveQL 与标准 SQL 的关系可以用一句话概括:查询语法高度兼容,数据操作(DML)差异显著,DDL 大量扩展

相同点(可以直接复用):

  • SELECT / FROM / WHERE / GROUP BY / HAVING / ORDER BY / LIMIT
  • JOIN(INNER/LEFT/RIGHT/FULL OUTER/CROSS)语法
  • 窗口函数(ROW_NUMBER、RANK、LAG、LEAD、SUM OVER 等)
  • 子查询(FROM 子查询、IN/EXISTS 子查询,Hive 0.13+)
  • CTE(WITH ... AS ...,Hive 0.13+)
  • CASE WHEN 表达式
  • 常用聚合函数和字符串/数值/日期函数

核心差异(需要重点注意):

  • 无行级 UPDATE/DELETE(Hive 3.x ACID 支持但有限制),用 INSERT OVERWRITE 替代
  • INSERT 语义不同:批量写入为主,分 INSERT INTO(追加)和 INSERT OVERWRITE(覆盖)
  • DDL 扩展:分区(PARTITIONED BY)、分桶(CLUSTERED BY)、存储格式(STORED AS)、外部表(EXTERNAL)
  • 无强制约束(PRIMARY KEY、NOT NULL、UNIQUE 不强制执行)
  • 特有数据类型:ARRAY、MAP、STRUCT
  • 特有排序关键字:SORT BY、DISTRIBUTE BY、CLUSTER BY
  • 特有函数:EXPLODE、COLLECT_LIST、get_json_object、TABLESAMPLE 等

对于熟悉 SQL 的工程师,HiveQL 的学习曲线并不陡峭——核心查询语法几乎可以直接迁移。真正需要适应的,是 Hive 的"批处理思维":数据是不可变的,修改通过覆盖实现;性能优化依赖分区设计,而不是索引;大表 JOIN 需要考虑 Shuffle 代价,而不是依赖查询优化器自动处理。