一起因MySQL時間戳精度引發的血案分析

2022-09-28 20:15:17 字數 1481 閱讀 6867

寫www.cppcns.com在前面

最近工作中遇到兩例mysql時間戳相關的問題,乙個是mysql-connector-j**a和msyql的精度不一致導致資料查不到;另一例是應用伺服器時區錯誤導致資料查詢不到。通過這篇文章,希望能夠解答關於mysql中時間戳的幾個問題:

案例分析 datetime的精度問題

前段時間,將負責的應用的mysql-connector-j**a的版本從5.1.16公升級到5.1.30,在做功能回歸的時候發現,使用了類似上面的sql的用例的執行時資料會有遺漏,導致功能有問題。

考慮到我負責的應用中,有個功能需要用到類似下面這種sql,即使用時間戳作為查詢的條件,查詢在某個時間戳之後的所有資料。

經過排查發現:mysql-connector-j**a在5.1.23之前會將秒後面的精度丟棄再傳給mysql服務端,正好我們使用的mysql版本中datetime的精度是秒;在我將mysql-connector-j**a公升級到5.1.30後,從j**a應用通過mysql-connector-j**a將時間戳傳到mysql服務端的時候,就不會將毫秒數丟棄了,從mysql-connector-j**a的角度看是修復了乙個bug,但是對於我的應用來說卻是觸發了乙個bug。

如果你面對這個問題,你會怎麼修復呢?

我們當時想了三種方案:

經過驗證,方案1會,j**a.util.date轉過去的j**a.sql.date物件會將日期之後的精度全部丟掉,從而導致查詢出更多不必要的資料;方案3是可以的,就是可能會查出多一兩條資料;方案2也是可以的,相當於從**上對mysql-connector-j**a的特性做了補償。最終我選擇的是方案2。

案例復現

利用homebrew安裝mysql,版本是8.0.15,裝好後建乙個表,用來存放使用者資訊,sql如下:

使用spirngboot + mybatis作為開發框架,定義乙個使用者實體,**如下所示:

定義該實體對應的mapper,**如下:

設定連線mysql相關的配置,**如下:

編寫測試**,先插入一條資料,然後用時間戳作為查詢條件去查詢,**如下:

執行單測,如我們的設想,確實是沒有查詢出資料來,結果如下:

然後修改**,利用上面的**將查詢的時間戳按秒取正,**如下:

再次執行單測,如我們的設想,這次可以查詢出資料來了。

不過,這裡有個小插曲,我在最開始設計表的時候,使用的sql語句是下面這樣的,

聰明如你一定發現了,這裡的datetime已經支援小數點後更小的時間精度了,最多支援6位即最多可以支援到微妙級別。這個特性是什麼時候引入的呢,我去查閱了[mysql的官方文件][9],發現這個特性是在mysql 5.6.4之後開始支援的。

知識點總結

經過了前面的實際案例分析和案例復現,想必讀者已經對mysql中datetime這個型別有了一定的認識,接下來跟我一起看下,我們從這個案例中可以總結出哪些經驗。

datetime

參考資料

總結本文標題: 一起因mysql時間戳精度引發的血案分析

本文位址:

Mysql 時間戳未設定精度引發的血案

使用mysql少不了日期型別 平時直接用預設的配置 沒想到出現了修改完一條記錄後記錄數少一的情況.簡單翻譯下 發生了一次update 影響1行 一次select 結果兩行,update之前為3行 第一次update時候想把updatetime設定為2019 09 29 14 05 10.749 由於...

與Apache一起使用MySQL

還有一些專案,你可以從mysql資料庫鑑別使用者,並且你還可以將日誌檔案寫入mysql資料庫表。你可以將以下內容放到apache配置檔案中,更改apache日誌格式,使mysql更容易讀取 logformat h t,s,b o u i i 要想將該格式的日誌檔案裝載到mysql,你可以使用以下語句...

跟我一起學 PostgreSQL 之 時間相關

select to char current date,yyyy 為 character varying格式型別 select extract year from now 為double precision 格式型別 select to char select now timestamp yyyy ...