1.重要行為規(guī)范
1) 不允許擅自導(dǎo)出線上數(shù)據(jù)
2) 批量更新,如洗數(shù)據(jù),避開(kāi)高峰期障癌,并通知運(yùn)維team,直接執(zhí)行sql的需要由運(yùn)維同事操作
3) 統(tǒng)計(jì)分析蹦玫、跨租戶管理、批量數(shù)據(jù)操作刘绣、導(dǎo)入導(dǎo)出功能上線前必須經(jīng)過(guò)審查
4) 復(fù)雜SQL樱溉,因各種特殊原因不符合本規(guī)范的SQL需要經(jīng)過(guò)審查上線
5) 所有DDL操作需要找運(yùn)維組執(zhí)行,并經(jīng)過(guò)審查(建表纬凤、改表福贞、建索引、改索引停士、建存儲(chǔ)過(guò)程)
2. 命名規(guī)范
1) 庫(kù)名挖帘、表名、索引名必須使用小寫字母恋技,并采用下劃線分割
比如表 eb_product拇舀,eb代表業(yè)務(wù)模塊名,關(guān)系表則使用eb_product_category蜻底,超長(zhǎng)使用簡(jiǎn)寫
普通索引以idx_col1col2命名骄崩,唯一索引以u(píng)k_col1col2命名。如idx_companyid_personid
2) 字段名使用全小寫字母
如companyid、personid要拂、username
3) 庫(kù)名抠璃、表名、字段名脱惰、索引名禁止超過(guò)32個(gè)字符搏嗡,須見(jiàn)名之意
庫(kù)名、表名拉一、字段名支持最多64個(gè)字符采盒,但為了統(tǒng)一規(guī)范、易于辨識(shí)以及減少傳輸量舅踪,禁止超過(guò)32個(gè)字符
4) 庫(kù)名纽甘、表名、字段名抽碌、索引名禁止使用MySQL保留字
5) 臨時(shí)庫(kù)、表名必須以tmp為前綴决瞳,并以日期為后綴
如eb_product_tmp20170225
6) 備份庫(kù)货徙、表必須以bak為前綴,并以日期為后綴
如eb_product_bak20170225
3. 表設(shè)計(jì)規(guī)范
1) 使用Innodb存儲(chǔ)引擎
2) 使用UTF8MB4字符集皮胡,兼容EMOJ
3) 所有表要加注釋
表注釋
字段注釋
類似status型的字段需指明主要值的含義痴颊,如”0-離線,1-在線”
4) 控制單表字段數(shù)量
單表字段不允許超過(guò)30個(gè)屡贺,再多的話考慮垂直分表蠢棱,一是冷熱數(shù)據(jù)分離,二是大字段分離甩栈,三是常在一起做條件和返回列的不分離
5) 所有表都必須要顯式指定主鍵
所有表必須顯式指定主鍵
主鍵使用bigint類型
主鍵使用framework中的id生成器獲刃合伞(建設(shè)中)
6) 禁止使用外鍵
7) 適度使用存儲(chǔ)過(guò)程、視圖量没,禁止使用觸發(fā)器玉转、事件
使用存儲(chǔ)過(guò)程必須報(bào)DBA
8) 分表策略
單表一到兩年內(nèi)數(shù)據(jù)量超過(guò)500w或數(shù)據(jù)容量超過(guò)10G考慮分表
不使用MySQL分區(qū)表
4.字段設(shè)計(jì)規(guī)范
1) 所有字段設(shè)置為not null
索引字段一定要定義為not null 。因?yàn)閚ull值會(huì)影響cordinate統(tǒng)計(jì)殴蹄,影響優(yōu)化器對(duì)索引的選擇
如果不能保證insert時(shí)一定有值過(guò)來(lái)究抓,定義時(shí)使用default ‘’ ,或 0
2) 同一意義的字段定義必須相同
比如不同表中都有userid 字段袭灯,那么它的類型刺下、字段長(zhǎng)度要設(shè)計(jì)成一樣
3) 禁止使用float、double類型稽荧,使用decimal存儲(chǔ)浮點(diǎn)型
對(duì)于貨幣橘茉、金額這樣的類型,使用decimal,如 decimal(9,2)捺癞。float默認(rèn)只能精確到6位有效數(shù)字
4) 用盡量少的存儲(chǔ)空間來(lái)存數(shù)一個(gè)字段的數(shù)據(jù)
能使用int就不要使用varchar
能用varchar(16)就不要使用varchar(256)
5) 對(duì)于type夷蚊、status類的字段用數(shù)值而不要直接用字符串
如obj_type用1,2,3 代替 'feed','blog','task'
使用tinyint或者int
減少存儲(chǔ)空間
加快查詢速度
減少數(shù)據(jù)傳輸IO
減少coding時(shí)拼寫錯(cuò)誤的可能
6)表達(dá)布爾值的字段,數(shù)據(jù)類型采用unsigned tinyint
7) 使用timestamp存儲(chǔ)時(shí)間
datetime和timestamp類型所占的存儲(chǔ)空間不同髓介,前者8個(gè)字節(jié)惕鼓,后者4個(gè)字節(jié),這樣造成的后果是兩者能表示的時(shí)間范圍不同唐础。前者范圍為1000-01-01 00:00:00 ~ 9999-12-31 23:59:59箱歧,后者范圍為 1970-01-01 08:00:01到2038-01-19 11:14:07,timestamp就夠用一膨。
timestamp可以在insert/update行時(shí)呀邢,自動(dòng)更新時(shí)間字段(如updatetime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)
timestamp顯示與時(shí)區(qū)有關(guān),內(nèi)部總是以 UTC 毫秒 來(lái)存的豹绪。還受到嚴(yán)格模式的限制
8) 禁止使用blob价淌、text類型保留大文本、文件瞒津、圖片蝉衣,使用其他方式存儲(chǔ),MySQL只保存指針信息
TEXT類型與VARCHAR類似巷蚪,存儲(chǔ)可變長(zhǎng)度病毡,最大限制也是2^16,但是它20bytes以后的內(nèi)容是在數(shù)據(jù)頁(yè)以外的空間存儲(chǔ)屁柏,對(duì)它的使用需要多一次尋址啦膜,沒(méi)有默認(rèn)值。一般用于存放容量平均都很大淌喻、操作沒(méi)有其它字段那樣頻繁的值僧家。
BLOB可以看出varbinary的擴(kuò)展版本,內(nèi)容以二進(jìn)制字符串存儲(chǔ)似嗤,無(wú)字符集啸臀,區(qū)分大小寫,不要在數(shù)據(jù)庫(kù)里存儲(chǔ)圖片烁落。
text和blob上面一般不會(huì)去建索引乘粒,而是利用全文搜索引擎。
另外盡可能把text/blob拆到另一個(gè)表中
9) 字段允許適當(dāng)冗余伤塌,以提性能灯萍,但必須考慮數(shù)據(jù)同步的情況
冗余字段不能是頻繁修改的字段。
冗余字段不能是varchar超長(zhǎng)字段每聪,更不能是text字段
5.索引設(shè)計(jì)規(guī)范
1) 單表索引個(gè)數(shù)限制
索引是雙刃劍旦棉,會(huì)增加維護(hù)負(fù)擔(dān)齿风,增大IO壓力,索引占用空間是成倍增加的
單張表的索引數(shù)量控制在5個(gè)以內(nèi)绑洛,每個(gè)索引字段不超過(guò)5個(gè)救斑。
2) 禁止重復(fù)、冗余索引
對(duì)同一字段建多個(gè)索引
(a)和(a,b)是冗余索引,索引最左原則
InnoDB表是一棵索引組織表真屯,普通索引最終指向的是主鍵地址脸候,所以把主鍵做最后一列是多余的。如shopid作為主鍵绑蔫,聯(lián)合索引(userid,shopid)上的shopid就完全多余
3) 索引盡量建在選擇性高的列上
不在低基數(shù)列上建立索引运沦,例如性別、類型配深。但有一種情況携添,idx_feedid_feedtype (feedid,feedtype),如果經(jīng)常用feed_type = 1 比較篓叶,而且能過(guò)濾掉90%行烈掠,那這個(gè)組合索引就值得創(chuàng)建。
索引選擇性計(jì)算方法(基數(shù) ÷ 數(shù)據(jù)行數(shù)) Selectivity = Cardinality / Total Rows 越接近1說(shuō)明使用索引的過(guò)濾效果越好
4) 不在頻繁更新的列上創(chuàng)建索引
5)重要的SQL必須使用索引
update缸托、delete語(yǔ)句中的where條件列
多表向叉、大表join的連接字段
order by、group by嗦董、distinct字段
6) 對(duì)字符串字段使用前綴索引
對(duì)字符串優(yōu)先使用前綴索引,索引長(zhǎng)度不超過(guò)8個(gè)字符
7) 業(yè)務(wù)上具有唯一特性的字段瘦黑,即使是組合字段京革,也必須建成唯一索引
6.業(yè)務(wù)設(shè)計(jì)規(guī)范
1) 在所有業(yè)務(wù)表中建社區(qū)ID字段(companyid)字段
減少聯(lián)查
方便客戶數(shù)據(jù)導(dǎo)出
利于多租戶數(shù)據(jù)安全保護(hù)
2) 重要業(yè)務(wù)數(shù)據(jù)表、主數(shù)據(jù)表建createtime幸斥、updatetime字段
方便未來(lái)按時(shí)間做分表或清理數(shù)據(jù)
方便出問(wèn)題時(shí)追查數(shù)據(jù)變更時(shí)間
7.SQL規(guī)范
1) 任何新的select,update,delete上線匹摇,都要先explain,看索引使用情況
update甲葬,delete 換成select再explain
非統(tǒng)計(jì)分析廊勃、批量執(zhí)行業(yè)務(wù)SQL在線上還原庫(kù)中執(zhí)行時(shí)間不允許超過(guò)2s
SQL優(yōu)化指標(biāo):至少要達(dá)到range級(jí)別,要求是ref級(jí)別经窖,如果可以是consts最好
2) 杜絕直接 SELECT*讀取全部字段
3) 使用prepared statement坡垫,禁止拼SQL
4) 禁止使用非同類型的列進(jìn)行等值查詢
隱式轉(zhuǎn)換不使用索引
5) 禁止在where條件列上使用函數(shù)
對(duì)索引列使用函數(shù)導(dǎo)致索引失效
6) 禁止使用like '%xxx'
會(huì)導(dǎo)致索引失效,有這種搜索需求時(shí)画侣,考慮全文搜索
7) 盡量不使用子查詢冰悠,改用join
8) 不使用負(fù)向查詢,如 not in/like
9) in的數(shù)量不超過(guò)500個(gè)
10)不在SQL中進(jìn)行數(shù)學(xué)運(yùn)算
MySQL不擅長(zhǎng)數(shù)學(xué)運(yùn)算和邏輯判斷
無(wú)法使用索引
11)join表不超過(guò)三個(gè)配乱,否則考慮優(yōu)化業(yè)務(wù)設(shè)計(jì)或表設(shè)計(jì)
12)非統(tǒng)計(jì)分析類業(yè)務(wù)杜絕使用case when then等復(fù)雜語(yǔ)句
13) 執(zhí)行批量插入業(yè)務(wù)時(shí)溉卓,減少與數(shù)據(jù)庫(kù)交互的次數(shù)皮迟,盡量采用批量SQL語(yǔ)句
14) 不要使用count(列名)或count(1)來(lái)替代count(*),因?yàn)閏ount(*)會(huì)統(tǒng)計(jì)值為NULL的桑寨,其他則不會(huì)
15)不寫危險(xiǎn)SQL
帶有companyid條件的SQL伏尼,companyid必須強(qiáng)制有值
杜絕where 1=1 這樣無(wú)意義或恒真的條件
SQL中不允許出現(xiàn)DDL語(yǔ)句 "$"