MySQL 開發規範

Thurs發表於2020-05-01

排版規範(修復中)

TODO:
此文件遵循 中文排版指南 規範,並在此之上遵守以下約定:

  • 英文的左右保持一個空白,避免中英文字黏在一起;
  • 使用全形標點符號;
  • 嚴格遵循 Markdown 語法;
  • 原文中的雙引號(” “)請代換成中文的引號(「」符號怎麼打出來見 這裡);
  • 加亮」和「加粗」和「連結」都需要在左右保持一個空格。

一 基礎規範

1. 使用InnoDB儲存引擎

支援事務、行級鎖、併發效能更好,CPU 及記憶體快取頁優化得當,資源利用率更高

2. InnoDB表必須有主鍵列,使用auto_increment

主鍵遞增,資料行寫入可以提高插入效能,可以避免 page 分裂,減少表碎片,提升空間和記憶體的使用
主鍵要選擇較短的資料型別, Innodb 引擎普通索引都會儲存主鍵的值,較短的資料型別可以有效的減少索引的磁碟空間,提高索引的快取效率
無主鍵的表刪除,在 row 模式的主從架構,會導致備庫卡住
使用自增列(INT/BIGINT型別)做主鍵,這時候寫入順序是自增的,和B+數葉子節點分裂順序一致;
該表不指定自增列做主鍵,同時也沒有可以被選為主鍵的唯一索引(上面的條件),這時候InnoDB會選擇內建的ROWID作為主鍵,寫入順序和ROWID增長順序一致;
除此以外,如果一個InnoDB表又沒有顯示主鍵,又有可以被選擇為主鍵的唯一索引,但該唯一索引可能不是遞增關係時(例如字串、UUID、多欄位聯合唯一索引的情況),該表的存取效率就會比較差。

3. 資料庫字符集使用UTF8,校對字符集使用utf8_general_ci

相容性更好,統一字符集可以避免由於字符集轉換產生的亂碼,不同的字符集進行比較前需要進行轉換會造成索引失效

4. 所有表、欄位都儘量新增註釋

進行資料字典的維護

5. 庫名、表名、欄位名使用小寫字母,禁止超過32個字元,須見名知意

庫名、表名、欄位名支援最多64個字元,但為了統一規範、易於辨識以及減少傳輸量,禁止超過32個字元

6. 非唯一索引以 “idx_欄位1_欄位2” 命名,唯一索引必須以 “uniq_欄位1_欄位2” 命名

二 查詢規範

1. SQL語句儘可能簡單,拆分複雜SQL為多個小SQL,避免大事務

簡單的SQL容易使⽤用到MySQL的QUERY CACHE;減少鎖表時間特別是MyISAM;可以使用多核 CPU

2. 不要使用SELECT * ,查詢具體要用到的欄位
3. 禁止like '%*' 開頭的模糊查詢做where條件

無法使用索引,進行全表遍歷,非常耗時,效能極低

4. 避免使用負向查詢條件, NOT , != , <> , !< , !> , NOT IN , NOT LIKE

無法使用索引

5. Where條件裡不要對列使用函式或者表示式

無法使用索引

6. 能確定返回結果只有一條時,使用limit 1

(LIMIT分頁注意效率,LIMIT越大,效率越低)

7. 少用子查詢,改用JOIN

(子查詢要在記憶體裡建臨時表)

8. 多表JOIN的欄位,區分度最大的欄位放在前面
9. IN條件裡的資料數量要儘量少,超過200個用EXIST代替IN
10. Where字句中同一個表的不同欄位組合建議小於5組

該考慮分表了

11. 禁止單條語句同時更新多個表
12. 事務要儘量簡單,整個事務的時間長度不要太長

三 表設計規範

1. 用DECIMAL代替FLOATDOUBLE儲存精確浮點數

(精確資料)

2. 使用TINYINT代替ENUM型別

ENUM型別在需要修改或增加列舉值時,需要線上DDL,成本較高;ENUM列值如果含有數字型別,可能會引起預設值混淆

3. 儘可能不使用TEXTBLOB型別

(該資料型別不能設定預設值、不便於排序、不便於建立索引)

4. 同一意義的欄位設計定義必須相同

(便於聯表查詢)

5. 所有欄位均定義為NOT NULL

(避免使用NULL欄位,NULL欄位很難查詢優化,NULL欄位的索引需要額外空間,NULL欄位的複合索引無效)

6. 表必須有主鍵,不使用更新頻繁的列做主鍵、儘量不使用字串列做主鍵,儘量使用非空的唯一自增鍵做主鍵

四 索引設計規範

1. 單表索引數量不超過10個
2. 單個欄位不要超過兩個索引
3. 新建的唯一索引必須不能和主鍵重複
4. 避免冗餘和重複索引
5. 儘量不要在頻繁更新的列上建立索引
6. 不在低基數列上建立索引,例如狀態、型別等
7. 不在索引列進行數學運算和函式運算

(參與了運算的列不會引用索引)

8. 複合索引須符合最左字首的特點建立索引

(mysql使用複合索引時從左向右匹配)

9. 重要的SQL中where條件裡的欄位必須被索引
10. Where條件裡的欄位順序與索引順序無關,優化器會自動調整
11. 索引選擇性 = Cardinality / Total Rows,即基數 ÷ 資料行數,值越接近1說明使用索引的過濾效果越好
12. 建立索引時,務必先explain,檢視索引使用情況
本作品採用《CC 協議》,轉載必須註明作者和本文連結

Thurs

相關文章