MySQL datetime類型詳解


研發反饋問題,數據庫中datetime數據類型存儲的值末尾會因四舍五入出現不一致數據,影響查詢結果,比如:程序中自動獲取帶毫秒精度的日期'2019-03-05 01:53:55.63',存入數據庫后變成'2019-03-05 01:53:56’。

拋出問題:

具體情況看例子:

mysql> create table t(id int,dt datetime);
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t values(1,'2019-03-05 01:53:55.63');
Query OK, 1 row affected (0.00 sec)

mysql> select * from t;
+------+---------------------+
| id | dt |
+------+---------------------+
| 1 | 2019-03-05 01:53:56 |
+------+---------------------+
1 row in set (0.00 sec)

問題好理解,數據庫自動對毫秒精度進行了四舍五入,取了個近似值。

解決問題:

問題也好解決:1.修改字段類型,給datetime加上精度,改成datetime(2),這樣就把后面的毫秒精度存進數據庫了,也不會出現查詢時數值錯誤;2.如果毫秒精度實際意義不大,可以在程序中截斷毫秒值,存入數據庫的值直接精確到秒,這樣數據庫層面不需要修改。

mysql> create table t_m(id int,dt datetime(2));
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t_m values(1,'2019-03-05 01:53:55.63');
Query OK, 1 row affected (0.00 sec)

mysql> select * from t_m;
+------+------------------------+
| id | dt |
+------+------------------------+
| 1 | 2019-03-05 01:53:55.63 |
+------+------------------------+
1 row in set (0.00 sec)

個人贊成第二種方法,因為架構定好后,不建議隨便修改底層數據庫,盡量從代碼層滿足需求,除非迫不得已。

問題延伸:

順便說一下datetime數據類型。

1.自動識別時間字符串  

查看數據庫默認日期類型格式:

mysql> show variables like 'datetime_format';
+-----------------+-------------------+
| Variable_name | Value |
+-----------------+-------------------+
| datetime_format | %Y-%m-%d %H:%i:%s |
+-----------------+-------------------+
1 row in set (0.00 sec)

默認格式是‘%Y-%m-%d %H:%i:%s’這樣的,一般寫入數據也是這種格式。

當寫入其他時間字符串時,只有數據庫能識別都會寫入成功,且是想要的數據;如果識別不了的時間值,會顯示成‘0000-00-00 00:00:00’。

mysql> insert into t values(3,'20191221010203');

mysql> select * from t;
+------+---------------------+
| id | dt |
+------+---------------------+
| 3 | 2019-12-21 01:02:03 |
+------+---------------------+

mysql> insert into t values(4,'2019/12/21/1/21/3');

mysql> select * from t;
+------+---------------------+
| id | dt |
+------+---------------------+
| 4 | 2019-12-21 01:21:03 |
+------+---------------------+

插入一個不存在的時間,會顯示出‘0000-00-00 00:00:00’,比如63秒

mysql> insert into t values(4,'2019/12/21/1/21/63');

mysql> select * from t;
+------+---------------------+
| id | dt |
+------+---------------------+
| 4 | 0000-00-00 00:00:00 |
+------+---------------------+

2.查詢時智能的補全模式

經常接到研發反饋,查一天的數據,查不出來,比如查詢‘2019-12-21’日期的全部數據,很多人在where條件中寫where dt = '2019-12-21',妄圖查出一天的數據。如果dt類型是date,會如常所願;如果是datetime或其他類型,恐怕要大失所望了,因為MySQL會對datetime值自動補零。

例子:

表中有3條數據:

mysql> select * from t;
+------+---------------------+
| id | dt |
+------+---------------------+
| 3 | 2019-12-21 01:02:03 |
| 4 | 2019-12-21 01:21:03 |
| 4 | 0000-00-00 00:00:00 |
+------+---------------------+

查詢‘2019-12-21’的數據:

mysql> select * from t where dt='2019-12-21';
Empty set (0.00 sec)

期望查到兩條數據,實際啥都沒查到,因為數據庫自動根據類型補全了0,實際查詢語句成了:select * from t where dt='2019-12-21 00:00:00';

對於datetime類型的值,想要查詢一天的數據,可以通過范圍查詢:between and(between and是左右閉合區間,兩邊數值都能查到) 。

mysql> select * from t where dt between '2019-12-21 00:00:00' and '2019-12-21 23:59:59';
+------+---------------------+
| id | dt |
+------+---------------------+
| 3 | 2019-12-21 01:02:03 |
| 4 | 2019-12-21 01:21:03 |
+------+---------------------+

3.其他

其它一些東西,比如和timestamp比較之類的,網上比較多,自行搜索。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM