https://blog.csdn.net/weixin_39933082/article/details/111688895
前言
從7月份畢業開始算起,也是將近有5個月的工作經驗了吧。在工作上,經歷了一段時間的適應,現在接觸到不同大神寫出來的代碼,發現各有優劣,於是就在思考一個問題,什么樣的代碼才是最正常最規范的呢?我的同事甩給我了一本《阿里巴巴Java開發手冊》,從頭到尾也算是過了一遍。今天趁着雙休的假期,我就來講一下這本書里面的MySQL規范制約吧~~~
建表規約
1、【強制】每張表必須設置一個主鍵ID,並且這個主鍵ID要自增(在滿足需要的情況下盡量短),除非是分庫分表
理解:由於InnoDB存儲引擎決定了需要有一個主鍵,而且這個主鍵ID是自增的話可以有效提高插入的性能,避免過多的頁分裂,減少表碎片提高空間的利用率。
但是在分庫分表下,會有分片規則,這個時候需要統一分配各個表中的主鍵值,從而避免整個邏輯表中主鍵重復,一般我們會使用雪花ID來實現。
2、【強制】必須使用utf8mb4字符集
理解:在MySQL中的UTF-8並非是真正的"UTF-8",而utf8mb4才是真正的"UTF-8"。
3、【強制】數據庫表、表字段必須加入中文注釋
理解:程序員都不要給我懶,這樣可以讓后來者更好的上手和理解。
4、【強制】庫名、表名、字段名必須小寫,下划線風格,不超過32個字符,必須見名知意,禁止拼音英文混用
理解:在linux環境下MySQL是區分大小寫的,而在windows是不區分大小寫的,所以統一使用小寫+下划線可以避免不必要的混淆。
5、【強制】單表列數目必須小於30,若超過則應該考慮將表拆分
理解:單表列數太多會使得MySQL處理InnoDB返回數據之間的映射成本太高。
6、【強制】禁止使用外鍵,如果有外鍵完整性約束,需要應用程序控制
理解:外鍵會導致表與表之間耦合,UPDATE與DELETE操作都會涉及相關聯的表,十分影響SQL的性能,甚至會造成死鎖。
7、【強制】必須把字段定義為NOT NULL並且提供默認值
理解:NULL需要更多的存儲空,無論是表還是索引中每行中的NULL的列都需要額外的空間來標識。NULL這種類型需要MySQL內部進行特殊處理,增加了數據庫處理記錄的復雜性,同等條件下,表中較多NULL字段會導致數據庫處理性能下降。
8、【強制】禁止使用保留字,如DESC、RANGE、MAX等
理解:請參考MySQL官方保留字。
9、【強制】如果存儲的字符串長度幾乎相等,使用CHAR定長字符串類型
理解:能夠減少空間碎片,節省存儲空間。
10、【強制】小數類型為 decimal,禁止使用 float 和 double
理解:float 和 double 在存儲的時候,存在精度損失的問題,很可能在值的比較時,得到正確的結果。如果存儲的數據范圍超過 decimal 的范圍,建議將數據拆成整數和小數分開存儲。
11、【強制】表必備三字段:id, gmt_create, gmt_modified。
理解:其中 id 必為主鍵,類型為 bigint unsigned、單表時自增、步長為 1。gmt_create,gmt_modified 的類型均為 datetime 類型,前者現在時表示主動創建,后者過去分詞表示被動更新。
12、【推薦】在一些場景下,考慮使用TIMESTAMP代替DATETIME
理解:TIMESTAMP可以表達1970-2038年,而且TIMESTAMP需要4字節存儲空間,而DATETIME需要8字節,存儲1001-9999年
13、【推薦】對於自動生成的schema不要太過信任,最好自己手動寫
理解:對於一些數據庫客戶端不要過分信任。
索引規約
1、【強制】業務上具有唯一特性的字段,即使是多個字段的組合,也必須建成唯一索引
理解:不要以為唯一索引影響了 insert 速度,這個速度損耗可以忽略,但提高查找速度是明顯的;另外,即使在應用層做了非常完善的校驗控制,只要沒有唯一索引,根據墨菲定律,必然有臟數據產生。
2、【強制】超過三個表禁止 join。需要 join 的字段,數據類型必須絕對一致;多表關聯查詢時,保證被關聯的字段需要有索引
理解:多表的join操作會影響SQL的性能
3、【強制】在 varchar 字段上建立索引時,必須指定索引長度,沒必要對全字段建立索引,根據實際文本區分度決定索引長度即可
理解:索引的長度與區分度是一對矛盾體,一般對字符串類型數據,長度為 20 的索引,區分度會高達 90%以上,可以使用 count(distinct left(列名, 索引長度))/count(*)的區分度來確定。
4、【強制】頁面搜索嚴禁左模糊或者全模糊,如果需要請走搜索引擎來解決
理解:索引文件具有 B-Tree 的最左前綴匹配特性,如果左邊的值未確定,那么無法使用此索引。
5、【推薦】如果有 order by 的場景,請注意利用索引的有序性。order by 最后的字段是組合索引的一部分,並且放在索引組合順序的最后,避免出現 file_sort 的情況,影響查詢性能
理解:組合索引的順序會影響到SQL的查詢性能
6、【推薦】利用覆蓋索引來進行查詢操作,避免回表
理解:覆蓋索引只需要通過索引即可拿到所需的數據,而不再需要再次回表查詢,提高了SQL的查詢效率。
7、【推薦】利用延遲關聯或者子查詢優化超多分頁場景
理解:MySQL 並不是跳過 offset 行,而是取 offset+N 行,然后返回放棄前 offset 行,返回N 行,那當 offset 特別大的時候,效率就非常的低下,要么控制返回的總頁數,要么對超過特定閾值的頁數進行 SQL 改寫。
8、【推薦】建組合索引的時候,區分度最高的在最左邊
理解:區分度最高的放左邊,能夠在一開始過濾掉很多無用數據,提高索引的效率。需要注意的是各個條件的順序盡量和索引的順序一致。
9、【推薦】防止因字段類型不同造成的隱式轉換,導致索引失效
理解:詳細細節可以參考這篇文章哦~~~
god-jiang:MySQL索引(三)索引不生效的情況zhuanlan.zhihu.com
SQL規約
1、【強制】不要使用 count(列名)或 count(常量)來替代 count(*),count(*)是 SQL92 定義的標准統計行數的語法,跟數據庫無關,跟 NULL 和非 NULL 無關
理解:count(*)會統計值為 NULL 的行,而 count(列名)不會統計此列為 NULL 值的行。
2、【強制】使用 ISNULL()來判斷是否為 NULL 值
理解:NULL與任何值直接比較都為NULL。
NULLNULL返回結果是NULL,而不是false。
NULL=NULL返回結果是NULL,而不是false。
NULL1返回結果是NULL,而不是true。
3、【強制】在代碼中寫分頁查詢邏輯時,若 count 為 0 應直接返回,避免執行后面的分頁語句
理解:提高SQL的效率,避免不必要的無用查詢。
4、【強制】不得使用外鍵與級聯,一切外鍵概念必須在應用層解決
理解:外鍵會導致表與表之間耦合,UPDATE與DELETE操作都會涉及相關聯的表,十分影響SQL的性能,甚至會造成死鎖。
5、【強制】禁止使用存儲過程,存儲過程難以調試和擴展,更沒有移植性
理解:避免不必要的維護。
6、【推薦】TRUNCATE TABLE 比 DELETE 速度快,且使用的系統和事務日志資源少,但 TRUNCATE無事務且不觸發 trigger,有可能造成事故,故不建議在開發代碼中使用此語句。
理解:TRUNCATE TABLE 在功能上與不帶 WHERE 子句的 DELETE 語句相同。
參考
《阿里巴巴Java開發手冊》
————————————————
版權聲明:本文為CSDN博主「weixin_39933082」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_39933082/article/details/111688895
