一憋沿,基礎(chǔ)規(guī)范
表存儲引擎必須使用InnoDB的
表字符集默認(rèn)使用utf8 葵诈,必要時(shí)候使用utf8mb4
解讀:
(1 )通用罐柳,無亂碼風(fēng)險(xiǎn)锻狗,漢字3 字節(jié)满力,英文1 字節(jié)
(2 )utf8mb4 是utf8 的超集,有存儲4 字節(jié)例如表情符號時(shí)轻纪,使用它
- 禁止使用存儲過程油额,視圖,觸發(fā)器刻帚,事件
解讀:
(1 )對數(shù)據(jù)庫性能影響較大潦嘶,互聯(lián)網(wǎng)業(yè)務(wù),能讓站點(diǎn)層和服務(wù)層干的事情我擂,不要交到數(shù)據(jù)庫層
(2 )調(diào)試衬以,排錯(cuò)缓艳,遷移都比較困難校摩,擴(kuò)展性較差
- 禁止在數(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 為后綴
三,表設(shè)計(jì)規(guī)范
- 單實(shí)例表個(gè)數(shù)必須控制在2000 個(gè)以內(nèi)
- 單表分表個(gè)數(shù)必須控制在1024 個(gè)以內(nèi)
- 表必須有主鍵匆帚,推薦使用無符號整數(shù)為主鍵
潛在坑:刪除無主鍵的表熬词,如果是行模式的主從架構(gòu),從庫會掛住
- 禁止使用外鍵吸重,如果要保證完整性互拾,應(yīng)由應(yīng)用程式實(shí)現(xiàn)
解讀:外鍵使得表之間相互耦合,影響更新/刪除等SQL 性能嚎幸,有可能造成死鎖摩幔,高并發(fā)情況下容易成為數(shù)據(jù)庫瓶頸
- 建議將大字段,訪問頻度低的字段拆分到單獨(dú)的表中存儲鞭铆,分離冷熱數(shù)據(jù)
解讀:具體參加“ 如何實(shí)施數(shù)據(jù)庫垂直拆分 ”
四或衡,列設(shè)計(jì)規(guī)范
- 根據(jù)業(yè)務(wù)區(qū)分使用tinyint / int / bigint ,分別會占用1/4/8 字節(jié)
- 根據(jù)業(yè)務(wù)區(qū)分使用CHAR / VARCHAR
解讀:
(1 )字段長度固定车遂,或者長度近似的業(yè)務(wù)場景封断,適合使用char ,能夠減少碎片舶担,查詢性能高
(2 )字段長度相差較大坡疼,或者更新較少的業(yè)務(wù)場景,適合使用varchar 衣陶,能夠減少空間
- 根據(jù)業(yè)務(wù)區(qū)分使用的日期時(shí)間/時(shí)間戳
解讀:前者占用5 個(gè)字節(jié)柄瑰,后者占用4 個(gè)字節(jié)闸氮,存儲年使用YEAR ,存儲日期使用DATE 教沾,存儲時(shí)間使用datetime
- 必須把字段定義為NOT NULL 并設(shè)默認(rèn)值
解讀:
(1 )NULL 的列使用索引蒲跨,索引統(tǒng)計(jì),值都更加復(fù)雜授翻,MySQL 更難優(yōu)化
(2 )NULL 需要更多的存儲空間
(3 )NULL 只能采用IS NULL 或者IS NOT NOT NULL 或悲,而在= =!= / in / not in 時(shí)有大坑
使用INT UNSIGNED 存儲IPv4 堪唐,不要用char(15)
使用VARCHAR(20)存儲手機(jī)號巡语,不要使用整數(shù)
解讀:
(1 )牽扯到國家代號,可能出現(xiàn)+ / - /()等字符淮菠,例如+86
(2 )手機(jī)號不會用來做數(shù)學(xué)運(yùn)算
(3 )varchar 可以模糊查詢男公,例如喜歡'138%'
- 使用TINYINT 來代替ENUM
解讀:ENUM 增加新值要進(jìn)行DDL 操作
五,索引規(guī)范
- 唯一索引使用uniq_ [ 字段名] 來命名
- 非唯一索引使用idx_ [ 字段名] 來命名
- 單張表索引數(shù)量建議控制在5 個(gè)以內(nèi)
解讀:
(1 )互聯(lián)網(wǎng)高并發(fā)業(yè)務(wù)合陵,太多索引會影響寫性能
(2 )生成執(zhí)行計(jì)劃時(shí)枢赔,如果索引太多,會降低性能曙寡,并可能導(dǎo)致MySQL 選擇不到最優(yōu)索引
(3 )異常復(fù)雜的查詢需求糠爬,可以選擇ES 等更為適合的方式存儲
- 組合索引字段數(shù)不建議超過5 個(gè)
解讀:如果5 個(gè)字段還不能極大縮小行范圍,八成是設(shè)計(jì)有問題
- 不建議在頻繁更新的字段上建立索引
- 非必要不要進(jìn)行JOIN 查詢举庶,如果要進(jìn)行JOIN 查詢执隧,被JOIN 的字段必須類型相同,并建立索引
解讀:踩過因?yàn)镴OIN字段類型不一致户侥,而導(dǎo)致全表掃描的坑么镀琉?
- 理解組合索引最左前綴原則,避免重復(fù)建設(shè)索引蕊唐,如果建立了(a屋摔,b,c)替梨,相當(dāng)于建立了(a)钓试,(a,b)副瀑,(a弓熏,b,c)
六糠睡,SQL 規(guī)范
- 禁止使用select * 挽鞠,只獲取必要字段
解讀:
(1 )選擇* 會增加cpu / io / 內(nèi)存/ 帶寬的消耗
(2 )指定字段能有效利用索引覆蓋
(3 )指定字段查詢,在表結(jié)構(gòu)變更時(shí),能保證對應(yīng)用程序無影響
- insert 必須指定字段信认,禁止使用插入T值()
解讀:指定字段插入材义,在表結(jié)構(gòu)變更時(shí),能保證對應(yīng)用程序無影響
隱式類型轉(zhuǎn)換會使索引失效嫁赏,導(dǎo)致全表掃描
禁止在哪里條件列使用函數(shù)或者表達(dá)式
解讀:導(dǎo)致不能命中索引其掂,全表掃描
- 禁止負(fù)向查詢以及%開頭的模糊查詢
解讀:導(dǎo)致不能命中索引,全表掃描
- 禁止大表JOIN 和子查詢
- 同一個(gè)字段上的OR 必須改寫問IN 橄教,IN 的值必須少于50 個(gè)
- 應(yīng)用程序必須捕獲SQL 異常
解讀:方便定位線上問題