深入浅出 Hive 数据类型:从入门到实战

分类: 英国365bet体育在线 📅 2026-07-20 23:15:57 👤 admin 👁️ 4125 ❤️ 351
深入浅出 Hive 数据类型:从入门到实战

深入浅出 Hive 数据类型:从入门到实战

在大数据领域,Hive 作为数据仓库的核心工具,其数据类型体系是构建高效数仓的基石。本文将带你全面掌握 Hive 的所有数据类型,并通过大量案例和代码让你真正会用、用对。

一、为什么数据类型如此重要?

在 Hive 中,正确选择和使用数据类型能带来三大好处:

提升查询性能:合适的类型减少数据扫描和转换开销

节省存储空间 :小粒度类型(如 TINYINT)比 STRING 省空间

避免隐式转换错误:类型不匹配导致的结果异常或任务失败

二、Hive 数据类型全景图

Hive数据类型

基本类型

复杂类型

数值型

字符型

日期时间型

布尔/二进制

ARRAY

MAP

STRUCT

UNIONTYPE

三、基本数据类型详解

1. 数值类型

类型

长度

范围

场景

TINYINT

1 字节

-128 ~ 127

年龄、枚举码

SMALLINT

2 字节

-32768 ~ 32767

小型数量

INT

4 字节

-2^31 ~ 2^31-1

最常见整数

BIGINT

8 字节

-2^63 ~ 2^63-1

大数据量ID、时间戳

FLOAT

4 字节

单精度

科学计算(慎用)

DOUBLE

8 字节

双精度

金额、比率

DECIMAL(precision, scale)

可变

高精度小数

金融、订单金额

💡 最佳实践 :金额永远用 DECIMAL(10,2) 而不是 DOUBLE,否则会出现精度丢失。

sql

复制代码

-- 示例:创建订单表

CREATE TABLE orders (

order_id BIGINT,

user_id INT,

amount DECIMAL(10,2), -- 总金额,保留2位小数

discount FLOAT, -- 折扣率,允许近似

quantity SMALLINT

);

2. 字符类型

类型

说明

最大长度

推荐度

STRING

变长字符串

约 2GB

⭐⭐⭐⭐⭐ 通用

VARCHAR(n)

变长,有上限

1~65535

⭐⭐⭐ 需限制长度时

CHAR(n)

定长,空格填充

1~255

⭐⭐ 极少用

⚠️ 注意 :VARCHAR(10) 如果存入 'hello' 实际占5字符,而 CHAR(10) 会填充5个空格,查询时需 TRIM。

sql

复制代码

-- 创建用户表,展示字符类型差异

CREATE TABLE users (

user_id INT,

name STRING, -- 灵活,推荐

country_code VARCHAR(3), -- 如 'USA', 'CHN'

gender CHAR(1) -- 'M' / 'F'

);

-- 插入数据

INSERT INTO users VALUES

(1, 'Alice', 'USA', 'F'),

(2, 'Bob', 'GBR', 'M');

3. 日期时间类型

Hive 2.1.0+ 支持标准 SQL 的 DATE、TIMESTAMP 和 INTERVAL,但老版本常用 STRING + 函数处理。

类型

格式示例

说明

DATE

2025-03-15

仅日期

TIMESTAMP

2025-03-15 12:30:45.123

精确到纳秒

STRING

'2025-03-15'

需配合 to_date() 等函数

sql

复制代码

-- 建表包含时间字段

CREATE TABLE events (

event_id BIGINT,

event_time TIMESTAMP,

event_date DATE,

dt STRING -- 分区字段常用字符串格式 '2025-03-15'

)

PARTITIONED BY (dt STRING);

-- 插入当前时间

INSERT INTO events VALUES

(1001, CURRENT_TIMESTAMP(), CURRENT_DATE(), '2025-03-15');

🛠 常用时间函数:

sql

复制代码

SELECT

to_date('2025-03-15 10:20:30') as date_val, -- '2025-03-15'

year('2025-03-15') as y, -- 2025

datediff('2025-03-20', '2025-03-15') as diff, -- 5

date_add('2025-03-15', 7) as next_week, -- '2025-03-22'

from_unixtime(1614556800) as ts; -- 时间戳转字符串

4. 布尔与二进制

类型

取值

场景

BOOLEAN

TRUE / FALSE

标志位(是否VIP、是否删除)

BINARY

字节数组

存储图片、序列化对象(实际生产很少直接用)

sql

复制代码

CREATE TABLE user_flags (

user_id INT,

is_vip BOOLEAN,

is_active BOOLEAN

);

-- 查询VIP且活跃用户

SELECT * FROM user_flags WHERE is_vip = TRUE AND is_active = TRUE;

四、复杂数据类型 ------ Hive 的核心优势

1. ARRAY:有序同类型集合

语法 :ARRAY

场景:存储商品标签、历史评分、多值属性。

sql

复制代码

-- 建表:用户浏览历史(每用户一组商品ID)

CREATE TABLE user_views (

user_id INT,

product_ids ARRAY, -- 浏览过的商品ID列表

ratings ARRAY -- 对应评分

);

-- 插入数据(使用 `array()` 或方括号)

INSERT INTO user_views VALUES

(101, array(1001, 1002, 1003), array(4.5, 3.0, 5.0)),

(102, array(2001), array(4.0));

-- 查询:访问数组元素(下标从0开始)

SELECT user_id, product_ids[0] as first_product FROM user_views;

-- 使用 explode 将数组展开成多行

SELECT user_id, product_id

FROM user_views

LATERAL VIEW explode(product_ids) t AS product_id;

-- 结果:101,1001 / 101,1002 / 101,1003 / 102,2001

2. MAP:键值对集合

语法 :MAP

场景:动态属性、扩展字段、KV配置。

sql

复制代码

-- 建表:学生成绩(科目 -> 分数)

CREATE TABLE student_scores (

student_id INT,

scores MAP -- 如 {'math':90, 'english':85}

);

-- 插入数据

INSERT INTO student_scores VALUES

(1, map('math', 90, 'english', 85, 'science', 92)),

(2, map('math', 78, 'english', 88));

-- 查询:获取指定key的值

SELECT student_id, scores['math'] as math_score FROM student_scores;

-- 获取所有key / value

SELECT student_id, map_keys(scores) as subjects, map_values(scores) as scores_list

FROM student_scores;

-- 展开map:LATERAL VIEW explode

SELECT student_id, subject, score

FROM student_scores

LATERAL VIEW explode(scores) t AS subject, score;

3. STRUCT:不同类型命名字段

语法 :STRUCT

场景:处理嵌套JSON、多属性分组(如地址、人名的姓/名)。

sql

复制代码

-- 建表:用户信息包含地址结构体

CREATE TABLE customers (

cust_id INT,

name STRING,

address STRUCT

);

-- 插入数据

INSERT INTO customers VALUES

(1, 'Alice', named_struct('street', '123 Main St', 'city', 'New York', 'zip', 10001)),

(2, 'Bob', named_struct('street', '456 Oak Ave', 'city', 'Los Angeles', 'zip', 90001));

-- 访问结构体字段:用点号

SELECT cust_id, name, address.city, address.zip FROM customers;

-- 结果:1, Alice, New York, 10001

4. UNIONTYPE:多种类型择一

语法 :UNIONTYPE

说明:实际生产极少使用,因为 Hive 对它的查询支持有限。了解即可。

sql

复制代码

-- 示例(不推荐生产)

CREATE TABLE test_union (

id INT,

value UNIONTYPE

);

五、实战案例:电商用户行为分析

场景描述

我们有一张用户行为日志表,包含:

基础字段:用户ID、事件时间

复杂字段:tags (ARRAY) 表示用户行为标签,properties (MAP) 存储额外属性,device (STRUCT) 记录设备信息。

建表语句

sql

复制代码

CREATE TABLE user_behavior_log (

user_id BIGINT,

event_time TIMESTAMP,

event_type STRING, -- 'click', 'purchase', 'add_cart'

tags ARRAY, -- 如 ['high_value', 'new_user']

properties MAP, -- 如 {'product_id':'123','price':'99.9'}

device STRUCT

)

PARTITIONED BY (dt STRING) -- 按日期分区

STORED AS PARQUET; -- 列式存储,推荐

插入测试数据

sql

复制代码

INSERT INTO user_behavior_log PARTITION(dt='2025-03-15') VALUES

(1001, '2025-03-15 10:00:00', 'click',

array('new_user'),

map('product_id','A100','price','29.9'),

named_struct('os','iOS','brand','Apple','screen_width',1170)),

(1001, '2025-03-15 10:05:00', 'purchase',

array('new_user','high_value'),

map('order_id','ORD001','amount','299.00'),

named_struct('os','iOS','brand','Apple','screen_width',1170)),

(1002, '2025-03-15 09:30:00', 'click',

array('vip'),

map('product_id','B200','ref','campaign1'),

named_struct('os','Android','brand','Samsung','screen_width',1080));

常用查询分析

1. 筛选使用 iPhone 的用户行为

sql

复制代码

SELECT user_id, event_type, device.brand

FROM user_behavior_log

WHERE device.brand = 'Apple';

2. 统计每个用户的行为标签分布(explode ARRAY)

sql

复制代码

SELECT user_id, tag, COUNT(*) as cnt

FROM user_behavior_log

LATERAL VIEW explode(tags) t AS tag

GROUP BY user_id, tag;

3. 提取 properties MAP 中的具体字段

sql

复制代码

SELECT

user_id,

event_type,

properties['product_id'] AS product_id,

CAST(properties['price'] AS DOUBLE) AS price

FROM user_behavior_log

WHERE event_type = 'click';

4. 同时展开 ARRAY 和 MAP(复杂场景)

sql

复制代码

-- 假设 properties 中存储多个商品信息,我们想同时展开 tags 和 product_id

SELECT user_id, tag, properties['product_id'] as product

FROM user_behavior_log

LATERAL VIEW explode(tags) t AS tag;

六、数据类型转换

Hive 支持隐式和显式转换。

隐式转换(自动,但不可控)

sql

复制代码

-- INT 转 BIGINT 没问题

SELECT 100 + 5L; -- 结果 BIGINT 105

-- STRING 转 DOUBLE 在算术运算中可能发生,但若字符串非数字会返回 NULL

SELECT '12.5' + 0.5; -- 13.0

显式转换(推荐使用 CAST)

sql

复制代码

SELECT

CAST('2025-03-15' AS DATE) as dt,

CAST('123.45' AS DECIMAL(10,2)) as price,

CAST(user_id AS STRING) as user_id_str,

CASE

WHEN is_vip THEN CAST(1 AS BOOLEAN)

ELSE FALSE

END as vip_flag;

常见陷阱

sql

复制代码

-- 1. 除法自动返回 DOUBLE,可能导致精度问题

SELECT 3 / 2; -- 1.5,若需要整数除法用 floor(3/2)

-- 2. STRING 和 TIMESTAMP 比较需显式转换

SELECT * FROM events WHERE event_time > CAST('2025-03-15 00:00:00' AS TIMESTAMP);

-- 3. 空值处理:任何类型与 NULL 运算得 NULL

SELECT 10 + NULL; -- NULL

七、数据类型选择最佳实践

场景

推荐类型

理由

ID字段(订单号、用户ID)

BIGINT

避免溢出,通用

状态码(0-10)

TINYINT

节省存储

金额

DECIMAL(12,2)

精度无损失

时间分区字段

STRING 格式 'yyyy-MM-dd'

便于管理,兼容老版本

事件时间戳

TIMESTAMP

支持时间运算

多值标签

ARRAY

天然支持 explode

动态属性

MAP

灵活扩展

固定结构对象

STRUCT

类型安全,查询简单

八、总结

基本类型 :掌握 INT, BIGINT, DECIMAL, STRING, TIMESTAMP, BOOLEAN 足够应对 90% 场景。

复杂类型 :ARRAY + MAP + STRUCT 是 Hive 区别于传统 SQL 的强大特性,结合 LATERAL VIEW explode() 可以轻松处理半结构化数据。

类型转换 :优先使用 CAST 显式转换,避免隐式带来的坑。

性能提示 :DECIMAL 优于 FLOAT/DOUBLE 存金额;STRING 做分区字段比 DATE 更灵活;复杂类型不宜嵌套过深(如 ARRAY>>),否则维护和查询都很痛苦。

希望本文帮你建立起 Hive 数据类型的完整知识体系。下次建表时,不妨根据业务语义精挑细选类型,让你的数据仓库既高效又健壮!

💬 互动

你在使用 Hive 数据类型时遇到过什么奇怪的 Bug 吗?欢迎留言交流~

❤️❤️❤️觉得有用的话点个赞 👍🏻 呗。

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

相关文章