聊一聊數據庫(MySQL)設計中的數據類型優化

良好的邏輯設計和物理設計事高性能的基石,在進行數據庫設計時,咱們應該要考慮到將來將會執行的查詢語句,這就須要對各類因素進行權衡。本文將會聊一聊數據庫(MySQL)設計中有關數據類型優化的一些內容。如下內容總結自《高性能 MysQL》。數據庫

選擇優化的數據類型

原則

咱們知道 MySQL 支持多種數據類型,一般狀況下,不少數據類型均可以完成相同的工做,選擇正確的數據類型對於高性能相當重要。在明確須要優化的數據類型前,咱們須要先掌握幾個原則,這些原則有助於咱們做出更好的選擇。服務器

  • 選擇相對輕量的數據類型

這裏的輕量指的是,在通常狀況下,應該使用能夠正確存儲數據的最小數據類型。例如一個列中的最大值爲 2020,那就不必選擇 INT 以及更大的數據類型。微信

  • 簡單就好

簡單的數據類型一般意味着處理時須要更少的 CPU 週期。例如,整型比字符操做代價更低;存儲日期/時間應該用內置的數據類型而不是字符串;存儲 IP 地址時應該用整型而不是字符串。數據庫設計

  • 避免 NULL

一般狀況下,應該設置列爲 NOT NULL。由於 NULL 會使某個列的索引、值等數據的處理變得複雜。並且可爲 NULL 的列會使用更多的存儲空間。工具

針對具體的數據類型

整數類型

對於整數,可選的數據類型有 TINYINT、SMALLINT、MEDIUMINT、INT 和 BIGINT。分別使用 八、16,24,32,64 位存儲空間。同時可選的屬性有UNSIGNED,表示不容許有負值,這可讓正數的上限提升一倍。例如 TINYINT 的存儲範圍是-128~127,TINYINT UNSIGNED 的存儲範圍是0~255性能

MySQL 能夠爲整數類型制定寬度,例如 INT(11),可是並不會限制數值的合法範圍,只會控制某些交互工具用來顯示字符的個數,對於存儲和計算來講,INT(1)和 INT(20)是相同的。即括號中的數字只是用於控制顯示的字符數,和實際能夠存儲的字符數無關。優化

實數類型

實數是帶有小數部分的數字,MySQL 中使用 DECIMAL 類型用於存儲精確的小數,可是 CPU 不支持對 DECIMAL 的直接計算,所以 MySQL 服務器自身實現了 DECIMAL 的高精度計算。設計

與此同時 CPU 支持原生浮點計算,所以浮點數的運算速度相對 DECIMAL 會更快。浮點分爲兩種:FLOAT 和 DOUBLE。因爲 DOUBLE 相對於 FLOAT 有更高的精度和更大的範圍,MySQL 使用 DOUBLE 做爲內部浮點計算的類型。code

由於須要額外的空間和計算開銷,因此應該儘可能只在對小數進行精確計算時才使用 DECIMAL,例如財務數據。數據量較大時,也能夠考慮使用 BIGINT 代替 DECIMAL,將須要存儲的貨幣單位根據小數的位數乘以相應的倍數便可。cdn

字符串類型

經常使用的是 VARCHAR 和 CHAR

VARCHAR

  • 存儲可變長字符串
  • 比定長類型省空間,越短的字符串使用空間越少
  • 使用 1 或 2 個額外字節記錄字符串的長度。列的最大長度小於或等於 255 字節,使用 1 個字節表示,不然使用 2 個字節表示

CHAR

  • 存儲定長字符串
  • 對於常常變動的數據,使用 CHAR 存儲不易產生碎片

所以兩者的使用場景也很明顯:

VARCHAR 適合字符串列的最大長度比平均長度大不少,同時列的更新不多,以及列中的字符串使用複雜的字符集,每一個字符都使用不一樣的字節數進行存儲(UTF-8)。

CHAR 適合存儲很短的字符串,或者全部值都接近同一個長度,例如存儲密碼的 MD5 值,或者用 CHAR(1)存儲只有 Y 和 N 的值,由於 CHAR(1)須要一個字節,VARCHAR(1)須要兩個字節(須要一個記錄長度的額外字節)。

日期和時間

DATETIME

  • 能夠保存從 1001 年到 9999 年,精度爲秒
  • 將日期和時間封裝到格式爲 YYYYMMDDHHMMSS 的整數中,與時區無關。
  • 使用 8 個字節的存儲空間

TIMESTAMP

  • 保存了從 1970 年 1 月 1 日午夜以來的秒數
  • 只使用 4 個字節存儲,所以範圍會小不少(最多表示從 1970 年到 2038 年)
  • 和時區有關

由於 TIMESTAMP 是用 4 個字節存儲,所以最多隻能保存到 2038 年,這一點也形成了很是著名的2038 年問題

選擇標識符

標識符是用於標識列與其餘值進行比較(例如關聯操做中,經過標識列尋找其餘列),標識列在選擇數據類型時,應該跟關聯表中的對應列同樣的類型。

整數類型一般是最好的選擇,效率高且能夠自增加(例如主鍵)。若是能夠,儘可能避免使用字符串做爲標識列,消耗空間,且查詢速度慢。

特殊數據

有些特殊的數據須要用一些數據類型專門存儲,例如存儲 IP 地址應該用無符號整數,由於 IP 地址本質上是 32 位無符號數,並非字符串,用小數點將地址分紅四段只是方便閱讀。

總結

想要提升 MySQL 的效率,能夠作的功課很是多,數據庫的數據類型優化也只是其中很小的一點,本文也只是挑出了經常使用的數據類型進行介紹。有興趣的能夠仔細閱讀《高性能 MySQL》這本書,你能夠在微信公衆號「01 二進制」後臺回覆「高性能 MySQL」獲取本書。

大道至簡,儘量將事情保持簡單老是好的,MySQL 喜歡簡單,但願使用數據庫的你也會喜歡簡單。


相關文章
相關標籤/搜索