目錄
1.設(shè)計(jì)階段
1.1 數(shù)據(jù)庫(kù)表的設(shè)計(jì)范式(三范式&反范式)
為什么需要范式
優(yōu)點(diǎn):編程相對(duì)簡(jiǎn)單,數(shù)據(jù)量更小,更適合放入內(nèi)存负饲,更新更快,只需要更新少量的數(shù)據(jù)娜汁,
更少的冗余意味著更少的需要group distinct 之類的操作精置。
第一范式
數(shù)據(jù)表每一列都是不可分割的基本數(shù)據(jù)項(xiàng)统翩。舉例一個(gè)人有多個(gè)手機(jī)號(hào)
第二范式
數(shù)據(jù)表里的所有數(shù)據(jù)都要和該數(shù)據(jù)表里的主鍵有完全相依賴的關(guān)系仁锯,不能只依賴部分耀找。
舉例:用戶名&用戶技能 是主鍵,用戶居住地 业崖,那么用戶名為主鍵就可以了野芒。
第三范式
缺點(diǎn):非鍵屬性都只和候選屬性相關(guān),非間屬性之間沒有關(guān)系双炕。舉例冠軍表中冠軍名&冠軍生日山叮。
范式的缺陷
查詢變得相當(dāng)復(fù)雜总放,查詢時(shí)需要更多的連接join ,一些復(fù)合索引的列由于范式化的需要被分割到不同的表中锅尘,導(dǎo)致索引策略不佳严卖。
反范式
優(yōu)點(diǎn):減少了連接案训,可以更好的利用索引進(jìn)行篩選和排序企锌,對(duì)查詢操作可以提高性能角寸。
缺點(diǎn):要在數(shù)據(jù)一致性與查詢之間找到平衡點(diǎn),符合業(yè)務(wù)場(chǎng)景的設(shè)計(jì)才是好的設(shè)計(jì)
數(shù)據(jù)庫(kù)設(shè)計(jì)準(zhǔn)則
設(shè)計(jì)的數(shù)據(jù)庫(kù)應(yīng)該按照用戶可能的訪問路徑顷编,訪問習(xí)慣進(jìn)行設(shè)計(jì)戚炫,而不是嚴(yán)格按照數(shù)據(jù)范式來設(shè)計(jì)
1.2 存儲(chǔ)引擎的選擇
存儲(chǔ)引擎分類
InnoDB:
1.災(zāi)難恢復(fù)性好
2.支持4中級(jí)別的事務(wù),默認(rèn)事務(wù)的隔離級(jí)別是Repeatable Read媳纬,事務(wù)支持是通過MVCC多版本并發(fā)控制來提供的双肤。
3.使用行級(jí)鎖,并發(fā)性能高钮惠。
4.使用此存儲(chǔ)引擎的表茅糜,數(shù)據(jù)的物理組織形式是簇表,數(shù)據(jù)按主鍵來組織素挽,即主鍵索引和數(shù)據(jù)是在一起的蔑赘,B+樹就是這樣的
5.實(shí)現(xiàn)緩沖管理,能緩存索引也能緩存數(shù)據(jù)预明。
6.支持外鍵
7.支持熱備份
MyISAM:
1.配合鎖缩赛,實(shí)現(xiàn)操作系統(tǒng)下的復(fù)制備份,遷移
2.使用表記鎖并發(fā)性差
3.支持全文索引
4.主機(jī)宕機(jī)后撰糠,表容易損壞酥馍,災(zāi)難恢復(fù)性不佳
5.無事務(wù)支持
6.只緩存索引,數(shù)據(jù)緩存利用操作系統(tǒng)緩沖區(qū)實(shí)現(xiàn)的阅酪,引發(fā)過多系統(tǒng)調(diào)用旨袒,性能不佳。
7.數(shù)據(jù)緊湊存儲(chǔ)术辐,可以獲得更快的索引和更快的全表掃描性能砚尽。
存儲(chǔ)引擎的選擇:
設(shè)計(jì)階段我們選用InnoDB存儲(chǔ)引擎作為數(shù)據(jù)的存儲(chǔ)模式,使用事務(wù)、且并發(fā)性高辉词,支持外鍵必孤,支持外鍵索引。
1.3 字符集選擇
字符編碼采用utf-8
字符校驗(yàn)采用utf-8-cgi
1.4 命名約定
規(guī)范的必要性P187
1.年前bug就是因?yàn)闆]有建立索引導(dǎo)致的一系列Bug瑞躺,所以建立規(guī)范隧魄,刻不容緩。
2.命名沒有強(qiáng)制約定隘蝎,但在一個(gè)應(yīng)用中建議風(fēng)格統(tǒng)一购啄。
命名約定
1.命名有意義,一眼知道這張表是干什么用的
2.數(shù)據(jù)庫(kù)嘱么,表都用小寫
數(shù)據(jù)庫(kù)形如:backend
數(shù)據(jù)表形如:client_device_info(客戶端設(shè)備信息)狮含,不要縮寫,字母全小寫
3.索引命名以idx_為前綴
4.命名不要過長(zhǎng)(應(yīng)盡量少于25字符)
5.不要使用保留字
6.同一字段在不同的表中也應(yīng)是相同的類型和長(zhǎng)度
7.同一數(shù)據(jù)庫(kù)下有不同的模塊曼振,可以考慮對(duì)表名用不同的前綴標(biāo)識(shí)
8.備份表時(shí)加上時(shí)間標(biāo)識(shí)
1.5 索引設(shè)計(jì)
直接參考MySQL 數(shù)據(jù)庫(kù)索引使用場(chǎng)景&注意事項(xiàng)
1.6 數(shù)據(jù)表設(shè)計(jì)與規(guī)劃
表設(shè)計(jì)
1.如果沒有特殊情況几迄,建議選擇InooDB索引
2.每個(gè)表都應(yīng)該有主鍵,可選擇自增字段冰评,或整型字段映胁。例外情況,一些應(yīng)用會(huì)頻繁的基于某些字段進(jìn)行檢索甲雅,設(shè)計(jì)人員可能認(rèn)為這些字段/
字組合更適合做主鍵解孙,因?yàn)楦匀豢犹睢⒏咝А?3.(不做強(qiáng)制要求)盡量將字段設(shè)置為NOT NULL。因?yàn)镹ULL值的存儲(chǔ)需要額外的空間弛姜,且會(huì)導(dǎo)致比較運(yùn)算更為復(fù)雜脐瑰,會(huì)使得優(yōu)化器更難以
優(yōu)化sql。null 值雖然會(huì)導(dǎo)致比較運(yùn)算更加復(fù)雜廷臼,但這比因此定義了not null帶來應(yīng)用邏輯異要好苍在。
4.使用更短小的列,比如整型列荠商。整型列的執(zhí)行速度往往更快寂恬。
5.存儲(chǔ)精確浮點(diǎn)數(shù)必須使用DECIMAL代替float和double。
6.建議使用unsigned類型存儲(chǔ)非負(fù)值
7.建議使用 int unsigned存儲(chǔ)ipv4
8.整型定義中不添加顯示長(zhǎng)度的值莱没,使用int初肉,而不是int(4)
9.盡可能不要使用text,blob類型
10.varchar(n) n表示字符數(shù)而不是字節(jié)數(shù),比如varchar(255)最大可存儲(chǔ)255個(gè)漢字郊愧,需根據(jù)實(shí)際字符長(zhǎng)度選擇n的值朴译。
11.字符集建議選擇utf-8
12.存儲(chǔ)年時(shí)使用year類型
13.存儲(chǔ)日期時(shí)使用date類型
14.存儲(chǔ)時(shí)間時(shí),建議使用timestamp類型属铁,因?yàn)閠imestamp使用的是4字節(jié)眠寿,datetime使用的是8字節(jié)。
15.不要在數(shù)據(jù)庫(kù)中使用varbinary或blob存儲(chǔ)圖片及文件焦蘑,mysql 并不適合大量存儲(chǔ)這類型文件
16.join 操作的字段盯拱,在不同表中的類型及命名要一致
17.如果更改表結(jié)構(gòu)會(huì)影響性能,需要我司后臺(tái)(有DBA盡可能找DBA)進(jìn)行聯(lián)合評(píng)審例嘱。
數(shù)據(jù)表規(guī)劃
查看數(shù)據(jù)表大小的腳本
select sum(data_length+index_length) from information_schema.tables where table_schema = ‘a(chǎn)pp_backend’ and table_name = ‘client_device_info’;
其中data_length是記錄大總大小狡逢,index_length 為索引的大小,table_schema 是數(shù)據(jù)庫(kù)名
table_name 是數(shù)據(jù)表名拼卵。
1.7 慎用外鍵
外鍵的使用
1.外鍵的優(yōu)點(diǎn):
外鍵約束使得程序員更不容易將不一致性引入數(shù)據(jù)庫(kù)奢浑,而且設(shè)計(jì)合適外鍵有助于以文檔方式記錄表間關(guān)系。
2.外鍵的缺點(diǎn)
但這些優(yōu)點(diǎn)是以服務(wù)器為執(zhí)行必要的檢查而花費(fèi)額外的開銷為代價(jià)的腋腮。服務(wù)器進(jìn)行額外的檢查會(huì)影響性能雀彼。
其次外鍵對(duì)并發(fā)性能的影響很大,因每次修改數(shù)據(jù)都需要去另外一個(gè)表檢查數(shù)據(jù)即寡,需要獲取額外的鎖(以確保事務(wù)完成之前徊哑,父表的記錄不
會(huì)被刪除)高并發(fā)環(huán)境下出現(xiàn)性能問題,更好的辦法是在應(yīng)用層實(shí)現(xiàn)外鍵約束聪富。