阿里數(shù)據(jù)庫開發(fā)規(guī)范:誰還敢說你的數(shù)據(jù)庫設(shè)計的“爛”

數(shù)據(jù)庫設(shè)計幾個規(guī)范:

數(shù)據(jù)庫命名規(guī)范、數(shù)據(jù)庫基本設(shè)計規(guī)范、數(shù)據(jù)庫索引設(shè)計規(guī)范、數(shù)據(jù)庫字段設(shè)計規(guī)范、數(shù)據(jù)庫SQL開發(fā)規(guī)范、數(shù)據(jù)庫操作行為規(guī)范

數(shù)據(jù)庫命名規(guī)范

1、所有數(shù)據(jù)庫對象名稱必須使用小寫字母并用下劃線分割

不同的數(shù)據(jù)庫名 DbName dbname

不同的表名 Table table tabLe

2、所有數(shù)據(jù)庫對象名稱禁止使用MySQL保留關(guān)鍵字

select id,username,from,age from tb_user from是關(guān)鍵字 ,但是可以用單引號括起來

3、數(shù)據(jù)庫對象的命名要見名識義,并且最好不要超過32個字符

例如 用戶數(shù)據(jù)庫mc_userdb 用戶賬號表 user_account

4、臨時庫表必須以tmp為前綴并以日期為后綴

5、備份庫、備份表必須以bak為前綴并以日期為前綴

6、所有存儲相同數(shù)據(jù)的列名和列類型必須一致

比如兩張表中有相同的數(shù)據(jù),那么他們列名和列類型必須是一致的

數(shù)據(jù)庫基本設(shè)計規(guī)范

1、所有表必須使用Innodb存儲引擎,mysql 5.6后默認(rèn)存儲引擎,支持事務(wù),行級鎖,更好的恢復(fù)性,高并發(fā)下性能更好

2、數(shù)據(jù)庫和表的字符集統(tǒng)一使用UTF8,避免由于字符集轉(zhuǎn)換產(chǎn)生的亂碼

mysql中utf8字符集漢字占3個字節(jié),ASCII碼占用1個字節(jié)

3、所有表和字段都需要添加注釋,使用comment從句添加表和列的備注

4、盡量控制單表數(shù)據(jù)量的大小,建議控制在500萬以內(nèi),500萬并不是mysql數(shù)據(jù)庫的限制,

mysql最多可以存儲多少萬數(shù)據(jù)?目前沒有做限制,這種限制取決于存儲設(shè)置和文件系統(tǒng)

可以用歷史數(shù)據(jù)歸檔,分庫分表等手段來控制數(shù)據(jù)量大小

5、謹(jǐn)慎使用mysql分區(qū)表

分區(qū)表在物理上表現(xiàn)為多個文件沒在邏輯上表現(xiàn)為一個表

謹(jǐn)慎選擇分區(qū)鍵,跨分區(qū)查詢效率可能更低

建議采用物理分表的方式管理大數(shù)據(jù)

6、盡量做到冷熱數(shù)據(jù)分離,減小表的寬度

mysql限制最多存儲4096列,為了是減少磁盤IO,保證熱數(shù)據(jù)的內(nèi)存緩存命中率,利用更有效的利用緩存,避免讀入無用的冷數(shù)據(jù)

經(jīng)常使用的列放在一個表中

7、禁止在表中建立預(yù)留字段

預(yù)留字段的命名很難做到見名識義

預(yù)留字段無法確認(rèn)存儲的數(shù)據(jù)類型,所以無法選擇合適的類型

對預(yù)留字段類型的修改,會對表進(jìn)行鎖定,修改字段類型的成本往往大于增加

8、禁止在數(shù)據(jù)庫中存儲圖片、文件等二進(jìn)制數(shù)據(jù)

9、禁止在線上做數(shù)據(jù)庫壓力測試

10、禁止從開發(fā)環(huán)境,測試環(huán)境直連生產(chǎn)環(huán)境數(shù)據(jù)庫

索引設(shè)計規(guī)范

索引對數(shù)據(jù)庫的查詢性能來說非常重要,查詢、更新,禁止濫用索引

1、限制每張表上的索引數(shù)量,建議單張表索引不超過5個

索引并不是越多越好的,索引可以提高效率同樣可以降低效率

索引可以增加查詢效率,但同樣也會降低插入和更新的效率

2、禁止給表中的每一列都建立單獨(dú)的索引

3、Innodb是按照主鍵索引的順序來組織表的

4、每個Innodb表必須有一個主鍵

不使用更新頻繁的列作為主鍵,不使用多列主鍵

不使用uuid、MD5、hash,字符串列作為主鍵

主鍵建議使用主鍵自增

常見的索引列建議:

select、update、delete語句的where從句中的列

包含在order by、group by 、destinct中的字段

多表join的關(guān)聯(lián)列

如何選擇索引列的順序:

聯(lián)合索引是從做到右的順序來實(shí)現(xiàn)的

1、區(qū)分度最高的列放在聯(lián)合索引的最左側(cè)

2、盡量把字段長度小的列放在聯(lián)合索引的最左側(cè)

3、使用最頻繁的列放到聯(lián)合索引的左側(cè)

5、避免建立冗余索引和重復(fù)索引

重復(fù)索引:如 primary key(id)、index(id)、unique index(id)

冗余索引:如 index(a,b,c) index(a,b) index(a)

6、對于頻繁的查詢優(yōu)先使用覆蓋索引

覆蓋索引:就是包括了所有查詢字段的索引

優(yōu)點(diǎn):避免Innodb表進(jìn)行索引的二次查找,可以把隨機(jī)IO變?yōu)轫樞騃O加快查詢效率

7、盡量避免使用外鍵

不建議使用外鍵約束,但一定在表與表之間的關(guān)聯(lián)鍵上建立索引

外鍵可用于保證數(shù)據(jù)的參照完整性,但建議在業(yè)務(wù)端實(shí)現(xiàn)

外鍵會影響父表和子表的寫操作從而降低性能

數(shù)據(jù)庫字段設(shè)計規(guī)范

1、優(yōu)先選擇符合存儲需要的最小的數(shù)據(jù)類型

將字符串轉(zhuǎn)化為數(shù)字類型存儲

對于非負(fù)數(shù)據(jù)采用無符號整形進(jìn)行存儲

signed int -2147483648-2147483648

unsigned int 0-2147483648

有符號比無符號多出一倍的存儲空間

varchar(n) n代表字符數(shù),不是字節(jié)數(shù),varchar(255)=765個字節(jié)

過大的長度會消耗更多的內(nèi)存

2、避免使用text\BLOB數(shù)據(jù)類型

建議text\BLOB列分離到單獨(dú)的擴(kuò)展表中

text\BLOB類型只能使用前綴索引

3、避免使用enum數(shù)據(jù)類型

修改enum需要使用alter語句

enum類型的order by操作效率低,需要額外操作

禁止使用數(shù)值作為enum的枚舉值

4、盡可能把所有列定義為not null

索引null列需要額外的空間來保存,所以要占用更多的空間

進(jìn)行比較和計算時要對null值做特別的處理

5、禁止字符串存儲日期型的數(shù)據(jù)

缺點(diǎn)1:無法用日期函數(shù)進(jìn)行計算和比較

缺點(diǎn)2:用字符串存儲日期要占用更多的空間

使用timestamp或datetime類型存儲時間,timestamp存儲空間更小

6、財務(wù)的相關(guān)金額使用decimal類型

decimal類型為精準(zhǔn)浮點(diǎn)數(shù),在計算時不會丟失精度

float、double非精準(zhǔn)浮點(diǎn)數(shù)

數(shù)據(jù)庫SQL開發(fā)規(guī)范

1、建議使用預(yù)編譯語句進(jìn)行數(shù)據(jù)庫操作

好處:只傳參數(shù),比傳遞SQL語句更高效

相同語句可以一次解析,多次使用,提高處理效率

2、避免數(shù)據(jù)類型的隱式轉(zhuǎn)換

隱式轉(zhuǎn)換會導(dǎo)致索引失效

3、利用表上已經(jīng)存在的索引

4、禁止連接不同的數(shù)據(jù)庫使用不同的賬號,禁止垮庫查詢

為數(shù)據(jù)庫遷移和分庫分表留出余地

減低業(yè)務(wù)耦合度

避免權(quán)限過大而產(chǎn)生的安全風(fēng)險

5、禁止使用select * 必須用select 字段列表 查詢

消耗更多的CPU和io以及網(wǎng)絡(luò)帶寬資源

無法使用覆蓋索引

可減少表結(jié)構(gòu)變更帶來的影響

6、禁止使用不含字段列表的insert語句

如,insert into t values(‘a(chǎn)’,’b’,’c’)

7、避免使用子查詢,可以把子查詢優(yōu)化為join操作

子查詢的結(jié)果集無法使用索引

子查詢會產(chǎn)生臨時表,如果子查詢數(shù)據(jù)量大則嚴(yán)重影響效率

消耗過多的CPU和io資源

8、避免使用join關(guān)聯(lián)太多的表

每join一個表會多占用一部分內(nèi)存join_buffer_size

會產(chǎn)生臨時表操作,影響查詢效率

mysql最多關(guān)聯(lián)61個表,建議不超過5個

9、減少同數(shù)據(jù)庫的交互次數(shù)

10、禁止使用order by rand()進(jìn)行隨機(jī)排序

11、where從句中禁止對列進(jìn)行函數(shù)轉(zhuǎn)換和計算

對列進(jìn)行函數(shù)轉(zhuǎn)換和計算會導(dǎo)致無法使用索引

如:where date(createtime)=’20160901’

優(yōu)化后:where createtime>=’20160901’

目錄展示

需要更多mysql相關(guān)資料,關(guān)注公眾號:Java架構(gòu)師聯(lián)盟,后臺回復(fù)mysql即可獲取,更可以查看本文檔的獲取方式

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容