Mysql範式與數據類型選擇

良好的邏輯設計與物理設計是高性能的基石,當我們在設計數據表結構的時候,應該跟根據業務邏輯來分析具體情況,然後設計出比較合理,高效的數據表結構

在數據表結構設計中,不得不提的就是範式數據類型

Mysql三範式

  • 字段不可分;即字段具有原子性 字段不可再分,否則就不是關係數據庫;
  • 有主鍵,非主鍵字段依賴主鍵; 唯一性 一個表只說明一個事物
  • 非主鍵字段不能相互依賴;每列都與主鍵有直接關係,不存在傳遞依賴
範式的優點與缺點
  • 優點

    • 範式化設計更新通常比反範式化更新要快
    • 當數據高度範式化時,就只有少量或者沒有重複數據,這樣修改的時候就只需要修改少量的數據
    • 範式化的表通常比較小,可以更好的放在內存裏面,操作就會更容易
    • 因爲範式化設計之後,冗餘數據較少,所以在執行某些查詢的時候可能就不會用到group bydistinct 這樣也提高了查詢效率
  • 缺點
    因爲嚴格遵循範式化設計的話。在某些業務場景下可能會查詢多個表。這樣的同樣會使得查詢效率變的很低。而且在某些時候因爲多表查詢的原因,可能某些索引不會被命中。

這裏我們看到範式化的設計有優點也有缺點,所以在實際的項目中,我們通常是混範式化設計。
某些表完全遵循範式化;某些表遵循部分範式化設計。在設計某些表的時候 會用到反範式化的思想,將某些數據存到同一張表中。這樣可以減少很多關聯查詢,也可以更好的去設計索引關係。

比如users表 與 user_messages表中,都會保存一個user_account_type字段。這樣的話,在單獨查詢user_account_type=1的消息總數時就不需要再去關聯users表了。

數據類型

Mysql支持的數據類型有很多種,所以選擇正確的數據類型對提高性能有着至關重要的作用。但是不管哪種數據類型我們都應該參考下面幾個原則

  • 更小的通常更好;更小的數據類型通常更快,因爲他們佔用更少的磁盤、內存、CPU緩存。
  • 簡單就好;操作簡單的數據類型通常需要更少的CPU週期。例如:整型比字符串操作代價更低
  • 儘量避免NULL;如果查詢中包含可爲Null的列,對於Mysql來說更難優化,因爲可以爲null的列使得索引,索引統計和值都變的更加複雜
整數類型

Mysql的整數類型有 TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT。他們使用到的儲存空間分別是,8,16,24,32,64位。值的範圍是-2(N-1)到2(N-1)-1
整形可以選擇UNSIGNED屬性,表示是否有符號,不允許爲負值。
如 TINYINT UNSIGNED 值的範圍 0~255, 而 TINYINT 值的範圍是-128-127。需要注意點是有符號跟無符號使用相同的儲存空間,擁有相同的性能,所以可以根據實際情況來選擇類型。

字符串類型

VARCHAR,CHAR是兩種最主要的字符串類型,

  • VARCHAR類型用於儲存可變字符串,是常見的字符串類型。它比定長類型更節省空間。
  • CHAR定長字符串類型,分配固定長度的空間。在保存某些定長字符串時比VARCHAR更有優勢、比如md5定長字符串,因爲定長類型字符串不容易產生碎片。
對於VARCHAR(5)VARCHAR(100)儲存hello的空間開銷是一樣的,那麼是不是我們就可以定義長度爲100呢?當然不是了,更長的列會消耗更多的內存,因爲Mysql通常會分配固定大小的內存塊來保存內部值。所以最好的策略就是分配合理的長度,這樣就分配到真正需要的 空間。
日期,時間類型
  • DATETIME類型,能夠保存1001-9999年,精度爲秒,與時區無關。
  • TIMESTAMP類型,保存了從1970-01-01午夜到現在的秒數,只使用了4個字節,只能表示1970-2038年。TIMESTAMP依賴於時區。TIMESTAMP在默認情況下,如果沒有指定列的值,會把列的值設置爲當前時間,在更新的時候也可以更新列的值爲當前時間。

通常情況下應該儘量使用TIMESTAMP,因爲它比DATETIME空間效率更高,有時候我們會將Unix時間戳保存爲整數值以表示當前時間,實際上並不會帶來任何收益。

上面列舉了幾個常用的mysql類型,在實際使用中可以根據業務選擇最優的方案。一般情況下遵循 更小的通常更好,簡單就好 ,儘量避免NULL是沒有問題的。

關於mysql的數據類型選擇,就寫到這裏。後面也會寫一些關於索引優化方面的文章,如果問題歡迎大家指出。
圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章