【问题标题】:Converting mysql column from INT to TIMESTAMP将mysql列从INT转换为TIMESTAMP
【发布时间】:2012-02-26 07:05:59
【问题描述】:

当我年轻的时候,stupid 没有什么经验,我决定用 PHP 生成时间戳并将它们存储在我的 MySQL innodb 表的INT 列中是个好主意。现在,当这个表有数百万条记录并且需要一些基于日期的查询时,是时候将该列转换为TIMESTAMP。我该怎么做?

当前,我的表是这样的:

id (INT) | message (TEXT) | date_sent (INT)
---------------------------------------------
1        | hello?         | 1328287526
2        | how are you?   | 1328287456
3        | shut up        | 1328234234
4        | ok             | 1328678978
5        | are you...     | 1328345324

这是我想出的查询,将date_sent 列转换为TIMESTAMP

-- creating new column of TIMESTAMP type
ALTER TABLE `pm`
  ADD COLUMN `date_sent2` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP();

-- assigning value from old INT column to it, in hope that it will be recognized as timestamp
UPDATE `pm` SET `date_sent2` = `date_sent`;

-- dropping the old INT column
ALTER TABLE `pm` DROP COLUMN `date_sent`;

-- changing the name of the column
ALTER TABLE `pm` CHANGE `date_sent2` `date_sent` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP();

对我来说一切似乎都是正确的,但是当UPDATEpmSETdate_sent2=date_sent; 的时间到了,我收到一个警告并且时间戳值仍然为空:

+---------+------+--------------------------------------------------+
| Level   | Code | Message                                          |
+---------+------+--------------------------------------------------+
| Warning | 1265 | Data truncated for column 'date_sent2' at row 1  |

我做错了什么,有办法解决这个问题吗?

【问题讨论】:

    标签: mysql timestamp


    【解决方案1】:

    你快到了,使用FROM_UNIXTIME()而不是直接复制值。

    -- creating new column of TIMESTAMP type
    ALTER TABLE `pm`
      ADD COLUMN `date_sent2` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP();
    
    -- Use FROM_UNIXTIME() to convert from the INT timestamp to a proper datetime type
    -- assigning value from old INT column to it, in hope that it will be recognized as timestamp
    UPDATE `pm` SET `date_sent2` = FROM_UNIXTIME(`date_sent`);
    
    -- dropping the old INT column
    ALTER TABLE `pm` DROP COLUMN `date_sent`;
    
    -- changing the name of the column
    ALTER TABLE `pm` CHANGE `date_sent2` `date_sent` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP();
    

    【讨论】:

      【解决方案2】:

      这种方式不需要临时字段来存储时间戳类型值,因此在更改大型表时应该对停机更友好,并且它也适用于 DATE(TIME) 类型字段(见下文)。

      如需将时间戳或日期时间转换为 int,请参阅:Mysql: Convert column from timestamp to int and perform conversion for each update

      首先我们必须将时间戳类型转换为不带标点符号的数字日期时间(如 202102060020302),因为数字完整形式太长而无法存储 int,应将字段更改为 bigint 类型(如果您需要 datetime 类型,这将是 TEXT 类型) :

      ALTER TABLE `table` CHANGE `field` `field` BIGINT NOT NULL;
      

      然后将时间戳转换为数字日期时间(如果您需要日期时间类型,则应删除 CAST()):

      UPDATE `table` SET `field` = CAST(FROM_UNIXTIME(`field`) AS UNSIGNED);
      

      最后我们可以将字段类型更改为时间戳,mysql 将完成转换数字日期时间的其余工作(如果您需要日期时间类型,只需使用 DATETIME):

      ALTER TABLE `table` CHANGE `field` `field` TIMESTAMP NOT NULL;
      

      参考https://dev.mysql.com/doc/refman/8.0/en/date-and-time-type-conversion.html

      > mysql> SELECT CURTIME(), CURTIME()+0, CURTIME(3)+0;
      > +-----------+-------------+--------------+
      > | CURTIME() | CURTIME()+0 | CURTIME(3)+0 |
      > +-----------+-------------+--------------+
      > | 09:28:00  |       92800 |    92800.887 |
      > +-----------+-------------+--------------+
      > mysql> SELECT NOW(), NOW()+0, NOW(3)+0;
      > +---------------------+----------------+--------------------+
      > | NOW()               | NOW()+0        | NOW(3)+0           |
      > +---------------------+----------------+--------------------+
      > | 2012-08-15 09:28:00 | 20120815092800 | 20120815092800.889 |
      > +---------------------+----------------+--------------------+
      

      【讨论】:

        猜你喜欢
        • 2013-08-08
        • 1970-01-01
        • 2017-04-11
        • 1970-01-01
        • 1970-01-01
        • 2023-03-04
        • 2011-01-22
        • 2023-04-09
        • 2016-10-19
        相关资源
        最近更新 更多