一狰域、基礎(chǔ)規(guī)范
1、使用InnoDB存儲(chǔ)引擎
支持事務(wù)黄橘、行級(jí)鎖兆览、并發(fā)性能更好、CPU及內(nèi)存緩存頁(yè)優(yōu)化使得資源利用率更高
2塞关、推薦使用utf8mb4字符集
無(wú)需轉(zhuǎn)碼抬探,無(wú)亂碼風(fēng)險(xiǎn), 支持emoji表情以及部分不常見(jiàn)漢字
3、表帆赢、字段必須加注釋
方便他人理解字段意思小压。
4、不在數(shù)據(jù)庫(kù)做計(jì)算
禁止使用存儲(chǔ)過(guò)程椰于、視圖怠益、觸發(fā)器、Event瘾婿。
在并發(fā)量大的情況下蜻牢,這些功能很可能將數(shù)據(jù)庫(kù)拖跨,業(yè)務(wù)邏輯放到服務(wù)層具備更好的擴(kuò)展性偏陪,能夠輕易實(shí)現(xiàn)“增機(jī)器就加性能”
5抢呆、禁止存儲(chǔ)文件
文件存儲(chǔ)在文件系統(tǒng),數(shù)據(jù)庫(kù)里存URI
6笛谦、控制單表數(shù)據(jù)量
單表記錄控制在千萬(wàn)級(jí)
二:命名規(guī)范
1抱虐、庫(kù)名、表名饥脑、字段名:小寫(xiě)恳邀,下劃線(xiàn)風(fēng)格
非唯一索引名idx_xxx懦冰,唯一索引名uniq_xxx
2、表必須有主鍵轩娶,例如自增主鍵
主鍵遞增儿奶,數(shù)據(jù)行寫(xiě)入可以提高插入性能
主鍵要選擇較短的數(shù)據(jù)類(lèi)型,Innodb引擎普通索引都會(huì)保存主鍵的值鳄抒,較短的數(shù)據(jù)類(lèi)型可以有效的減少索引的磁盤(pán)空間闯捎,提高索引的緩存效率
保證實(shí)體的完整性,唯一性
3许溅、不要使用外鍵瓤鼻,如果有外鍵約束,用應(yīng)用程序控制
外鍵會(huì)導(dǎo)致表與表之間耦合贤重,update與delete操作都會(huì)涉及相關(guān)聯(lián)的表茬祷,十分影響sql 的性能,甚至?xí)斐伤梨i并蝗。高并發(fā)情況下容易造成數(shù)據(jù)庫(kù)性能下降祭犯,大數(shù)據(jù)高并發(fā)業(yè)務(wù)場(chǎng)景數(shù)據(jù)庫(kù)使用以性能優(yōu)先
三:字段設(shè)計(jì)規(guī)范
1、把字段定義為NOT NULL并且提供默認(rèn)值
null的列使索引/索引統(tǒng)計(jì)/值比較都更加復(fù)雜滚停,對(duì)MySQL來(lái)說(shuō)更難優(yōu)化
null 這種類(lèi)型MySQL內(nèi)部需要進(jìn)行特殊處理沃粗,增加數(shù)據(jù)庫(kù)處理記錄的復(fù)雜性;同等條件下键畴,表中有較多空字段的時(shí)候最盅,數(shù)據(jù)庫(kù)的處理性能會(huì)降低很多
null值需要更多的存儲(chǔ)空間,無(wú)論是表還是索引中每行中的null的列都需要額外的空間來(lái)標(biāo)識(shí)
對(duì)null 的處理時(shí)候起惕,只能采用is null或is not null涡贱,而不能采用=、in惹想、<问词、<>、!=嘀粱、not in這些操作符號(hào)激挪。如:where name!=’zhangsan’,如果存在name為null值的記錄草穆,查詢(xún)結(jié)果就不會(huì)包含name為null值的記錄
2灌灾、不要使用TEXT搓译、BLOB類(lèi)型
會(huì)浪費(fèi)更多的磁盤(pán)和內(nèi)存空間悲柱,非必要的大量的大字段查詢(xún)會(huì)淘汰掉熱數(shù)據(jù),導(dǎo)致內(nèi)存命中率急劇降低些己,影響數(shù)據(jù)庫(kù)性能,如果必須要使用則獨(dú)立出來(lái)一張表豌鸡,用主鍵來(lái)對(duì)應(yīng)嘿般,避免影響其它字段索引效率
3、不要使用小數(shù)存儲(chǔ)貨幣
建議使用整數(shù)涯冠,小數(shù)容易導(dǎo)致錢(qián)對(duì)不上
4炉奴、必須使用varchar存儲(chǔ)手機(jī)號(hào)
手機(jī)號(hào)會(huì)去做數(shù)學(xué)運(yùn)算么?
5蛇更、為提高效率可以犧牲范式設(shè)計(jì)瞻赶,冗余數(shù)據(jù)
不是頻繁修改的字段
不是 varchar 超長(zhǎng)字段,更不能是 text 字段
四:索引設(shè)計(jì)規(guī)范
1派任、禁止在更新十分頻繁砸逊、區(qū)分度不高的屬性上建立索引
更新會(huì)變更B+樹(shù),更新頻繁的字段建立索引會(huì)大大降低數(shù)據(jù)庫(kù)性能
“性別”這種區(qū)分度不大的屬性掌逛,建立索引是沒(méi)有什么意義的
2师逸、建立組合索引,必須把區(qū)分度高的字段放在最左邊
如果 where a=? and b=? 豆混, a 列的幾乎接近于唯一值篓像,那么只需要單建 idx_a 索引即可
3、 頁(yè)面搜索嚴(yán)禁左模糊或者全模糊
索引文件具有 B-Tree 的最左前綴匹配特性皿伺,如果左邊的值未確定员辩,那么無(wú)法使用此索引, 如果需要請(qǐng)走搜索引擎來(lái)解決
五:SQL使用規(guī)范
1、禁止使用SELECT *心傀,只獲取必要的字段屈暗,需要顯示說(shuō)明列屬性
消耗cpu,io脂男,內(nèi)存养叛,帶寬
不能有效的利用覆蓋索引
使用SELECT *容易在增加或者刪除字段后出現(xiàn)程序BUG, 不具有擴(kuò)展性
2、使用INSERT INTO t_xxx VALUES(xxx)宰翅,必須顯示指定插入的列屬性
容易在增加或者刪除字段后出現(xiàn)程序BUG
3弃甥、務(wù)必請(qǐng)使用“同類(lèi)型”進(jìn)行比較,否則可能全表掃面
SELECT name FROM t_user WHERE phone=1333333333 會(huì)導(dǎo)致全表掃描.
4汁讼、禁止在WHERE條件的上使用函數(shù)或者計(jì)算
解讀:SELECT naem FROM t_user WHERE date(create_datatime)='2017-12-15' 會(huì)導(dǎo)致全表掃描
推薦的寫(xiě)法是:SELECT name FROM t_user WHERE create_datatime>= '2017-02-15 ' and create_datatime < '2017-02-16 '
5淆攻、禁止負(fù)向查詢(xún),以及%開(kāi)頭的模糊查詢(xún)
負(fù)向查詢(xún)條件:NOT嘿架、!=瓶珊、<>、!<耸彪、!>伞芹、NOT IN、NOT LIKE等,會(huì)導(dǎo)致全表掃描
%開(kāi)頭的模糊查詢(xún)唱较,會(huì)導(dǎo)致全表掃描
6扎唾、不要大表使用JOIN查詢(xún),禁止大表使用子查詢(xún)
會(huì)產(chǎn)生臨時(shí)表南缓,消耗較多內(nèi)存與CPU胸遇,極大影響數(shù)據(jù)庫(kù)性能
7、OR改寫(xiě)為IN()或者UNION
原因很簡(jiǎn)單or不會(huì)走索引
8汉形、簡(jiǎn)單的事務(wù)
事務(wù)就像程序中的鎖一樣粒度盡可能要小
9纸镊、不要一次更新大量數(shù)據(jù)
數(shù)據(jù)更新會(huì)對(duì)行或者表加鎖,應(yīng)該分為多次更新