• ADADADADAD

    如何解决MySQL存储时间类型选择的问题[ mysql数据库 ]

    mysql数据库 时间:2024-11-28 13:25:39

    作者:文/会员上传

    简介:

    MySQL中存储时间通常会用datetime类型,但现在很多系统也用int存储unix时间戳,它们有什么区别?本人总结如下:int(1)4个字节存储,INT的长度是4个字节,存储空间上比datatime少,int索引存

    以下为本文的正文内容,内容仅供参考!本站为公益性网站,复制本文以及下载DOC文档全部免费。

    MySQL中存储时间通常会用datetime类型,但现在很多系统也用int存储unix时间戳,它们有什么区别?本人总结如下:

    int

    (1)4个字节存储,INT的长度是4个字节,存储空间上比datatime少,int索引存储空间也相对较小,排序和查询效率相对较高一点点

    (2)可读性极差,无法直观的看到数据

    TIMESTAMP

    (1)4个字节储存

    (2)值以UTC格式保存

    (3)时区转化 ,存储时对当前的时区进行转换,检索时再转换回当前的时区。

    (4)TIMESTAMP值不能早于1970或晚于2037

    datetime

    (1)8个字节储存

    (2)与时区无关

    (3)以'YYYY-MM-DD HH:MM:SS'格式检索和显示DATETIME值。支持的范围为'1000-01-01 00:00:00'到'9999-12-31 23:59:59'

    随着Mysql性能越来越来高,个人觉得关于时间的存储方式,具体怎么存储看个人习惯和项目需求吧

    分享两篇关于int vs timestamp vs datetime性能测试的文章

    Myisam:MySQL DATETIME vs TIMESTAMP vs INT 测试仪

    CREATETABLE`test_datetime`(`id`int(10)unsignedNOTNULLAUTO_INCREMENT,`datetime`FIELDTYPENOTNULL,PRIMARYKEY(`id`))ENGINE=MyISAM;

    机型配置

      kip-locking

      key_buffer = 128M

      max_allowed_packet = 1M

      table_cache = 512

      sort_buffer_size = 2M

      read_buffer_size = 2M

      read_rnd_buffer_size = 8M

      myisam_sort_buffer_size = 8M

      thread_cache_size = 8

      query_cache_type = 0

      query_cache_size = 0

      thread_concurrency = 4

      测试

      DATETIME 14111 14010 14369 130000000
      TIMESTAMP 13888 13887 14122 90000000
      INT 13270 12970 13496 90000000

      执行mysql

      mysql>select*fromtest_datetimeintooutfile‘/tmp/test_datetime.sql';QueryOK,10000000rowsaffected(6.19sec)mysql>select*fromtest_timestampintooutfile‘/tmp/test_timestamp.sql';QueryOK,10000000rowsaffected(8.75sec)mysql>select*fromtest_intintooutfile‘/tmp/test_int.sql';QueryOK,10000000rowsaffected(4.29sec)altertabletest_datetimerenametest_int;altertabletest_intaddcolumndatetimeintINTNOTNULL;updatetest_intsetdatetimeint=UNIX_TIMESTAMP(datetime);altertabletest_intdropcolumndatetime;altertabletest_intchangecolumndatetimeintdatetimeintnotnull;select*fromtest_intintooutfile‘/tmp/test_int2.sql';droptabletest_int;

      So now I have exactly the same timestamps from the DATETIME test, and it will be possible to reuse the originals for TIMESTAMP tests as well.

      mysql> load data infile ‘/export/home/ntavares/test_datetime.sql' into table test_datetime;
      Query OK, 10000000 rows affected (41.52 sec)
      Records: 10000000 Deleted: 0 Skipped: 0 Warnings: 0

      mysql> load data infile ‘/export/home/ntavares/test_datetime.sql' into table test_timestamp;
      Query OK, 10000000 rows affected, 44 warnings (48.32 sec)
      Records: 10000000 Deleted: 0 Skipped: 0 Warnings: 44

      mysql> load data infile ‘/export/home/ntavares/test_int2.sql' into table test_int;
      Query OK, 10000000 rows affected (37.73 sec)
      Records: 10000000 Deleted: 0 Skipped: 0 Warnings: 0

      As expected, since INT is simply stored as is while the others have to be recalculated. Notice how TIMESTAMP still performs worse, even though uses half of DATETIME storage size.

      Let's check the performance of full table scan:

      mysql>SELECTSQL_NO_CACHEcount(id)FROMtest_datetimeWHEREdatetime>‘1970-01-0101:30:00′ANDdatetime<‘1970-01-0101:35:00′;+———–+|count(id)|+———–+|211991|+———–+1rowinset(3.93sec)mysql>SELECTSQL_NO_CACHEcount(id)FROMtest_timestampWHEREdatetime>‘1970-01-0101:30:00′ANDdatetime<‘1970-01-0101:35:00′;+———–+|count(id)|+———–+|211991|+———–+1rowinset(9.87sec)mysql>SELECTSQL_NO_CACHEcount(id)FROMtest_intWHEREdatetime>UNIX_TIMESTAMP('1970-01-0101:30:00′)ANDdatetime<UNIX_TIMESTAMP('1970-01-0101:35:00′);+———–+|count(id)|+———–+|211991|+———–+1rowinset(15.12sec)

      Then again, TIMESTAMP performs worse and the recalculations seemed to impact, so the next good thing to test seemed to be without those recalculations: find the equivalents of those UNIX_TIMESTAMP() values, and use them instead:

      mysql>selectUNIX_TIMESTAMP('1970-01-0101:30:00′)ASlower,UNIX_TIMESTAMP('1970-01-0101:35:00′)ASbigger;+——-+——–+|lower|bigger|+——-+——–+|1800|2100|+——-+——–+1rowinset(0.00sec)mysql>SELECTSQL_NO_CACHEcount(id)FROMtest_intWHEREdatetime>1800ANDdatetime<2100;+———–+|count(id)|+———–+|211991|+———–+1rowinset(1.94sec)

      Innodb:MySQL DATETIME vs TIMESTAMP vs INT performance and benchmarking with InnoDB

    如何解决MySQL存储时间类型选择的问题.docx

    将本文的Word文档下载到电脑

    推荐度:

    下载
    热门标签: mysqlinttimestamp