基礎規(guī)范
- 表存儲引擎必須使用
InnoDB
- 表字符集默認使用
utf8
狈网,必要時候使用utf8mb4
- 通用搜贤,無亂碼風險掖举,漢字 3 字節(jié)包券,英文 1 字節(jié)
-
utf8mb4
是utf8
的超集,有存儲 4 字節(jié)例如表情符號時株旷,使用它
- 禁止使用存儲過程再登,視圖,觸發(fā)器晾剖,Event
- 對數(shù)據(jù)庫性能影響較大锉矢,互聯(lián)網(wǎng)業(yè)務,能讓站點層和服務層干的事情齿尽,不要交到數(shù)據(jù)庫層
- 調(diào)試沽损,排錯,遷移都比較困難循头,擴展性較差
- 禁止在數(shù)據(jù)庫中存儲大文件绵估,例如照片,可以將大文件存儲在對象存儲系統(tǒng)卡骂,數(shù)據(jù)庫中存儲路徑
- 禁止在線上環(huán)境做數(shù)據(jù)庫壓力測試
- 測試国裳,開發(fā),線上數(shù)據(jù)庫環(huán)境必須隔離
命名規(guī)范
- 庫名全跨,表名缝左,列名必須用小寫,采用下劃線分隔
- abc浓若,Abc渺杉,ABC 都是給自己埋坑
- 庫名,表名挪钓,列名必須見名知義是越,長度不要超過 32 字符
- tmp,wushan 誰 TM 知道這些庫是干嘛的
- 庫備份必須以 bak 為前綴诵原,以日期為后綴
- 從庫必須以
-s
為后綴 - 備庫必須以
-ss
為后綴
表設計規(guī)范
- 單實例表個數(shù)必須控制在
2000
個以內(nèi) - 單表分表個數(shù)必須控制在
1024
個以內(nèi) - 表必須有主鍵英妓,推薦使用
UNSIGNED
整數(shù)為主鍵- 刪除無主鍵的表挽放,如果是
row
模式的主從架構(gòu)绍赛,從庫會掛住
- 刪除無主鍵的表挽放,如果是
- 禁止使用外鍵蔓纠,如果要保證完整性,應由應用程式實現(xiàn)
- 外鍵使得表之間相互耦合吗蚌,影響
update/delete
等 SQL 性能腿倚,有可能造成死鎖,高并發(fā)情況下容易成為數(shù)據(jù)庫瓶頸
- 外鍵使得表之間相互耦合吗蚌,影響
- 建議將大字段蚯妇,訪問頻度低的字段拆分到單獨的表中存儲敷燎,分離冷熱數(shù)據(jù)(具體參考:《如何實施數(shù)據(jù)庫垂直拆分》)
列設計規(guī)范
- 根據(jù)業(yè)務區(qū)分使用
tinyint/int/bigint
,分別會占用1/4/8
字節(jié) - 根據(jù)業(yè)務區(qū)分使用
char/varchar
- 字段長度固定箩言,或者長度近似的業(yè)務場景硬贯,適合使用
char
,能夠減少碎片陨收,查詢性能高 - 字段長度相差較大饭豹,或者更新較少的業(yè)務場景,適合使用
varchar
务漩,能夠減少空間
- 字段長度固定箩言,或者長度近似的業(yè)務場景硬贯,適合使用
- 根據(jù)業(yè)務區(qū)分使用
datetime/timestamp
- 前者占用 5 個字節(jié)拄衰,后者占用 4 個字節(jié),存儲年使用
YEAR
饵骨,存儲日期使用DATE
翘悉,存儲時間使用datetime
- 前者占用 5 個字節(jié)拄衰,后者占用 4 個字節(jié),存儲年使用
- 必須把字段定義為
NOT NULL
并設默認值- NULL 的列使用索引,索引統(tǒng)計居触,值都更加復雜妖混,MySQL 更難優(yōu)化
- NULL 需要更多的存儲空間
- NULL 只能采用
IS NULL
或者IS NOT NULL
,而在=/!=/in/not in
時有大坑
- 使用
INT UNSIGNED
存儲IPv4
轮洋,不要用char(15)
- 使用
varchar(20)
存儲手機號制市,不要使用整數(shù)- 牽扯到國家代號,可能出現(xiàn)
+/-/()
等字符砖瞧,例如+86
- 手機號不會用來做數(shù)學運算
-
varchar
可以模糊查詢息堂,例如like‘138%’
- 牽扯到國家代號,可能出現(xiàn)
- 使用
TINYINT
來代替ENUM
-
ENUM
增加新值要進行DDL
操作
-
索引規(guī)范
- 唯一索引使用
uniq_[字段名]
來命名 - 非唯一索引使用
idx_[字段名]
來命名 - 單張表索引數(shù)量建議控制在 5 個以內(nèi)
- 互聯(lián)網(wǎng)高并發(fā)業(yè)務,太多索引會影響寫性能
- 生成執(zhí)行計劃時块促,如果索引太多荣堰,會降低性能,并可能導致 MySQL 選擇不到最優(yōu)索引
- 異常復雜的查詢需求竭翠,可以選擇
ES
等更為適合的方式存儲
- 組合索引字段數(shù)不建議超過 5 個
- 如果 5 個字段還不能極大縮小 row 范圍振坚,八成是設計有問題
- 不建議在頻繁更新的字段上建立索引
- 非必要不要進行
JOIN
查詢,如果要進行JOIN
查詢斋扰,被JOIN
的字段必須類型相同渡八,并建立索引- 踩過因為
JOIN
字段類型不一致啃洋,而導致全表掃描的坑么?
- 踩過因為
- 理解組合索引最左前綴原則屎鳍,避免重復建設索引宏娄,如果建立了(a,b,c),相當于建立了(a), (a,b), (a,b,c)
SQL 規(guī)范
- 禁止使用
select *
逮壁,只獲取必要字段-
select *
會增加cpu/io/內(nèi)存/帶寬
的消耗 - 指定字段能有效利用索引覆蓋
- 指定字段查詢孵坚,在表結(jié)構(gòu)變更時,能保證對應用程序無影響
-
-
insert
必須指定字段窥淆,禁止使用insert into T values()
- 指定字段插入卖宠,在表結(jié)構(gòu)變更時,能保證對應用程序無影響
- 隱式類型轉(zhuǎn)換會使索引失效忧饭,導致全表掃描
- 禁止在
where
條件列使用函數(shù)或者表達式- 導致不能命中索引扛伍,全表掃描
- 禁止負向查詢以及
%
開頭的模糊查詢- 導致不能命中索引,全表掃描
- 禁止大表
JOIN
和子查詢 - 同一個字段上的
OR
必須改寫問IN
词裤,IN
的值必須少于 50 個 - 應用程序必須捕獲 SQL 異常
- 方便定位線上問題
說明
本軍規(guī)適用于并發(fā)量大刺洒,數(shù)據(jù)量大的典型互聯(lián)網(wǎng)業(yè)務,可直接帶走參考亚斋,不謝作媚。