所有的數(shù)據(jù)庫對象名稱必須使用小寫字母并用下劃線分割(MySQL大小敏感乖杠,見名知意贩耐,最好不超過32字符)
所有的數(shù)據(jù)庫對象名稱禁止使用MySQL保留關(guān)鍵字(如 desc房铭、range售葡、match蝶桶、delayed 等忆首,請參考 MySQL 官方保留字http://dev.mysql.com/doc/refman/5.7/en/keywords.html)
臨時庫表必須以tmp為前綴并以日期為后綴(tmp_)
備份庫和庫爱榔,必須以bak為前綴,日期為后綴(bak_)
所有存儲相同數(shù)據(jù)的列名和列類型必須一致糙及。(在多個表中的字段如user_id)
mysql5.5之前默認(rèn)的存儲的引擎是myisam搓蚪,沒有特殊要求,所有的表必須使用innodb(支持失誤丁鹉,行級鎖妒潭,高并發(fā)下性能更好,對多核揣钦,大內(nèi)存,ssd等硬件支持更好)
數(shù)據(jù)庫和表的字符集統(tǒng)一使用utf8【要統(tǒng)一冯凹,避免由于字符集轉(zhuǎn)換產(chǎn)生的亂碼】。漢字utf8下暫3個字節(jié)
所有表和字段都要添加注釋COMMENT夫凸,從一開始就進(jìn)行數(shù)據(jù)字典的維護(hù)
盡量控制單表數(shù)據(jù)量的大小在500w以內(nèi)夭拌,超過500w可以使用歷史數(shù)據(jù)歸檔衷咽,分庫分表來實現(xiàn)(500萬行并不是MySQL數(shù)據(jù)庫的限制镶骗。過大對于修改表結(jié)構(gòu),備份骡和,恢復(fù)都會有很大問題慰于。MySQL沒有對存儲有限制裆赵,取決于存儲設(shè)置和文件系統(tǒng))跺嗽。
謹(jǐn)慎使用mysql分區(qū)表(分區(qū)表在物理上表現(xiàn)為多個文件桨嫁,在邏輯上表現(xiàn)為一個表)璃吧。
謹(jǐn)慎選擇分區(qū)鍵,跨分區(qū)查詢效率可能更低
建議使用物理分表的方式管理大數(shù)據(jù)
盡量做到冷熱數(shù)據(jù)分離筒繁,減小表的寬度(mysql限制最多存儲4096列毡咏,行數(shù)沒有限制逮刨,但是每一行的字節(jié)總數(shù)不能超過65535)【列限制好處:減少磁盤io,保證熱數(shù)據(jù)的內(nèi)存緩存命中率迎罗,避免讀入無用的冷數(shù)據(jù)】
禁止在表中建立預(yù)留字段(無法確認(rèn)存儲的數(shù)據(jù)類型片仿,對預(yù)留字段類型進(jìn)行修改滋戳,會對表進(jìn)行鎖定)
禁止在數(shù)據(jù)中存儲圖片奸鸯,文件二進(jìn)制數(shù)據(jù)(使用文件服務(wù)器)
禁止在線上做數(shù)據(jù)庫壓力測試
禁止從開發(fā)環(huán)境娄涩,測試環(huán)境直接連生產(chǎn)環(huán)境數(shù)據(jù)庫
限制每張表上的索引數(shù)量,建議單表索引不超過5個(索引會增加查詢效率扬虚,但是會降低插入和更新的速度)
避免建立冗余索引和重復(fù)索引(冗余:index(a,b,c) index(a,b) index(a))
禁止給表中的每一列都建立單獨(dú)的索引
每個innodb表必須有一個主鍵辜昵,選擇自增id(不能使用更新頻繁的列作為主鍵堪置,不適用UUID,MD5,HASH,字符串列作為主鍵)张惹,
區(qū)分度最高的列放在聯(lián)合索引的最左側(cè)
盡量把字段長度小的列放在聯(lián)合索引的最左側(cè)
盡量避免使用外鍵(禁止使用物理外鍵宛逗,使用邏輯外鍵)
優(yōu)先選擇符合存儲需要的最小數(shù)據(jù)類型
優(yōu)先使用無符號的整形來存儲
優(yōu)先選擇存儲最小的數(shù)據(jù)類型(varchar(N),N代表的是字符數(shù)雷激,而不是字節(jié)數(shù)屎暇,N代表能存儲多少個漢字)
避免使用Text或是Blob類型
避免使用ENUM數(shù)據(jù)類型(修改ENUM值需要使用ALTER語句,ENUM類型的ORDER BY操作效率低快毛,需要額外操作唠帝,禁止使用書值作為ENUM的枚舉值
盡量把所有的字段定義為NOT NULL(索引NULL需要額外的空間來保存,所以需要暫用更多的內(nèi)存,進(jìn)行比較和計算要對NULL值做特別的處理)
使用timestamp或datetime類型來存儲時間
同財務(wù)相關(guān)的金額數(shù)據(jù)瀑晒,采用decimal類型(不丟失精度苔悦,禁止使用 float 和 double)
避免使用雙%號和like玖详,搜索嚴(yán)禁左模糊或者全模糊(如果需要請走搜索引擎來解決蟋座。索引文件具有 B-Tree 的最左前綴匹配特性,如果左邊的值未確定巢墅,那么無法使用此索)
建議使用預(yù)編譯語句進(jìn)行數(shù)據(jù)庫操作
禁止跨庫查詢(為數(shù)據(jù)遷移和分庫分表留出余地君纫,降低耦合度庵芭,降低風(fēng)險)
禁止select * 查詢(消耗更多的cpu和io及網(wǎng)絡(luò)帶寬資源,無法使用覆蓋索引)
禁止使用不含字段列表的insert語句(不允許insert into t values(‘a(chǎn)’会前,‘b’瓦宜,‘c’)不允許)
in 操作能避免則避免临庇,若實在避免不了假夺,需要仔細(xì)評估 in 后邊的集合元素數(shù)量,控制在 1000 個之內(nèi)
禁止使用order by rand()進(jìn)行隨機(jī)排序
禁止where從句中對列進(jìn)行函數(shù)轉(zhuǎn)換和計算(例如:where date(createtime)=‘20160901’ 會無法使用createtime列上索引梧田。改成 where createtime>='20160901' and createtime <'20160902')
盡量使用 union all 代替 union
拆分復(fù)雜的大SQL為多個小SQL( MySQL一個SQL只能使用一個CPU進(jìn)行計算)
盡量避免使用子查詢,可以把子查詢優(yōu)化為join操作(子查詢的結(jié)果集無法使用索引穿稳,子查詢會產(chǎn)生臨時表操作司草,如果子查詢數(shù)據(jù)量大會影響效率泡仗,消耗過多的CPU及IO資源)
超過100萬行的批量寫操作娩怎,要分批多次進(jìn)行操作(大批量操作可能會造成嚴(yán)重的主從延遲截亦,binlog日志為row格式會產(chǎn)生大量的日志崩瓤,避免產(chǎn)生大事務(wù)操作)
對于大表使用pt—online-schema-change修改表結(jié)構(gòu)(避免大表修改產(chǎn)生的主從延遲却桶,避免在對表字段進(jìn)行修改時進(jìn)行鎖表)
對于程序連接數(shù)據(jù)庫賬號颖系,遵循權(quán)限最小原則
超過三個表禁止 join嘁扼。(需要 join 的字段趁啸,數(shù)據(jù)類型必須絕對一致;多表關(guān)聯(lián)查詢時姑丑,保證被關(guān)聯(lián)的字段需要有索引栅哀。即使雙表 join 也要注意表索引、SQL 性能痴柔。)
在varchar字段上建立索引時咳蔚,必須指定索引長度谈火,沒必要對全字段建立索引糯耍,根據(jù)實際文本區(qū)分度決定索引長度即可温技。
SQL 性能優(yōu)化的目標(biāo):至少要達(dá)到 range 級別舵鳞,要求是 ref 級別,如果可以是 consts最好虐块。
使用 ISNULL()來判斷是否為 NULL 值贺奠。
禁止物理刪除(即直接刪除)挂据,只做邏輯刪除儿普,用deleteFlag做邏輯刪除个绍,如果刪除巴柿,則為1,不刪除則為0
如果有 order by 的場景钉迷,請注意利用索引的有序性。order by 最后的字段是組合,索引的一部分枷颊,并且放在索引組合順序的最后,避免出現(xiàn) file_sort 的情況题造,影響查詢性能界赔。
在代碼中寫分頁查詢邏輯時,若 count 為 0 應(yīng)直接返回,避免執(zhí)行后面的分頁語句羹令。