HiveQL 语言手册 数据类型篇

概览

本篇将列出 Hive 所支持所有数据类型。有关其他信息,请参阅Tutorial中的Type System

HCatalog 支持的数据类型请参阅:

数值类型 (Numeric Types)

  • TINYINT(1 字节,有符号整型,范围为 -128127
  • SMALLINT(2 字节,有符号整型,范围为 -32,76832,767
  • INT/INTEGER(4字节,有符号整型,范围为-2,147,483,6482,147,483,647
  • BIGINT(4字节,有符号整型,范围为-9,223,372,036,854,775,8089,223,372,036,854,775,807
  • FLOAT(4字节,单精度浮点类型)
  • Double(8字节,双精度浮点类型)
  • Decimal(最大位数38,Hive 0.11.0 版本引入,从 Hive 0.13.0 引入了用户可定义的精度和比例)
  • NUMERIC(理论上与Decimal一致,从 Hive3.0.0 版本开始引入)

时间类型(Date/Time Types)

  • TIMESTEAMP (注意,仅从 Hive 0.8.0 版本开始可用)
  • DATE(注意,仅从 Hive 0.12.0 版本开始可用)
  • INTERVAL(注意,仅从Hive 1.2.0 版本开始可用)

字符类型 (String Types)

  • STRING
  • VARCHAR(注意,仅从Hive 0.12.0 版本开始可用)
  • CHAR(注意,仅从Hive 0.13.0 版本开始可用)

复合类型 (Complex Types)

  • arrays Hive ARRAY<data_type>(从 Hive 0.14 开始,允许负值和非常量表达式)

  • maps Hive MAP<primitive_type, data_type>(从 Hive 0.14 开始,允许负值和非常量表达式)

  • structs Hive STRUCT<col_name Hive data_type [COMMENT col_comment], ...>

  • union Hive UNIONTYPE<data_type, data_type, ...>(注意,仅从Hive 0.7.0 版本开始可用)

其他类型 (Misc Types)

  • BOOLEAN
  • BINARY(注意,仅从 Hive 0.8.0 版本开始可用)

字段类型详述

整数类型

Hive 有四种带符号的整数类型,TINYINTSMALLINTINTBIGINT,他们分别对应 Java 里面的 byteshortintlong,字节长度分别为1字节,2字节,4字节,8字节,在使用整数字面量的时候,默认使用 INT,如果需要使用其他,需要加对应的后缀名,如下表:

类型后缀例子
TINYINTY100Y
SMALLINTS100S
BIGINTL100L

Version

INTEGER 类型在 Hive 2.2.0 (Hive -14950) 中作为 INT 类型的同义词被引入

String

String 的内容需要用单引号或双引号进行包裹。Hive 使用 C-style 转义 String 类型数据。String 存储变长文本,对长度没有限制,理论上可存储大小为2GB,但是存储特别大的对象时,整体写入读写效率均会受到影响。

Varchar

Varchar与String类似,但是有长度限制,长度为1-65355之间。如果转换/赋值给 varchar 值的字符串值超过了预定义的长度,则该字符串将被截断。

局限性

Non-generic UDFs不能直接使用 varchar 类型作为输入参数或返回值。需要先将 varchar 转为 String 类型才可以使用对应的 UDF。如果你仍然想要直接使用 varchar 类型作为传参或返回 varchar 值,需创建GenericUDF

Version

Varchar 类型在Hive 0.12.0 (Hive -4844)中被引入

Char

Char 类型类似于 Varchar 类型,但该类型是固定长度的,最大长度为255。如果值的长度短于预定义的长度,将会使用空格进行填充。

Version

Char 类型在Hive 0.13.0 (Hive -5191)中被引入

Timestamp

支持传统的UNIX时间戳,可选纳秒精度。

可将其他类型转为Timestamp类型:

  • 整数数字类型:解释为 UNIX 时间戳,以秒为单位
  • 浮点数值类型:解释为 UNIX 时间戳,以秒为单位,具有十进制精度
  • 字符串:JDBC 兼容的 java.sql.Timestamp 格式 YYYY-MM-DD HHHiveMMHiveSS.fffffffff (小数点后 9 位精度)

Timestamp 本身不含时区概念,它记录的是与UNIX时间的偏移量/时长。但可以使用 UDFs 在时区间进行转换。如:to_utc_timestamp(将 XXX 时区的时间转为 UTC 时间), from_utc_timestamp(将 UTC 时间转为 XXX 时区时间)。

所有的datatime UDFs(month, day, year, hour等),其参数是用 Timestamp 数据类型。

Timestamp 类型的数据,在 Text 文件中使用yyyy-mm-dd hhHivemmHivess[.f...]格式存储,如果使用其他格式,需要先用 UDF 将其转为 Timestamp 格式。

Timestamps类型的数据,在 Parquet 文件中被存储为 int64 (而不是 int96),需要启用参数hive.parquet.write.int64.timestamp=true 并设置hive.parquet.timestamp.time.unit ("nanos", "micros", "millis"; 默认为: "micros") 默认的存储时间单位。注意,因为只存储64位,所以如果在1677-09-21T00Hive12Hive43.152262-04-11T23Hive47Hive16.8范围之外,存储为nanosint64时间戳将存储为NULL

在表中,可以通过将格式提供给SerDe property“ timestamp.formats”(从带有HIVE-9298的 1.2.0 版开始)来支持其他时间戳格式。例如,yyyy-MM-dd'T'HHHivemmHivess.SSS,yyyy-MM-dd'T'HHHivemmHivess.

Version

Timestamp 类型在Hive 0.8.0 (Hive -2272)中被引入

Date

DATE类型以YYYY-MM-DD的形式描述特定的年/月/日。例如,DATE'2013-01-01'。该类型只有日期部分,没有时间部分。 Date类型支持的日期范围是0000-01-019999-12-31(具体取决于原始 Java Date 类型的支持)。

Version

Date 类型在Hive 0.12.0 (Hive -4055) 中被引入

强制类型转换

Date 类型支持转换为日期、时间戳或字符串类型:

  • cast(date as date) ,无任何变化,相同的日期值
- hive> select cast(date'2022-12-14' as date);
- OK
- 2022-12-14
  • cast(date as string) ,日期表示的年/月/日格式为'YYYY-MM-DD'形式的字符串
- hive> select cast(date'2022-12-14' as date);
- OK
- 2022-12-14
  • cast(date as timestamp),根据本地时区,生成一个时间戳值,对应于日期值的年/月/日的凌晨
- hive> select cast(date'2022-12-14' as timestamp);
- OK
- 2022-12-14 00:00:00
  • cast(string as date),如果字符串的格式是'YYYY-MM-DD',则返回与该年/月/日对应的日期值。如果字符串值不匹配此格式,则返回NULL
- hive> select cast('2022-12-14' as date);
- OK
- 2022-12-14

- hive> select cast('20221214' as date);
- OK
- NULL
  • cast(timestamp as date),根据本地时区确定,只返回日期值。
- hive> select cast(timestamp'2022-12-14 18:00:00' as date);
- OK
- 2022-12-14

Intervals

  • 可用的时间间隔关键字(依赖 Hive 1.2.0 (HIVE-9792) )
    • SECOND / MINUTE / DAY / MONTH / YEAR
-- 间隔1天
INTERVAL '1' DAY
  • 年至月间隔,格式:SY-M(依赖 Hive 1.2.0 (HIVE-9792) )

    • S:可以符号(+/-)

    • Y:年数

    • M:月数

-- 等同于:INTERVAL '1' YEAR + INTERVAL '2' MONTH
INTERVAL '-1-2' YEAR TO MONTH
  • 日到秒的间隔,格式:SD H:M:S.nnnnnn(依赖 Hive 1.2.0 (HIVE-9792) )

    • S:可以符号(+/-)

    • D:day countH: hours

    • M:分钟

    • S:秒,可选纳秒

-- 等同于:INTERVAL '1' DAY+ INTERVAL '2' HOUR + INTERVAL '3' MINUTE + INTERVAL '4' SECOND + INTERVAL '5' NANO 
INTERVAL '1 2:3:4.000005' DAY
  • 支持常量间隔(依赖 Hive 2.2.0 (HIVE-13557))
-- 增强查询的可读性/可移植性
INTERVAL 1 DAY
  • 支持在表达式中使用INTERVAL(依赖 Hive 2.2.0 (HIVE-13557))
    • 表达式必须是一个数字(不能是浮点类型)或是 STRING 类型
-- 启用动态间隔
INTERVAL (1+dt) DAY
  • INTERVAL 关键字的可选用法:关键字在表达式中必须要有间隔
-- INTERVAL 1 DAY INTERVAL '1-2' YEARS TO MONTH
1 DAY '1-2' YEAR TO MONTH
  • 添加时间单位别名,使可移植性/可读性增强(依赖 Hive 2.2.0 (HIVE-13557))
    • SECONDS / MINUTES / HOURS / DAYS / WEEKS / MONTHS / YEARS
-- 2 SECOND
2 SECONDS

Decimal

Version

Decimal 类型在 Hive 0.11.0 (Hive -2693) 中引入,并在Hive 0.13.0 (Hive -3976)中进行了修订。

NUMERIC 类型在 Hive 3.0.0 (Hive -16764)中被引入,其使用方法与 Decimal 类型相同

Hive 中的 Decimal 类型基于 Java 的 BigDecimal,BigDecimal 用于表示 Java 中不可变的任意精确十进制数。支持十进制类型所有常规数字计算(例如+、-、*、/)和相关udf(例如Floor、Ceil、Round等)处理,Decimals 可以像处理其他数字类型一样转换为十进制类型或从十进制类型转换,支持科学计算法和非科学及算法。 因此无论你的数据集中是否包含科学计数法或非科学计数法,或两者的组合,都可以使用 Decimal 类型进行存储。

  • Hive 0.11 和 0.12 版本,Decimal 类型的精度固定在38位。
  • 在Hive 0.13 中,用户可以在使用Decimal(precision, scale)语法指定具体的精度和位数。如果没有指定scale,则默认为0(没有小数)。如果未指定精度,则默认为10。
CREATE TABLE foo (
  a Decimal, -- Defaults to Decimal(10,0)
  b Decimal(9, 7)
)

Decimal 类型的值域

大于BIGINT的整数必须用 Decimal(38,0) 处理。并需要携带BD后缀。例:

select CAST(18446744073709001000BD AS Decimal(38,0)) from my_table limit 1;

Decimal 类型在 Hive 0.12.0 和 Hive 0.13.0之后的不兼容问题

Hive 0.13.0 版本之前的 Decimal 字段类型都被视作 Decimal(10,0)。这意味着从表中读取的现有数据将被视为10位整数值,而写入这些表的数据将会在写入之前转换为10位整数值写入。为避免这些问题,使用 0.12 或更早版本的 Hive 用户在升级到 Hive 0.13.0 或更高版本后,需要更新包含 Decimal 列的表,具体操作如下。

更新 Pre-Hive 0.13.0 Decimal 列

如果用户使用的是Hive 0.12.0或更早版本,并且创建了带有Decimal类型列的表,在升级到Hive 0.13.0或更高版本后,应该对这些表执行以下步骤。

  1. 确定要为表中的deciaml列设置的精度及位数

  2. 对每个Decimal的列,执行ALTER TABLE 命令来更新:

    ALTER TABLE foo CHANGE COLUMN dec_column_name dec_column_name Decimal(38,18);
    

    如果表不是分区表,那么更新就完成了。如果表有分区,则继续执行步骤3。

  3. 如果表是一个分区表,那么找到表的分区列:

    SHOW PARTITIONS foo;
      
    ds=2008-04-08/hr=11
    ds=2008-04-08/hr=12
    ...
    
  4. 表中的每个现有分区还必须更改其Decimal列,以添加所需的精度/比例。

    这可以通过开启动态分区,执行单条ALTER TABLE CHANGE COLUMN语句来完成所有分区的更新(这需要 Hive 0.14 或更高版本的,参考Hive -8411):

    SET hive.exec.dynamic.partition = true;
      
    -- hive.exec.dynamic.partition needs to be set to true to enable dynamic partitioning with ALTER PARTITION
    -- This will alter all existing partitions of the table - be sure you know what you are doing!
    ALTER TABLE foo PARTITION (ds, hr) CHANGE COLUMN dec_column_name dec_column_name Decimal(38,18);
    

    或者,也可以使用ALTER TABLE CHANGE COLUMN,通过单条语句指定一个分区更新(这需要在Hive 0.14或更高版本中可用,参考Hive -7971)。

    ALTER TABLE foo PARTITION (ds='2008-04-08', hr=11) CHANGE COLUMN dec_column_name dec_column_name Decimal(38,18);
    ALTER TABLE foo PARTITION (ds='2008-04-08', hr=12) CHANGE COLUMN dec_column_name dec_column_name Decimal(38,18);
    ...
    

Union

当前对 UNION 类型的支持是不完善的

UNIONTYPE 数据类型是 在Hive 0.7.0 (Hive -537) 中引入的,但是 Hive 对这种类型的完全支持还不完整。 在 SQL 查询语句中,如果使用到 UNIONTYPE 字段进行 JOIN (HIVE-2508),WHERE,以及GROUP BY 操作,则会导致失败。并且 Hive 不支持解析UNIONTYPE的 tag 和 fields ,这意味着 UNIONTYPE 只能做存储不能做操作。

UNION 类似于 C语言 中的UNION结构,UNION类型可以保存指定数据类型中的任意一种。类型声明语法为UNIONTYPE<data_type,data_type,…>

-- 每个UNION类型的值都通过一个整数来表示其类型,这个整数位声明时的索引,从0开始。例如:
CREATE TABLE union_test(foo UNIONTYPE<int,double,array,strucy<a:int,b:string>>);

-- foo的一些取值如下(其中冒号左边的整数代表数据类型,必须在预先定义的范围类,通过0开始的下标表示。冒号右边是该类型的取值):
{0:1}
{1:2.0}
{2:["three","four"]}
{3:["a":5,b:"five"]}
{0:9}

-- 下面的这个CRATE语句用到了这4种复杂类型:
CREATE TABLE complex (
c1 ARRAY,
c2 MAP<STRING,INT>,
c3 STRUCT<a STRING,b INT,c Double>,
c4 UNIONTYPE<STRING,INT>
);

-- 通过下面的SELECT语句查询相应的数据:
SELECT c1[0] , c2['b'] , c3.c , c4 FROM complex;

-- 结果类似:
1 2 1.0 {1:63}

字面值详述

Float 类型

浮点值被认为与Double一致,目前还不支持科学计数法。

Decimal 类型

Decimal 类型与 Double 类型相比,Decimal 拥有更精确的值和更大的浮点范围。Decimal 数据类型存储精准值,而 Double 类型存储近似值。

当 Double 类型的精度无法满足需求时,需要使用 Decimal 类型,比如金融领域金额计算,对账计算,以及四舍五入等场景。

有关 Double 类型的使用受限相关的讨论,请参阅 Double-precision floating-point format

关于 Decimal 类型的精度在 Hive 中被限制为38位。关于此位数限制的原因,请参阅 HIVE-4271HIVE-4320

Decimal 类型使用

你可以在Hive中创建一个使用Decimal类型的表,语法如下:

create table Decimal_1 (t Decimal);

可以使用LazySimpleSerDeLazyBinarySerDe序列化方式,来读写 Decimal :

alter table Decimal_1 set serde 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe';

or

alter table Decimal_1 set serde 'org.apache.hadoop.hive.serde2.lazy.LazyBinarySerDe';

强制类型转换

支持在deimcal类型和其他基本类型(integer, Double, boolean等)之间进行强制转换,例如:

select cast(t as boolean) from Decimal_2;

数学运算函数

Decimal 还支持许多算术运算符数学UDFUDAFs,其语法与 Double 计算类似。

可以使用 Decimal 类型的基本数学运算包括:

这些舍入类型的函数也可以应用于 Decimal 类型:

  • Floor
  • Ceiling
  • Round

NULL 值的处理

字段的缺失值将由特殊值NULL表示。要导入带有 NULL 字段的数据,请检查表使用的 SerDe 的文档。(默认文本格式使用LazySimpleSerDe,它在导入时将字符串\N会被解释为NULL)。

数据类型转换

hive. Metastore .disallow. compatible.col.type.changes 被设置为false时,Metastore中允许的列类型,可以在类型间进行自由转换。类型转换之后,如果转换后的类型可以正确地显示数据,则值和转换前应当一至,否则,数据将显示为NULL。

Hive 支持的隐式转换

voidbooleantinyintsmallintintbigintfloatDoubleDecimalstringvarchartimestampdatebinary
void totruetruetruetruetruetruetruetruetruetruetruetruetruetrue
boolean tofalsetruefalsefalsefalsefalsefalsefalsefalsefalsefalsefalsefalsefalse
tinyint tofalsefalsetruetruetruetruetruetruetruetruetruefalsefalsefalse
smallint tofalsefalsefalsetruetruetruetruetruetruetruetruefalsefalsefalse
int tofalsefalsefalsefalsetruetruetruetruetruetruetruefalsefalsefalse
bigint tofalsefalsefalsefalsefalsetruetruetruetruetruetruefalsefalsefalse
float tofalsefalsefalsefalsefalsefalsetruetruetruetruetruefalsefalsefalse
Double tofalsefalsefalsefalsefalsefalsefalsetruetruetruetruefalsefalsefalse
Decimal tofalsefalsefalsefalsefalsefalsefalsefalsetruetruetruefalsefalsefalse
string tofalsefalsefalsefalsefalsefalsefalsetruetruetruetruefalsefalsefalse
varchar tofalsefalsefalsefalsefalsefalsefalsetruetruetruetruefalsefalsefalse
timestamp tofalsefalsefalsefalsefalsefalsefalsefalsefalsetruetruetruefalsefalse
date tofalsefalsefalsefalsefalsefalsefalsefalsefalsetruetruefalsetruefalse
binary tofalsefalsefalsefalsefalsefalsefalsefalsefalsefalsefalsefalsefalsetrue