【乾貨】MySQL數據庫開發規範

  1. 全部的數據庫對象名稱必須使用小寫字母並用下劃線分割(MySQL大小寫敏感,名稱要見名知意,最好不超過32字符)
  2. 全部的數據庫對象名稱禁止使用MySQL保留關鍵字(如 desc、range、match、delayed 等,請參考 MySQL官方保留字
  3. 臨時庫表必須以tmp爲前綴並以日期爲後綴(tmp_)
  4. 備份庫和庫必須以bak爲前綴並以日期爲後綴(bak_)
  5. 全部存儲相同數據的列名和列類型必須一致。(在多個表中的字段如user_id,它們類型必須一致)
  6. mysql5.5以前默認的存儲的引擎是myisam,沒有特殊要求,全部的表必須使用innodb(innodb好處支持失誤,行級鎖,高併發下性能更好,對多核,大內存,ssd等硬件支持更好)
  7. 數據庫和表的字符集儘可能統一使用utf8(字符集必須統一,避免因爲字符集轉換產生的亂碼,漢字utf8下佔3個字節)
  8. 全部表和字段都要添加註釋COMMENT,從一開始就進行數據字典的維護
  9. 儘可能控制單表數據量的大小在500w之內,超過500w可使用歷史數據歸檔,分庫分表來實現(500萬行並非MySQL數據庫的限制。過大對於修改表結構,備份,恢復都會有很大問題。MySQL沒有對存儲有限制,取決於存儲設置和文件系統)
  10. 謹慎使用mysql分區表(分區表在物理上表現爲多個文件,在邏輯上表現爲一個表)
  11. 謹慎選擇分區鍵,跨分區查詢效率可能更低
  12. 建議使用物理分表的方式管理大數據
  13. 儘可能作到冷熱數據分離,減少表的寬度(mysql限制最多存儲4096列,行數沒有限制,可是每一行的字節總數不能超過65535。列限制好處:減小磁盤io,保證熱數據的內存緩存命中率,避免讀入無用的冷數據)
  14. 禁止在表中創建預留字段(沒法確認存儲的數據類型,對預留字段類型進行修改,會對錶進行鎖定)
  15. 禁止在數據中存儲圖片,文件二進制數據(使用文件服務器)
  16. 禁止在線上作數據庫壓力測試
  17. 禁止從開發環境,測試環境直接連生產環境數據庫
  18. 限制每張表上的索引數量,建議單表索引不超過5個(索引會增長查詢效率,可是會下降插入和更新的速度)
  19. 避免創建冗餘索引和重複索引(冗餘:index(a,b,c) index(a,b) index(a))
  20. 禁止給表中的每一列都創建單獨的索引
  21. 每一個innodb表必須有一個主鍵,選擇自增id(不能使用更新頻繁的列做爲主鍵,不適用UUID,MD5,HASH,字符串列做爲主鍵)
  22. 區分度最高的列放在聯合索引的最左側
  23. 儘可能把字段長度小的列放在聯合索引的最左側
  24. 儘可能避免使用外鍵(禁止使用物理外鍵,建議使用邏輯外鍵)
  25. 優先選擇符合存儲須要的最小數據類型
  26. 優先使用無符號的整形來存儲
  27. 優先選擇存儲最小的數據類型(varchar(N),N表明的是字符數,而不是字節數,N表明能存儲多少個漢字)
  28. 避免使用Text或是Blob類型
  29. 避免使用ENUM數據類型(修改ENUM值須要使用ALTER語句,ENUM類型的ORDER BY操做效率低,須要額外操做,禁止使用書值做爲ENUM的枚舉值
  30. 儘可能把全部的字段定義爲NOT NULL(索引NULL須要額外的空間來保存,因此須要暫用更多的內存,進行比較和計算要對NULL值作特別的處理)
  31. 使用timestamp或datetime類型來存儲時間
  32. 同財務相關的金額數據,採用decimal類型(不丟失精度,禁止使用 float 和 double)
  33. 避免使用雙%號和like,搜索嚴禁左模糊或者全模糊(若是須要請用搜索引擎來解決。索引文件具備 B-Tree 的最左前綴匹配特性,若是左邊的值未肯定,那麼沒法使用此索)
  34. 建議使用預編譯語句進行數據庫操做
  35. 禁止跨庫查詢(爲數據遷移和分庫分表留出餘地,下降耦合度,下降風險)
  36. 禁止select * 查詢(消耗更多的cpu和io及網絡帶寬資源,沒法使用覆蓋索引)
  37. 禁止使用不含字段列表的insert語句(不容許insert into t values(‘a’,‘b’,‘c’)不容許)
  38. in 操做能避免則避免,若實在避免不了,須要仔細評估 in 後邊的集合元素數量,控制在 1000 個以內
  39. 禁止使用order by rand()進行隨機排序
  40. 禁止where從句中對列進行函數轉換和計算(例如:where date(createtime)=‘20160901’ 會沒法使用createtime列上索引。改爲 where createtime>='20160901' and createtime <'20160902')
  41. 儘可能使用 union all 代替 union
  42. 拆分複雜的大SQL爲多個小SQL( MySQL一個SQL只能使用一個CPU進行計算)
  43. 儘可能避免使用子查詢,能夠把子查詢優化爲join操做(子查詢的結果集沒法使用索引,子查詢會產生臨時表操做,若是子查詢數據量大會影響效率,消耗過多的CPU及IO資源)
  44. 超過100萬行的批量寫操做,要分批屢次進行操做(大批量操做可能會形成嚴重的主從延遲,binlog日誌爲row格式會產生大量的日誌,避免產生大事務操做)
  45. 對於大表使用pt—online-schema-change修改表結構(避免大表修改產生的主從延遲,避免在對錶字段進行修改時進行鎖表)
  46. 對於程序鏈接數據庫帳號,遵循權限最小原則
  47. 超過三個表禁止 join。(須要 join 的字段,數據類型必須絕對一致;多表關聯查詢時,保證被關聯的字段須要有索引。即便雙表 join 也要注意表索引、SQL 性能。)
  48. 在varchar字段上創建索引時,必須指定索引長度,不必對全字段創建索引,根據實際文本區分度決定索引長度便可。
  49. SQL 性能優化的目標:至少要達到 range 級別,要求是 ref 級別,若是能夠是 consts最好
  50. 使用 ISNULL()來判斷是否爲 NULL 值。
  51. 儘可能不要使用物理刪除(即直接刪除,若是要刪除的話提早作好備份),而是使用邏輯刪除,使用字段delete_flag作邏輯刪除,類型爲tinyint,0表示未刪除,1表示已刪除
  52. 若是有 order by 的場景,請注意利用索引的有序性。order by 最後的字段是組合,索引的一部分,而且放在索引組合順序的最後,避免出現 file_sort 的狀況,影響查詢性能。
  53. 在代碼中寫分頁查詢邏輯時,若 count 爲 0 應直接返回,避免執行後面的分頁語句

參考:html

  1. 《阿里巴巴Java開發手冊》
  2. 《高性能可擴展MySQL數據庫設計及架構優化 電商項目》

歡迎你們指出更正和補充!mysql

相關文章
相關標籤/搜索