【IT168 专稿】MySQL 5.6引入了一个新功能,即在某些时间数据类型中增加了对微秒的支持。在MySQL 5.6.4中,TIME、TIMESTAMP和DATETIME能够支持秒的小数部分。在创建一个亚秒字段时,可以在括号里定义精度,如TIME(3)、DATETIME(6)等。
很明显,新功能会带来数据类型格式的变化。TIME、TIMESTAMP和DATETIME三种数据类型存在小数部分,或许有1-3字节的长度,最多可以精确到小数点后6位。
非小数部分也发生了变化。因此,DATETIME数据类型仅占用5个字节,而在之前的版本中需要占用8个字节。
下面新建一个示例表,看看新的时间类型是怎么工作的:
`id` int(11) AUTO_INCREMENT,
`t1` time(3),
`t2` timestamp(6),
`t3` datetime(1),
`t4` datetime,
PRIMARY KEY (`id`)
) ENGINE=InnoDB
+----+--------------+----------------------------+-----------------------+---------------------+
| id | t1 | t2 | t3 | t4 |
+----+--------------+----------------------------+-----------------------+---------------------+
| 1 | 05:05:10.000 | 2013-07-04 05:05:10.000000 | 2013-07-04 05:05:10.0 | 2013-07-04 05:05:10 |
| 2 | 05:14:24.414 | 2013-07-04 05:14:24.125000 | 2013-07-04 05:14:24.4 | 2013-07-04 05:14:25 |
| 3 | 05:14:32.566 | 2013-07-04 05:14:32.207031 | 2013-07-04 05:14:32.3 | 2013-07-04 05:14:32 |
| 4 | 05:14:34.344 | 2013-07-04 05:14:34.507813 | 2013-07-04 05:14:34.5 | 2013-07-04 05:14:35 |
| 5 | 05:14:45.348 | 2013-07-04 05:14:45.832031 | 2013-07-04 05:14:45.1 | 2013-07-04 05:14:45 |
+----+--------------+----------------------------+-----------------------+---------------------+
首先,生成一个表定义文件,如下:
然后,重编译工具,并分割包含表t记录的表空间:
下一步,在InnoDB索引中得到记录:
-- Page id: 3, Format: COMPACT, Records list: Valid, Expected records: (5 5)
0000000007DB A6000001A20110 t 1 "05:05:10.0" "2013-07-04 05:05:10.0" "2013-07-04 05:05:10.0" "2013-07-04 05:05:10.0"
0000000007DE A8000001530110 t 2 "05:14:24.4140" "2013-07-04 05:14:24.125000" "2013-07-04 05:14:24.40" "2013-07-04 05:14:25.0"
0000000007EC B2000001A40110 t 3 "05:14:32.5660" "2013-07-04 05:14:32.207031" "2013-07-04 05:14:32.30" "2013-07-04 05:14:32.0"
0000000007ED B3000001A50110 t 4 "05:14:34.3440" "2013-07-04 05:14:34.507813" "2013-07-04 05:14:34.50" "2013-07-04 05:14:35.0"
0000000007FB BD000001670110 t 5 "05:14:45.3480" "2013-07-04 05:14:45.832031" "2013-07-04 05:14:45.10" "2013-07-04 05:14:45.0"
-- Page id: 3, Found records: 5, Lost records: NO, Leaf page: YES
使用LOAD DATA INFILE命令加载dump文件,然后重新传入上面示例的/dev/null中。
以上的过程非常简单,这里有两点需要注意:
·由于格式不同,该工具可以检测字段的格式是新的还是旧的;
·新格式中的TIME类型字段(不管是否包含小数部分)需要给contraints_parser一个提示,如This is -6 option。
在MySQL 5.6.4之前,TIME类型占用3个字节:DD×24×3600 + HH×3600 + MM×60 + SS。MySQL 5.6.4之后,类型仍然占用3个字节,但是格式发生了变化:
TIME的新格式
位 | 描述 | 值 |
1 | sign | 1= non-negative, 0= negative |
1 | unused | reserved for future extensions |
10 | hour | 0-838 |
6 | minute | 0-59 |
6 | second | 0-59 |
如果创建的字段没有小数部分,就不能定义字段值的格式,以下表为例:
`id` int(11) AUTO_INCREMENT,
`t1` time ,
`t2` time(3) ,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
+----+----------+--------------+
| id | t1 | t2 |
+----+----------+--------------+
| 1 | 11:01:17 | 11:01:17.000 |
| 2 | 11:01:17 | 11:01:17.125 |
| 3 | 11:01:17 | 11:01:17.125 |
+----+----------+--------------+
如果没有小数部分,constraints_parser表现为旧格式。因此,如果从上面的表格中恢复记录,结果将是错误的:
-- Page id: 3, Format: COMPACT, Records list: Valid, Expected records: (3 3)
000000000807 C5000001AC0110 t8 1 "12:32:17" "11:01:17.0"
000000000807 C5000001AC011C t8 2 "12:32:17" "11:01:17.1250"
000000000807 C5000001AC0128 t8 3 "12:32:17" "11:01:17.1250"
-- Page id: 3, Found records: 3, Lost records: NO, Leaf page: YES
因此需要给constraints_parser一个提示-6,那么TIME的值将是正确的:
-- Page id: 3, Format: COMPACT, Records list: Valid, Expected records: (3 3)
000000000807 C5000001AC0110 t8 1 "11:01:17.0" "11:01:17.0"
000000000807 C5000001AC011C t8 2 "11:01:17.0" "11:01:17.1250"
000000000807 C5000001AC0128 t8 3 "11:01:17.0" "11:01:17.1250"
-- Page id: 3, Found records: 3, Lost records: NO, Leaf page: YES
原文链接:Recovering temporal types in MySQL 5.6: TIME, TIMESTAMP and DATETIME