規範在整個後端執行也有大半年的時間,對於整個團隊在開發階段就減小不恰當的建表語句、錯誤 SQL、錯誤的索引有積極的意義,故分享出來給你們參考。java
下邊分爲建表規約、SQL 規約、索引規約三個部分,每部分的每一條都有強制、建議兩個級別,你們在參考時,根據本身公司的狀況來權衡。數據庫
建表規約後端
【強制】:①存儲引擎必須使用 InnoDB緩存
解讀:InnoDB 支持事物、行級鎖、併發性能更好,CPU 及內存緩存頁優化使得資源利用率更高。服務器
【強制】:②每張表必須設置一個主鍵 ID,且這個主鍵 ID 使用自增主鍵(在知足須要的狀況下儘可能短),除非在分庫分表環境下微信
解讀:因爲 InnoDB 組織數據的方式決定了須要有一個主鍵,並且如果這個主鍵 ID 是單調遞增的能夠有效提升插入的性能,避免過多的頁分裂、減小表碎片提升空間的使用率。
併發
而在分庫分表環境下,則須要統一來分配各個表中的主鍵值,從而避免整個邏輯表中主鍵重複。app
【強制】:③必須使用 utf8mb4 字符集less
解讀:在 MySQL 中的 UTF-8 並不是「真正的 UTF-8」,而 utf8mb4」纔是真正的「UTF-8」。編輯器
【強制】:④數據庫表、表字段必須加入中文註釋
解讀:你們都別懶。
【強制】:⑤庫名、表名、字段名均小寫,下劃線風格,不超過 32 個字符,必須見名知意,禁止拼音英文混用
解讀:約定。
【強制】:⑥單表列數目必須小於 30,若超過則應該考慮將表拆分
解讀:單表列數太多使得 MySQL 服務器處理 InnoDB 返回數據之間的映射成本過高。
【強制】:⑦禁止使用外鍵,若是有外鍵完整性約束,須要應用程序控制
解讀:外鍵會致使表與表之間耦合,UPDATE 與 DELETE 操做都會涉及相關聯的表,十分影響 SQL 的性能,甚至會形成死鎖。
【強制】:⑧必須把字段定義爲 NOT NULL 而且提供默認值
解讀:
NULL 的列使索引/索引統計/值比較都更加複雜,對 MySQL 來講更難優化。
NULL 這種類型 MySQL 內部須要進行特殊處理,增長數據庫處理記錄的複雜性;同等條件下,表中有較多空字段的時候,數據庫的處理性能會下降不少。
NULL 值須要更多的存儲空,不管是表仍是索引中每行中的 NULL 的列都須要額外的空間來標識。
【強制】:⑨禁用保留字,如 DESC、RANGE、MARCH 等
解讀:請參考 MySQL 官方保留字。
這兩種類型的都能表達"yyyy-MM-dd HH:mm:ss"格式的時間,TIMESTAMP 只須要佔用 4 個字節的長度,能夠存儲的範圍爲(1970-2038)年,在各個時區,所展現的時間是不同的。
而 DATETIME 類型佔用 8 個字節,對時區不敏感,能夠存儲的範圍爲(1001-9999)年。
SQL 規約
【建議】:①爲了充分利用緩存,不容許使用自定義函數、存儲函數、用戶變量
解讀:若是查詢中包含任何用戶自定義函數、存儲函數、用戶變量、臨時表、MySQL 庫中的系統表,其查詢結果都不會被緩存。
好比函數 NOW() 或者 CURRENT_DATE() 會由於不一樣的查詢時間,返回不一樣的查詢結果。
讀取不須要的列會增長 CPU、IO、NET 消耗。
不能有效的利用覆蓋索引。
解讀:假設咱們在手機號列上添加了索引,而後執行下面的 SQL 會發生什麼?
explain SELECT user_name FROM parent WHERE phone=13812345678;很明顯就是索引不生效,會全表掃描。
索引規約
解讀:覆蓋查詢便是查詢只須要經過索引便可拿到所需 DATA,而再也不須要再次回表查詢,因此效率相對很高。
咱們在使用 EXPLAIN 的結果,extra 列會出現:"using index"。這裏也要強調一下不要使用「SELECT * 」,不然幾乎不可能使用到覆蓋索引。
解讀:索引的長度與區分度是一對矛盾體,通常對字符串類型數據,若長度爲 20 的索引,區分度會高達 90% 以上,則能夠考慮建立長度例爲 20 的索引,而非全字段索引。
例如可使用 SELECT COUNT(DISTINCT LEFT(lesson_code, 20))/COUNT(*) FROM lesson;來肯定 lesson_code 字段字符長度爲 20 時文本區分度。
【建議】:⑦若是有 ORDER BY 的場景,請注意利用索引的有序性
ORDER BY 最後的字段是聯合索引的一部分,而且放在索引組合順序的最後,避免出現 file_sort 的狀況,影響查詢性能。
假設有查詢條件爲 WHERE a=? and b=? ORDER BY c;存在索引:a_b_c,則此時能夠利用索引排序。
反例:在查詢條件中包含了範圍查詢,那麼索引有序性沒法利用,如:WHERE a>10 ORDER BY b;索引 a_b 沒法排序。
《High.Performance.MySQL.3rd.Edition》
《阿里巴巴java開發手冊》
做者:浮雷
編輯:陶家龍
出處:https://juejin.im/post/6871969929365553165
更多好文敬請關注公衆號
本文分享自微信公衆號 - JAVA開發者課堂(leechence)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。