您的位置:首页 > 数据库 > MySQL

MySQL中同时存在创建和上次更新时间戳字段解决方法浅析;MYSQL日期 字符串 时间戳互转

2017-03-12 15:47 821 查看
因为欣赏所以转载,原文地址 http://www.2cto.com/database/201409/330251.html 
http://www.cnblogs.com/jhy-ocean/p/5560857.html
在写这篇文章之前,明确我的MySQL版本。

mysql> SELECT VERSION(); +------------+ | VERSION() | +------------+ | 5.5.29-log | +------------+ 1 row in set (0.00 sec)

第一个,测试通过。  


?
?
第一种,created_at使用DEFAULT CURRENT_TIMESTAMP或者DEFAULT now(),updated_at使用触发器。

?
mysql> INSERT INTO temp(name,created_at,updated_at) VALUES('robin',now(),now()); Query OK, 1 row affected (0.03 sec) mysql> INSERT INTO temp(name,created_at,updated_at)
VALUES('wentasy',now(),now()); Query OK, 1 row affected (0.01 sec) mysql> SELECT * FROM temp; +----+---------+---------------------+---------------------+ | id | name | created_at | updated_at | +----+---------+---------------------+---------------------+
| 1 | robin | 2014-09-01 14:00:39 | 2014-09-01 14:00:39 | | 2 | wentasy | 2014-09-01 14:01:11 | 2014-09-01 14:01:11 | +----+---------+---------------------+---------------------+ 2 rows in set (0.00 sec)
delimiter | DROP TRIGGER IF EXISTS tri_temp_updated_at; CREATE TRIGGER tri_temp_updated_at BEFORE UPDATE ON temp FOR EACH ROW BEGIN SET NEW.updated_at = now(); END; | delimiter ;

mysql> UPDATE temp SET name='robinwen' WHERE id=1; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 #可以看到已经记录了第一条数据的更新时间 mysql> SELECT * FROM temp; +----+----------+---------------------+---------------------+ | id | name | created_at | updated_at | +----+----------+---------------------+---------------------+ | 1 | robinwen | 2014-09-01 14:00:39 | 2014-09-01 14:03:05 | | 2 | wentasy | 2014-09-01 14:01:11 | 2014-09-01 14:01:11 | +----+----------+---------------------+---------------------+ 2 rows in set (0.00 sec)

第二种,created_at使用触发器,updated_at使用DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP或者DEFAULT now() ON UPDATE now();


具体解决方法如下:

?
delimiter | DROP TRIGGER IF EXISTS tri_temp_created_at; CREATE TRIGGER tri_temp_created_at BEFORE INSERT ON temp FOR EACH ROW BEGIN IF new.created_at IS NULL
THEN SET new.created_at=now(); END IF; END; | delimiter ;
mysql> INSERT INTO temp(name,created_at,updated_at) VALUES('robin',now(),now()); Query OK, 1 row affected (0.01 sec) mysql> INSERT INTO temp(name,created_at,updated_at) VALUES('wentasy',now(),now()); Query OK, 1 row affected (0.01 sec) mysql> SELECT * FROM temp; +----+---------+---------------------+---------------------+ | id | name | created_at | updated_at | +----+---------+---------------------+---------------------+ | 1 | robin | 2014-09-01 14:08:36 | 2014-09-01 14:08:36 | | 2 | wentasy | 2014-09-01 14:08:44 | 2014-09-01 14:08:44 | +----+---------+---------------------+---------------------+ 2 rows in set (0.00 sec)

mysql> UPDATE temp SET name='robinwen' WHERE id=1; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 #可以看到已经记录了第一条数据的更新时间 mysql> SELECT * FROM temp; +----+----------+---------------------+---------------------+ | id | name | created_at | updated_at | +----+----------+---------------------+---------------------+ | 1 | robinwen | 2014-09-01 14:08:36 | 2014-09-01 14:09:09 | | 2 | wentasy | 2014-09-01 14:08:44 | 2014-09-01 14:08:44 | +----+----------+---------------------+---------------------+ 2 rows in set (0.00 sec)

第三种,created_at指定timestamp DEFAULT '0000-00-00 00:00:00',updated_at指定DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP或者timestamp DEFAULT now() ON UPDATE now();
CREATE TABLE temp ( id INT(11) PRIMARY KEY AUTO_INCREMENT, name VARCHAR(10), created_at timestamp NULL DEFAULT '0000-00-00 00:00:00', updated_at timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP );

mysql> INSERT INTO temp(name,created_at,updated_at) VALUES('robin',now(),now()); Query OK, 1 row affected (0.01 sec) mysql> INSERT INTO temp(name,created_at,updated_at) VALUES('wentasy',now(),now()); Query OK, 1 row affected (0.01 sec) mysql> SELECT * FROM temp; +----+---------+---------------------+---------------------+ | id | name | created_at | updated_at | +----+---------+---------------------+---------------------+ | 1 | robin | 2014-09-01 14:10:43 | 2014-09-01 14:10:43 | | 2 | wentasy | 2014-09-01 14:10:57 | 2014-09-01 14:10:57 | +----+---------+---------------------+---------------------+ 2 rows in set (0.00 sec)

mysql> UPDATE temp SET name='robinwen' WHERE id=1; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 #可以看到已经记录了第一条数据的更新时间 mysql> SELECT * FROM temp; +----+----------+---------------------+---------------------+ | id | name | created_at | updated_at | +----+----------+---------------------+---------------------+ | 1 | robinwen | 2014-09-01 14:10:43 | 2014-09-01 14:11:24 | | 2 | wentasy | 2014-09-01 14:10:57 | 2014-09-01 14:10:57 | +----+----------+---------------------+---------------------+ 2 rows in set (0.00 sec)

第四种,更换MySQL版本,MySQL 5.6已经去除了此限制。


我们可以看下MySQL 5.5和5.6帮助文档对于这个问题的解释。

From the MySQL 5.5 documentation:

One TIMESTAMP column in a table can have the current timestamp as the default value for initializing the column, as the auto-update value, or both. It is not possible to have the current timestamp be the default value for one column and the auto-update value
for another column.

Changes in MySQL 5.6.5:

Previously, at most one TIMESTAMP column per table could be automatically initialized or updated to the current date and time. This restriction has been lifted. Any TIMESTAMP column definition can have any combination of DEFAULT CURRENT_TIMESTAMP and ON UPDATE
CURRENT_TIMESTAMP clauses. In addition, these clauses now can be used with DATETIME column definitions. For more information, see Automatic Initialization and Updating for TIMESTAMP and DATETIME.

我们确定下MySQL的版本。
mysql> SELECT VERSION();
+---------------------------------------+
| VERSION()                             |
+---------------------------------------+
| 5.6.20-enterprise-commercial-advanced |
+---------------------------------------+
1 row in set (0.00 sec)

CREATE TABLE temp ( id INT(11) PRIMARY KEY AUTO_INCREMENT, name VARCHAR(10), created_at timestamp NULL DEFAULT CURRENT_TIMESTAMP, updated_at timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ); Query OK, 0 rows affected (0.28 sec)

mysql> INSERT INTO temp(name) VALUES('robin'); Query OK, 1 row affected (0.07 sec) mysql> INSERT INTO temp(name) VALUES('wentasy'); Query OK, 1 row affected (0.00 sec) mysql> SELECT * FROM temp; +----+---------+---------------------+---------------------+ | id | name | created_at | updated_at | +----+---------+---------------------+---------------------+ | 1 | robin | 2014-09-01 15:05:57 | 2014-09-01 15:05:57 | | 2 | wentasy | 2014-09-01 15:06:02 | 2014-09-01 15:06:02 | +----+---------+---------------------+---------------------+ 2 rows in set (0.01 sec) mysql> UPDATE temp SET name='robinwen' WHERE id=1; Query OK, 1 row affected (0.02 sec) Rows matched: 1 Changed: 1 Warnings: 0 #可以看到已经记录了第一条数据的更新时间 mysql> SELECT * FROM temp; +----+----------+---------------------+---------------------+ | id | name | created_at | updated_at | +----+----------+---------------------+---------------------+ | 1 | robinwen | 2014-09-01 15:05:57 | 2014-09-01 15:06:45 | | 2 | wentasy | 2014-09-01 15:06:02 | 2014-09-01 15:06:02 | +----+----------+---------------------+---------------------+ 2 rows in set (0.00 sec)


总结

平时比较常用的时间、字符串、时间戳之间的互相转换,虽然常用但是几乎每次使用时候都喜欢去搜索一下用法;本文将作为一个笔记,整理一下三者之间的 转换(即:date转字符串、date转时间戳、字符串转date、字符串转时间戳、时间戳转date,时间戳转字符串)用法,方便日后查看;


涉及的函数

date_format(date, format) 函数,MySQL日期格式化函数date_format()

unix_timestamp() 函数

str_to_date(str, format) 函数

from_unixtime(unix_timestamp, format) 函数,MySQL时间戳格式化函数from_unixtime


时间转字符串

select date_format(now(), '%Y-%m-%d');  

  

#结果:2016-01-05  


时间转时间戳

select unix_timestamp(now());  

  

#结果:1452001082  


字符串转时间

select str_to_date('2016-01-02', '%Y-%m-%d %H');  

  

#结果:2016-01-02 00:00:00  


字符串转时间戳

select unix_timestamp('2016-01-02');  

  

#结果:1451664000  


时间戳转时间

select from_unixtime(1451997924);  

  

#结果:2016-01-05 20:45:24  


时间戳转字符串

select from_unixtime(1451997924,'%Y-%d');  

  

//结果:2016-01-05 20:45:24  


附表

MySQL日期格式化(format)取值范围。
 含义
%S、%s两位数字形式的秒( 00,01, ..., 59)
%I、%i两位数字形式的分( 00,01, ..., 59)
小时 %H24小时制,两位数形式小时(00,01, ...,23)
%h12小时制,两位数形式小时(00,01, ...,12)
%k24小时制,数形式小时(0,1, ...,23)
%l12小时制,数形式小时(0,1, ...,12)
%T24小时制,时间形式(HH:mm:ss)
%r 12小时制,时间形式(hh:mm:ss AM 或 PM)
%p AM上午或PM下午 
  周  %W一周中每一天的名称(Sunday,Monday, ...,Saturday)
 %a一周中每一天名称的缩写(Sun,Mon, ...,Sat) 
%w 以数字形式标识周(0=Sunday,1=Monday, ...,6=Saturday) 
%U数字表示周数,星期天为周中第一天
%u数字表示周数,星期一为周中第一天
%d 两位数字表示月中天数(01,02, ...,31)
%e  数字表示月中天数(1,2, ...,31)
 %D英文后缀表示月中天数(1st,2nd,3rd ...) 
 %j以三位数字表示年中天数(001,002, ...,366) 
%M 英文月名(January,February, ...,December) 
%b 英文缩写月名(Jan,Feb, ...,Dec) 
%m 两位数字表示月份(01,02, ...,12)
%c 数字表示月份(1,2, ...,12) 
%Y 四位数字表示的年份(2015,2016...)
%y  两位数字表示的年份(15,16...)
文字输出 %文字 直接输出文字内容
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐