技术开发 频道

MySQL-数据类型存储-TIMESTAMP

  【IT168技术文档】1. 环境版本:

  OS : LINUX AS4

  MYSQL: 5.0.51a-log

  ENGINE : Myisam

  2. 属性

  TIMESTAMP , Stored as unix time(), low byte first.

  共占4个字节(32位),范围'1970-01-01 00:00:00'到'2037-12-31 23:59:59' ,格式'YYY-MM-DD HH:MM:SS'

  3. 一种算法:

  3.1分析

  在存储时,

  1) 通过UNIX_TIMESTAMP(date)函数,将用户输入的时间转换成unix time();

  select UNIX_TIMESTAMP(date);

  2) 将第1步的结果转换成十六进制 并反向存储.

  在从数据库里取数据时:

  1) 从磁盘定位到行后,按反向顺序取出,并转换成十进制;

  2) 将第1步的结果,用FROM_UNIXTIME()函数获得时间.

  select FROM_UNIXTIME(unix_timestamp);

  注意,以上两个函数都与系统参数:time_zone有关.

  如果两个操作时TIME_ZONE的值不一样,那么得到的日期前后将不一致.

  比如,当前TIME_ZONE='+08:00' ,time = '2009-03-09 14:22:48' ,

  1) select UNIX_TIMESTAMP('2009-03-09 14:22:48');

  --> 1236579768

  2) select conv(1236579768,10,16) ;

  --> 49B4B5B8

  3) 反向存储 : B8 B5 B4 49

  3.2 验证

  下面我们可以来验证一下上面的分析结果:

  set @@time_zone = '+8:00';

  drop table if exists heyf;

  create table heyf (id int ,curtime timestamp) type myisam;

  insert into heyf values (11,'2009-03-09 14:22:48');

  system hexdump /opt/mysql/data/test/heyf.MYD

  ------------------------------------

  0000000 0bfd 0000 b800 b4b5 0049

  0000009

  ------------------------------------

  其中:

  fd : 标志位

  0b 00 00 00 : COL1 ,INT = 11

  b8 b5 b4 49 : 即时间.由于是反向存储,所以需要反向读取: 49b4b5b8

  在这里我们正好来进行反演测试:

  1) b8 b5 b4 49 --> 49b4b5b8

  2) select conv('49b4b5b8',16,10) ;

  --> 1236579768

  3) select FROM_UNIXTIME(1236579768) ;

  --> '2009-03-09 14:22:48'

  我们看到,这个时间前后刚好一致!

  4. 另外一种算法:

  4.1 分析

  存储时:

  1) 将用户输入的时间,与当前SESSION TIME_ZONE 相减. (得到标准格林威治时间)

  2) 将第1步结果与时间" 1970-01-01 00:00:00"相减,得到X秒

  3) 将第2步结果转换与十六进制,并反向

  读取时:

  1) 定位到行后,将字段值反向并转换成十进制;

  2) 将第1步结果与 " 1970-01-01 00:00:00"相加;

  3) 将第2步结果与 当前SESSION TIME_ZONE 相加,并将结果输出给用户

  4.2 验证:

  比如,当前TIME_ZONE='+08:00' ,time = '2008-05-09 15:09:48' ,

  存储时:

  1) select '2008-05-09 15:09:48'- interval 8 hour ;

  --> 2008-05-09 07:09:48

  2) select datediff('2008-05-09','1970-01-01')*24*3600 + time_to_sec('07:09:48');

  --> 1210316988

  3) select conv(1210316988,10,16) ;

  --> 4823F8BC

  反向:

  --> BC F8 32 48

  下面来看一下存储的值:

  set @@time_zone = '+8:00';

  drop table if exists heyf;

  create table heyf (id int ,curtime timestamp) type myisam;

  insert into heyf values (11,'2008-05-09 15:09:48');

  system hexdump /opt/mysql/data/test/heyf.MYD

  ------------------------------------

  0000000 0bfd 0000 bc00 23f8 0048

  0000009

  ------------------------------------

  其中:

  -------------------------------

  fd : 标志位

  0b 00 00 00 : COL1 ,INT = 11

  bc f8 23 48 : 即时间.由于是反向存储,所以需要反向读取: 48 23 f8 bc

  -------------------------------

  反向读取过程:

  1) bc f8 23 48 --> 4823f8bc

  2) select '1970-01-01 00:00:00' + interval conv("4823f8bc",16,10) second ;

  -->2008-05-09 07:09:48

  3) select select @@time_zone;

  --> +08:00

  select '2008-05-09 07:09:48' + interval 8 hour ;

  --> 2008-05-09 15:09:48

  结果完全一致.

  5. 当TIME_ZONE 不一样时

  drop table if exists heyf;

  create table heyf (id int ,curtime timestamp) type myisam;

  set @@time_zone = '+8:00';

  insert into heyf values (11,'2008-08-09 15:53:48');

  (root@FuncTestDB:)> select * from heyf ;

  +------+---------------------+

  | id | curtime |

  +------+---------------------+

  | 11 | 2008-08-09 15:53:48 |

  +------+---------------------+

  1 row in set (0.00 sec)

  (root@FuncTestDB:)> set @@time_zone = '+6:00';

  Query OK, 0 rows affected (0.00 sec)

  (root@FuncTestDB:)> select * from heyf ;

  +------+---------------------+

  | id | curtime |

  +------+---------------------+

  | 11 | 2008-08-09 13:53:48 |

  +------+---------------------+

  1 row in set (0.00 sec)

  (root@FuncTestDB:)> set @@time_zone = '+4:00';

  Query OK, 0 rows affected (0.00 sec)

  (root@FuncTestDB:)> select * from heyf ;

  +------+---------------------+

  | id | curtime |

  +------+---------------------+

  | 11 | 2008-08-09 11:53:48 |

  +------+---------------------+

  1 row in set (0.00 sec)

  我们看到,时间在随着TIME_ZONE的变化而变化;

  timestamp 实际存储的是一个与'19700101000000'的时间差值(秒为单位),在提取时会根据当前的TIME_ZONE来重新计算.

  所以我们在使用这种类型的数据时,要特别注意系统变量:TIME_ZONE。

0
相关文章