暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

GBase8a如何将不同格式的日期时间数据加载入库

VV_刺头王 2022-03-14
2635

1. GBase 8a MPP Cluster支持的日期和时间类型,如下表所示:
类型名称 最小值 最大值 格式
DATE 0001-01-01 9999-12-31 YYYY-MM-dd
DATETIME 0001-01-01 00:00:00.000000 9999-12-31 23:59:59.999999 YYYY-MM-dd HH:MI:SS.ffffff
TIME -838:59:59 838:59:59 HHH:MI:SS
TIMESTAMP 1970-01-01 08:00:01 2038-01-01 00:59:59 YYYY-MM-DD HH:MI:SS
当使用日期和时间类型时,用户应当提供正确的格式:如,YYYY-MM-DD、YYYY-MM-DD HH:MI:SS。


2. 应该选择datetime还是选择timestamp?各中日期格式的数据如何加载入库?
Datetime类型支持六位的时间精度,可以到纳秒;
Timestamp类型只能支持到秒;Timestamp在GBase8a集群中是时间戳类型,必须指定默认值,且每个表中只允许一个timestamp类型指定默认值为当前日期时间(CURRENT_TIMESTAMP);

在一些oracle等数据库迁移中,如不熟悉GBase8a集群的日期时间类型情况,会直接将Oracle的timestamp迁移为GBase 8a的timestamp类型,一是会造成时间精度的丢失,二是GBase8a的timestamp默认会直接设置第一个timestamp字段的默认值为CURRENT_TIMESTAMP,如该表有第二个字段真实需要时间戳属性时,就会造成困扰。


3. Gbase 8a对日期格式的处理
默认的日期、时间字段数据的格式见上表。
 在查询展示时,可以通过date_format()、to_date()、to_char()等函数进行日期、时间数据的格式化。
 insert values入库日期格式的数据也较为宽泛,可以是年月日时分秒的数值数据,可以是各类分隔符,如下面的三个数据都可以通过insert values插入到定义为datetime类型的字段中
20200111120002
'2020-01-11 12/00/03'
'2020/11/11 12/00/03'
 对于日期、时间类型数据有多种数据格式,那么在加载入库时,需要严格按照其日期格式进行匹配,此时可以使用DATETIME|TIMESTAMP|DATE|TIME FORMAT format进行日期\时间格式的匹配与定义,不同类型的字段使用不同的FORMAT,如datetime类型字段使用TIMESTAMP FORMAT会没有效果。
格式 描述
%a 星期名的英文缩写形式(Sun...Sat)
%b 月份的英文缩写形式(Jan...DEC)
%c 月份的数字形式(0...12)
%D 有英文后缀的某月的第几天(0th, 1st, 2nd, 3rd...)
%d 月份中的天数,数字形式(00...31)
%e 月份中的天数,数字形式(0...31)
%f 微秒(000000...999999)
%H 小时,24小时制(00...23)
%h 小时,12小时制(0,1...12)
%I 小时,12小时制,个位数字前加0(01...12)
%i 分钟,数字形式(00...59)
%j 一年中的天数(001...366)
%k 小时,24小时制(0...23)
%l 小时,12小时制(1...12)
%M 月份,英文形式全拼(January...December)
%m 月份,数字形式(00...12)
%p AM或PM
%r 时间,12小时制(HH:MI:SS后面紧跟AM或PM)
%S 秒(00...59)
%s 秒(00...59)
%T 时间,24小时(HH:MI:SS)
%U 星期(00...53),星期日是一个星期的第一天
%u 星期(00...53),星期一是一个星期的第一天
%V 星期(01...53),星期日是一个星期的第一天。
与“%X”一起使用
%v 星期(01...53),星期一是一个星期的第一天。
与“%x”一起使用
%W 星期名的英文全拼形式(Sunday...Saturday)
%w 一星期中的哪一天(0=Sunday...6=Saturday)
%X 以4位数字形式反映周所在的年份,星期日周的第一天
%x 以4位数字形式反映周所在的年份,星期日周的第一天
%Y 4位数字形式表达的年份
%y 2位数字形式表达的年份
%% 一个字母“%”
%. 除字母、数字和空格外的一个或多个字符
%@ 一个或多个字母
%# 一个或多个数字

 示例:日期时间的默认加载和指定格式加载
下面以举例的方式介绍日期时间格式的加载,所使用的的数据样例为dt123.txt文件,内容如下:
[gbase@pst_w160 test]$ cat dt123.txt
2020-05-31 21:10:01.654321|1
2020-06-12 10:00:01|2
|3
|4
null|5
2020-07-01 01/22/10|6
2019.06.18 21:01:50.123456|7

gbase> create table dt1(d1 datetime,id int);
Query OK, 0 rows affected (Elapsed: 00:00:00.05)
Ø 不指定日期格式,测试用例如下:
gbase> load data infile 'ftp://gbase:gbase@172.16.3.160/home/gbase/test/dt123.txt' into table dt1 FIELDS TERMINATED BY '|' ;
Query OK, 3 rows affected (Elapsed: 00:00:00.70)
Task 486416 finished, Loaded 3 records, Skipped 4 records
gbase> select * from dt1;
+---------------------+------+
| d1 | id |
+---------------------+------+
| NULL | 3 |
| 2020-06-12 10:00:01 | 2 |
| NULL | 4 |
+---------------------+------+
3 rows in set (Elapsed: 00:00:00.02)
-- 注释:默认的datetime加载格式为YYYY-MM-dd HH:MI:SS,因此只有2020-06-12 10:00:01符合格式要求,可以正确入库。入库数据包含空值数据,默认情况下空串被认为是null值,也可以在加载时通过null_values指定NULL值。

Ø 指定日期时间数据格式
gbase> load data infile 'ftp://gbase:gbase@172.16.3.160/home/gbase/test/dt123.txt' into table test.dt1 FIELDS TERMINATED BY '|' DATETIME FORMAT '%Y-%m-%d %H:%i:%s.%f' ;
Query OK, 4 rows affected (Elapsed: 00:00:00.68)
Task 486419 finished, Loaded 4 records, Skipped 3 records
gbase> select * from dt1;
+----------------------------+------+
| d1 | id |
+----------------------------+------+
| 2020-06-12 10:00:01 | 2 |
| NULL | 4 |
| 2020-05-31 21:10:01.654321 | 1 |
| NULL | 3 |
+----------------------------+------+
4 rows in set (Elapsed: 00:00:00.01)


gbase> create table dt2(ts1 timestamp DEFAULT CURRENT_TIMESTAMP, id int);
Query OK, 0 rows affected (Elapsed: 00:00:00.04)
gbase> load data infile 'ftp://gbase:gbase@172.16.3.160/home/gbase/test/dt123.txt' into table test.dt2 FIELDS TERMINATED BY '|' TIMESTAMP FORMAT '%Y-%m-%d %H/%i/%s' ;
Query OK, 3 rows affected (Elapsed: 00:00:00.78)
Task 486423 finished, Loaded 3 records, Skipped 4 records
gbase> select * from dt2;
+---------------------+------+
| ts1 | id |
+---------------------+------+
| 2021-10-11 05:10:15 | 3 |
| 2020-07-01 01:22:10 | 6 |
| 2021-10-11 05:10:15 | 4 |
+---------------------+------+
3 rows in set (Elapsed: 00:00:00.01)
-- id=6的数据2020-07-01 01/22/10入库,如使用DATETIME FORMAT而不是TIMESTAMP FORMAT,则入库数据为默认格式的日期数据和空值数据。


gbase> CREATE TABLE dt3(d3 datetime default '2020-01-01 12:00:00',id int);
Query OK, 0 rows affected (Elapsed: 00:00:00.03)
gbase> load data infile 'sftp://gbase:gbase@172.16.3.160/home/gbase/test/dt123.txt' into table test.dt3 FIELDS TERMINATED BY '|' DATETIME FORMAT '%Y-%m-%d %H:%i:%s.%f' ;
Query OK, 4 rows affected (Elapsed: 00:00:00.70)
Task 486432 finished, Loaded 4 records, Skipped 3 records
gbase> select * from dt3;
+----------------------------+------+
| d3 | id |
+----------------------------+------+
| 2020-05-31 21:10:01.654321 | 1 |
| 2020-01-01 12:00:00 | 3 |
| 2020-06-12 10:00:01 | 2 |
| 2020-01-01 12:00:00 | 4 |
+----------------------------+------+
4 rows in set (Elapsed: 00:00:00.02)
-- 当日期数据有默认值时,会将null值替换为默认值数据

Ø 按列指定日期时间数据格式的加载
加载时,可以通过TABLE_FIELDS指定日期时间列的格式,适用于一个表中有多个datetime列,且数据格式不统一
gbase> load data infile 'sftp://gbase:gbase@172.16.3.160/home/gbase/test/dt123.txt' into table test.dt1 FIELDS TERMINATED BY '|' TABLE_FIELDS 'd1 date "%Y-%m-%d %H/%i/%s",id';
Query OK, 3 rows affected (Elapsed: 00:00:00.65)
Task 486427 finished, Loaded 3 records, Skipped 4 records
gbase> select * from dt1;
+---------------------+------+
| d1 | id |
+---------------------+------+
| NULL | 4 |
| NULL | 3 |
| 2020-07-01 01:22:10 | 6 |
+---------------------+------+
3 rows in set (Elapsed: 00:00:00.02)

Ø 日期格式只有分隔符不同时的加载
样例数据中,2020-06-12 10:00:01、2020-07-01 01/22/10、2019.06.18 21:01:50.123456三个数据格式不一致但只有分隔符不同,且都是一个字段的数据,按照前面举例,因加载时指定的日期格式为"%Y-%m-%d %H:%i:%s",导致数据加载时不符合该格式的数据作为错误数据被skipped。
GBase 8a集群提供了%.和%@来处理这种场景。
gbase> load data infile 'sftp://gbase:gbase@172.16.3.160/home/gbase/test/dt123.txt' into table test.dt1 FIELDS TERMINATED BY '|' DATETIME FORMAT '%Y%.%m%.%d %H%.%i%.%s.%f' ;
Query OK, 6 rows affected (Elapsed: 00:00:00.82)
Task 486439 finished, Loaded 6 records, Skipped 1 records
gbase> select * from dt1;
+----------------------------+------+
| d1 | id |
+----------------------------+------+
| 2020-06-12 10:00:01 | 2 |
| NULL | 4 |
| 2019-06-18 21:01:50.123456 | 7 |
| 2020-05-31 21:10:01.654321 | 1 |
| NULL | 3 |
| 2020-07-01 01:22:10 | 6 |
+----------------------------+------+
6 rows in set (Elapsed: 00:00:00.02)
如果数据中包含有字母,则需要使用%@来处理,如下用例
gbase> load data infile 'sftp://gbase:gbase@172.16.3.160/home/gbase/test/dt124.txt' into table test.dt1 FIELDS TERMINATED BY '|' DATETIME FORMAT '%Y%@%m%@%d%@ %H%@%i%@%s%@';
Query OK, 1 row affected (Elapsed: 00:00:02.57)
Task 486451 finished, Loaded 1 records, Skipped 0 records
gbase> select * from dt1;
+---------------------+------+
| d1 | id |
+---------------------+------+
| 2015-05-31 21:01:50 | 8 |
+---------------------+------+
1 row in set (Elapsed: 00:00:00.02)
gbase> system cat ~/test/dt124.txt
2015year05M31d 21h01m50sec|8

最后修改时间:2022-03-18 15:20:55
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论