java面試(4)SQL軍規

注:軍規主要適用於那些大企業,有着併發量大、數據量大的互聯網業務。這類業務架構設計的重點往往是吞吐量,性能優先,對數據庫性能影響較大的數據庫特性較少使用。這類場景的架構方向是“解放數據庫CPU,把複雜邏輯計算放到服務層”,服務層具備更好的擴展性,容易實現“增機器就擴充性能”,數據庫擅長存儲與索引,勿讓數據庫揹負過重的任務。

  1. 必須使用UTF8字符集,新庫默認使用utf8mb4字符集。utf8mb4是utf8的超集,emoji表情以及部分不常見漢字在utf8下會表現爲亂碼,故需要升級至utf8mb4。默認使用這個字符集的原因是:“標準,萬國碼,無需轉碼,無亂碼風險”,並不“節省空間”。

  2. 數據表、數據字段必須加入中文註釋

  3. 禁止使用外鍵,如果有外鍵完整性約束,需要應用程序控制:外鍵會導致表與表之間耦合,update與delete操作都會涉及相關聯的表,十分影響sql 的性能,甚至會造成死鎖。高併發情況下容易造成數據庫性能,大數據高併發業務場景數據庫使用以性能優先

  4. 禁止大表使用JOIN查詢,禁止大表使用子查詢

  5. 只允許使用內網域名,而不是ip連接數據庫。不只是數據庫,緩存(memcache、redis)的連接,服務(service)的連接都必須使用內網域名,機器遷移/平滑升級/運維管理…太多太多的好處,如果朋友你還是採用ip直連的,趕緊升級到內網域名吧。

  6. 禁止使用小數存儲貨幣,建議使用整數存儲,小數容易獲取導致錢對不上

  7. 禁止使用負向查詢NOT、!=、<>、!<、!>、NOT IN、NOT LIKE等,以及%開頭的模糊查詢,會導致全表掃描。 
    一般來說,WHERE過濾條件不會只帶這麼一個“負向查詢條件”,還會有其他過濾條件,舉個例子:查詢沈劍已完成訂單之外的訂單(好拗口): 
    SELECT oid FROM t_order WHERE uid=123 AND status != 1; 
    訂單表5000w數據,但uid=123就會迅速的將數據量過濾到很少的級別(uid建立了索引),此時再接上一個負向的查詢條件就無所謂了,掃描的行數本身就會很少。 
    但如果要查詢所有已完成訂單之外的訂單: 
    SELECT oid FROM t_order WHERE status != 1; 
    這就掛了,立馬CPU100%,status索引會失效,負向查詢導致全表掃描。

  8. 禁止使用應用程序配置文件內的帳號手工訪問線上數據庫

  9. 禁止非DBA對線上數據庫進行寫操作,修改線上數據需要提交工單,由DBA執行,提交的SQL語句必須經過測試

  10. 分配非DBA以只讀帳號,必須通過VPN+跳板機訪問授權的從庫

  11. 開發、測試、線上環境隔離

  12. 必須使用InnoDB存儲引擎:支持事務、行級鎖、併發性能更好、CPU及內存緩存頁優化使得資源利用率更高

  13. 禁止存儲大文件或者大照片:爲何要讓數據庫做它不擅長的事情?大文件和照片存儲在文件系統,數據庫裏存URI多好

  14. 線上環境、開發環境、測試環境數據庫內網域名遵循命名規範(自己的命名規範)

  15. 庫名、表名、字段名:小寫,下劃線風格,不超過32個字符,必須見名知意,禁止拼音英文混用

  16. 表名t_xxx,非唯一索引名idx_xxx,唯一索引名uniq_xxx

  17. 單實例表數目必須小於500

  18. 單表列數目必須小於30(這個數目看業務,不過一般不會太多)

  19. 表必須有主鍵,例如自增主鍵

  20. 必須把字段定義爲NOT NULL並且提供默認值

  21. 禁止使用TEXT、BLOB類型

  22. 必須使用varchar(20)存儲手機號

  23. 禁止使用ENUM,可使用TINYINT代替:增加新的ENUM值要做DDL操作;ENUM的內部實際存儲就是整數,你以爲自己定義的是字符串?

  24. 單表索引建議控制在5個以內

  25. 單索引字段數不允許超過5個

  26. 禁止在更新十分頻繁、區分度不高的屬性上建立索引

  27. 建立組合索引,必須把區分度高的字段放在前面:能夠更加有效的過濾數據

  28. 禁止使用SELECT *,只獲取必要的字段,需要顯示說明列屬性

  29. 禁止使用INSERT INTO t_xxx VALUES(xxx),必須顯示指定插入的列屬性:容易在增加或者刪除字段後出現程序BUG

  30. 禁止使用屬性隱式轉換:SELECT uid FROM t_user WHERE phone=13812345678 會導致全表掃描,而不能命中phone索引

  31. 禁止在WHERE條件的屬性上使用函數或者表達式

  32. 應用程序必須捕獲SQL異常,並有相應處理

  33. 禁止使用OR條件,必須改爲IN查詢,in的個數建議控制在200以內:舊版本Mysql的OR查詢是不能命中索引的,即使能命中索引,爲何要讓數據庫耗費更多的CPU幫助實施查詢優化呢?

  34. 不在數據庫做運算:cpu計算務必移至業務層

  35. 控制單表數據量:單表記錄控制在1000w

  36. 平衡範式與冗餘:爲提高效率犧牲範式設計,冗餘數據

  37. 拒絕3B:拒絕大sql,大事物,大批量

  38. 字符轉化爲數字

  39. sql語句儘可能簡單:一條sql只能在一個cpu運算;大語句拆小語句,減少鎖時間;一條大sql可以堵死整個庫

  40. 簡單的事務:事務時間儘可能短

  41. limit高效分頁:limit越大,效率越低

  42. 少用連接join

  43. 使用load data導數據:load data比insert快約20倍;

  44. 打散批量更新

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