MySQL中儲存時間的最佳實踐指南

2022-09-21 16:27:12 字數 2059 閱讀 7479

目錄

平時開發中經常需要記錄時間,比如用於記錄某條記錄的建立時間以及修改時間。在資料庫中儲存時間的方式有很多種,比如 mysql 本身就提供了日期型別,比如 datetime,timestamep 等,我們也可以直接儲存時間戳為 int 型別,也有人直接將時間儲存為字串型別。

那麼到底哪種儲存時間的方式更好呢?

這是初學者很容易犯的錯誤,容易直接將字段設定為 varchar 型別,儲存"2021-01-01 00:00:00"這樣的字串。當然這樣做的優點是比較簡單,上手快。

但是極力不推薦這樣做,因為這樣做有兩個比較大的問題:

mysql 資料庫中常見的日期型別有 year、date、time、datetime、timestamep。因為一般都需要將日期精確到秒,其中比較合適的有datetime,timestamep。

datetime 在資料庫中儲存的形式為:yyyy-mm-dd hh:mm:ss,固定占用 8 個位元組。

從 mysql 5.6 版本開始,datetime 型別支援毫秒,datetime(n) 中的 n 表示毫秒的精度。例如,datetime(6) 表示可以儲存 6 位的毫秒值。

timestamp 實際儲存的內容為『1970程式設計客棧-01-01 00:00:00'到現在的毫秒數。在 mysql 中,由於型別 timestamp 占用 4 程式設計客棧個位元組,因此其儲存的時間上限只能到『2038-01-19 03:14:07'。

從 mysql 5.6 版本開始,型別 timestamp 也能支援毫秒。與 datetime 不同的是,若帶有毫秒時,型別 timestamp 占用 7 個位元組,而 datetime 無論是否儲存毫秒資訊,都占用 8 個位元組。

型別 timestamp 最大的優點程式設計客棧是可以帶有時區屬性,因為它本質上是從毫秒轉化而來。如果你的業務需要對應不同的國家時區,那麼型別 timestamp 是一種不錯的選擇。比如新聞類的業務,通常使用者想知道這篇新聞發布時對應的自己國家時間,那麼 timestamp 是一種選擇。timestamp 型別欄位的值會隨著伺服器時區的變化而變化,自動換算成相應的時間,說簡單點就是在不同時區,查詢到同乙個條記錄此字段的值會不一樣。

timestamp 還存在潛在的效能問題。

雖然從毫秒數轉換到型別 timestamp 本身需要的 cpu 指令並不多,這並不會帶來直接的效能問題。但是如果使用預設的作業系統時區,則每次通過時區計算時間時,要呼叫作業系統底層系統函式 __tz_convert(),而這個函式需要額外的加鎖操作,以確保這時作業系統時區沒有修改。所以,當大規模併發訪問時,由於熱點資源競爭,會產生兩個問題:

為了優化 timestamp 的使用,建議使用顯式的時區,而不是作業系統時區。比如在配置檔案中顯示地設定時區,而不要使用系統時區:

程式設計客棧[mysqld]

time_zone = "+08:00"

簡單總結一下這兩種資料型別的優缺點:

很多時候,我們也會使用 int 或者 bigint 型別的數值也就是時間戳來表示時間。

程式設計客棧這種儲存方式的具有 timestamp 型別的所具有一些優點,並且使用它的進行日期排序以及對比等操作的效率會更高,跨系統也很方便,畢竟只是存放的數值。缺點也很明顯,就是資料的可讀性太差了,你無法直觀的看到具體時間。

如果需要檢視某個時間段內的資料

select * from t where created_at > unix_timestamp('2021-01-01 00:00:00');

每種方式都有各自的優勢,下面再對這三種方式做乙個簡單的對比:

日期型別

占用空間

日期格式

日期範圍

是否存在時區問題

datetime

8 位元組

yyyy-mm-dd hh:mm:ss

1000-01-01 00:00:00 ~9999-12-31 23:59:59

是timestamp

4 位元組

yyyy-mm-dd hh:mm:ss

1970-01-01 00:00:00 ~2038-01-19 03:14:07

否int

4 位元組

全數字時間戳

1000-01-01 00:00:01 之後的時間

mysql中儲存過程

delimiter,簡單解釋下這個命令的用途,在mysql中每行命令都是用 結尾,回車後自動執行,在儲存過程中 往往不代表指令結束,馬上執行,而delimiter原本就是 的意思,因此用這個命令轉換一下 為 這樣只有收到 才認為指令結束可以執行 檢視myql中已經存在的儲存過程 show proce...

mysql中儲存過程

儲存過程,其本質還是函式 但其規定 不能有返回值 說明 1,in 用於設定該變數是用來 接收實參資料 的,即 傳入 預設不寫,就是in 2,out 用於設定該變數是用來 儲存儲存過程中的資料 的,即 傳出 即函式中必須對它賦值 3,inout 是in和out的結合,具有雙向作用 4,對於,out和i...

mysql中儲存過程學習

例項 獲取登入 登出 操作日誌 命令日誌 從系統日誌表查詢,命令日誌表查詢結過儲存到臨時表中,得到所有的日誌,然後按條件進行篩選 create function getlog uname varcharacter 200 starttime datetime,endtime datetime,log...