Hive 提供了 DATE 类型作为存储日期的格式,但在大多数业务中还是用 STRING 格式来存储日期,那么为什么不使用 DATE 呢?
什么是DATE格式
HIve 中的 DATE 格式遵循 ISO 标准,用 YYYY-MM-DD
描述年月日。
测试用例
设计一些日期字符串用作测试用例,涵盖不同分隔符、简化的年月日,以及错误的日期等情景:
1 | 2023-01-01 |
在 Hive 中创建 test_date
表,载入文件数据:
1 | hive> create table test_date(dt date); |
将查询结果和原始数据放一起进行比较:
原始数据 | 查询结果 |
---|---|
2023-01-01 | 2023-01-01 |
2023/01/02 | NULL |
20230103 | NULL |
2023-1-4 | 2023-01-04 |
23-1-5 | NULL |
2023-1-06 | 2023-01-06 |
2023-01-7 | 2023-01-07 |
2023-02-31 | 2023-03-03 |
2023-04-31 | 2023-05-01 |
2023-05-31 | 2023-05-31 |
2023-05-32 | NULL |
2023-13-01 | NULL |
可以看到 DATE 格式可以识别出来的日期字符串格式有以下特征:
- 年、月、日之间使用
-
分割; - 年份必须完整;
- 月和日支持短格式。
DATE 格式对日期也有一定的纠错能力:
- 部分月份没有 29、30、31 日,会被纠正为下个月的相应日期,比如 4 月 31 日可以被自动纠正为 5 月 1 日;
- 错误的日期数据,比如 13 月或 32 日会被记为
NULL
。
查询
使用文件内的原始字符串作为查询条件对表数据进行查询,用 IN
运算符指定这些字符串,看看能否查询出结果:
1 | hive> select dt from test_date where dt in ('2023-01-01','2023/01/02','20230103','2023-1-4','23-1-5','2023-1-06','2023-01-7','2023-02-31','2023-04-31','2023-05-31','2023-05-32','2023-13-01'); |
似乎只有格式严格遵守 ISO 标准即 YYYY-MM-DD
且没被纠错过的字符串能得到查询结果。为了验证是否真的如此,把 IN
运算符中的字符串改为正确格式后再进行查询:
1 | hive> select dt from test_date where dt in ('2023-01-01','2023-01-02','2023-01-03','2023-01-04','23-01-05','2023-01-06','2023-01-07','2023-03-03','2023-05-01','2023-05-31','2023-05-32','2023-13-01'); |
修改后非 NULL
数据都能查询出来了。
难道只有对查询条件中的日期字符串做 ISO 标准化和纠错后才能查询到结果么?将 IN
运算符修改为 =
后再试下,发现用原始数据也可以查询到了:
1 | hive> select dt from test_date where dt='2023-01-01' OR dt='2023/01/02' OR dt='20230103' OR dt='2023-1-4' OR dt='23-1-5' OR dt='2023-1-06' OR dt='2023-01-7' OR dt='2023-02-31' OR dt='2023-04-31' OR dt='2023-05-31' OR dt='2023-05-32' OR dt='2023-13-01'; |
如何选择日期格式
问问 ChatGPT 的看法吧。
Hive 中存储日期使用 Date 好还是 String 好?
在使用 =
运算符时,查询条件中的日期字符串也支持短格式和纠错。
在Hive中存储日期数据,使用Date
类型或者String
类型都是可以的,具体应该根据实际情况来选择。下面是一些比较常见的考虑因素:
- 存储空间:对于同一个日期,使用
Date
类型只需要占用4个字节的存储空间,而使用String
类型可能会占用更多的存储空间。 - 查询效率:如果需要对日期进行排序、分组等操作,使用
Date
类型通常比使用String
类型更加高效。 - 数据来源:如果日期数据源来自于文件或者数据库中的字符型字段,建议使用
String
类型,这样避免了类型转换带来的开销和错误。
总之,在选择日期类型时,需要考虑到具体的业务需求,权衡存储空间与查询效率等方面的利弊,并且需要注意保持数据的一致性,避免出现格式不统一、类型不匹配等问题。
为什么说 Hive 中 Date 类型比 String 类型对日期进行排序、分组等操作效率高?
在Hive中,Date类型比String类型对日期进行排序、分组等操作效率高的原因是因为Date类型本身是可以被序列化和反序列化的,而String类型则需要先进行解析。
具体来说,Date类型存储的是一个整数,而String类型存储的是一串字符。当Hive需要对其中一个字段进行排序或分组时,如果该字段是Date类型,则只需要将该整数进行比较即可;而如果该字段是String类型,则需要将每个字符串进行解析并转换为日期格式后再进行比较。这个过程会非常耗时和资源消耗。
此外,Date类型还有一个优势是它的排序和比较结果更加准确。由于String类型存储的是一串字符,因此可能存在诸如“2021-01-01”和“2021/01/01”这样的格式不同但实际表示同一日期的情况。而Date类型只存储日期值,不涉及任何格式问题,自然比较和排序更加准确和可靠。
因此,在Hive中,如果数据中包含日期信息,建议使用Date类型进行存储和处理,能够提高查询效率和准确性。