數(shù)據(jù)庫(kù)開發(fā)規(guī)范以及優(yōu)化(MySql)

建表時(shí)需考慮的事情

在實(shí)際的業(yè)務(wù)場(chǎng)景中榜配,利用關(guān)系表來(lái)構(gòu)建整個(gè)業(yè)務(wù)需求,那么我們需要考慮的是
范式規(guī)范(1NF吕晌,2NF蛋褥,3NF,BCNF睛驳,4NF烙心,5NF);
表之間的關(guān)系(一對(duì)一乏沸,一對(duì)多淫茵,多對(duì)多);
表用途(數(shù)據(jù)表蹬跃,配置表)匙瘪;
數(shù)據(jù)庫(kù)級(jí)別配置
表字段
索引使用

范式規(guī)范

1NF:關(guān)系中的每個(gè)屬性都不可再分。

1NF是所有關(guān)系型數(shù)據(jù)庫(kù)的最基本要求蝶缀,不符合1NF的關(guān)系表是無(wú)法在數(shù)據(jù)庫(kù)中建立的丹喻。但是只滿足1NF的表數(shù)據(jù)冗余過(guò)大,而且會(huì)存在插入異常翁都,刪除異常驻啤,修改異常的問(wèn)題。我們舉一個(gè)金融系統(tǒng)中貸款申請(qǐng)的一個(gè)實(shí)際業(yè)務(wù)場(chǎng)景來(lái)說(shuō)荐吵,現(xiàn)在設(shè)計(jì)一個(gè)貸款申請(qǐng)表骑冗,該表符合1NF

貸款申請(qǐng)表

數(shù)據(jù)冗余過(guò)大:貸款渠道描述,貸款產(chǎn)品描述先煎,所屬額度描述贼涩,這三個(gè)字段完全是冗余字段。

插入異常:如果我們想新增一個(gè)貸款渠道薯蝎,但是沒(méi)有人從這個(gè)渠道貸款遥倦,我們便無(wú)法插入這個(gè)渠道。
刪除異常:我們要?jiǎng)h除李四的貸款信息占锯,那么對(duì)應(yīng)的貸款產(chǎn)品p2袒哥,也被刪除了。
修改異常:我們要修改張三的貸款產(chǎn)品的話消略,那么產(chǎn)品對(duì)應(yīng)關(guān)系也被修改了堡称。
總之一句話,1NF下的表艺演,牽一發(fā)動(dòng)全身却紧。

2NF和3NF:消除了非主屬性對(duì)于碼的部分函數(shù)依賴(2NF)和傳遞函數(shù)依賴(3NF)

首先桐臊,理清概念
完全函數(shù)依賴:
部分函數(shù)依賴:
傳遞函數(shù)依賴:
碼:設(shè) K 為某表中的一個(gè)屬性或?qū)傩越M,若除 K 之外的所有屬性都完全函數(shù)依賴于 K(這個(gè)“完全”不要漏了)晓殊,那么我們稱 K 為候選碼断凶,簡(jiǎn)稱為。在實(shí)際中我們通澄装常可以理解為:假如當(dāng) K 確定的情況下认烁,該表除 K 之外的所有屬性的值也就隨之確定,那么 K 就是碼介汹。一張表中可以有超過(guò)一個(gè)碼砚著。(實(shí)際應(yīng)用中為了方便,通常選擇其中的一個(gè)碼作為主碼

表之間的關(guān)系

如果你設(shè)計(jì)的表符合BCNF范式的話痴昧,那么對(duì)于一對(duì)一,一對(duì)多冠王,多對(duì)多這些表之間的關(guān)系就能理解了赶撰。之所以表之間有這些關(guān)系,就是為了讓表符合范式規(guī)范柱彻。

一對(duì)一關(guān)系

實(shí)際情況中豪娜,我們只有在垂直分表中使用。表中字段數(shù)過(guò)多哟楷,可以分為熱點(diǎn)字段和非熱點(diǎn)字段瘤载,我們可以根據(jù)這個(gè),利用主鍵卖擅,將這些字段拆分到不同的表中鸣奔。

一對(duì)多關(guān)系

實(shí)現(xiàn)2NF和3NF規(guī)范,我們就要用到一對(duì)多關(guān)系惩阶。

多對(duì)多關(guān)系

要想實(shí)現(xiàn)多對(duì)多關(guān)系挎狸,就需要引入一張中間表,中間表中的兩個(gè)字段存儲(chǔ)另外兩張表的主屬性(主鍵)

表用途

數(shù)據(jù)表

數(shù)據(jù)表(流水表)是有狀態(tài)的断楷,多筆業(yè)務(wù)之間沒(méi)有關(guān)聯(lián)锨匆,會(huì)有大量insert,update和查詢操作冬筒。是我們優(yōu)化的重點(diǎn)對(duì)象恐锣。

配置表

一些業(yè)務(wù)數(shù)據(jù)的配置,特點(diǎn)是數(shù)據(jù)量較小舞痰,而且結(jié)構(gòu)簡(jiǎn)單土榴,一般為靜態(tài)數(shù)據(jù),變化頻率很低响牛,但CRUD的場(chǎng)景比較多鞭衩。即使出現(xiàn)大量CRUD学搜,但數(shù)據(jù)量小,其實(shí)影響不大论衍。

其實(shí)配置表和數(shù)據(jù)表是一對(duì)多主外鍵關(guān)聯(lián)關(guān)系瑞佩。但我們會(huì)面臨一個(gè)問(wèn)題,就是配置表中的配置不是一成不變的坯台,那這個(gè)時(shí)候數(shù)據(jù)表中外鍵關(guān)聯(lián)的該項(xiàng)配置就跟著變了炬丸。其實(shí)到底變還是不變是根據(jù)實(shí)際業(yè)務(wù)需求來(lái)看的。根據(jù)后視鏡原則蜒蕾,我思考了一個(gè)比較好的方案稠炬,能夠滿足表范式規(guī)范,又能回溯數(shù)據(jù)咪啡。
配置表:(id,code,version,status...業(yè)務(wù)相關(guān)配置)
其中id為表主鍵首启,唯一;code為業(yè)務(wù)編碼撤摸,可以唯一標(biāo)識(shí)一個(gè)業(yè)務(wù)配置毅桃;version為該業(yè)務(wù)版本的版本號(hào)(code+version為主屬性,可以唯一標(biāo)識(shí)一筆數(shù)據(jù))stats為生效失效狀態(tài)(code+status也為主屬性准夷,也可以唯一標(biāo)識(shí)一筆數(shù)據(jù))钥飞。當(dāng)修改某一項(xiàng)配置的時(shí)候不進(jìn)行update,而是insert一條新的數(shù)據(jù)衫嵌,只是version+1读宙,然后上一筆失效。
數(shù)據(jù)表:(id,foreign1,foreign2,...其他數(shù)據(jù))
id為主鍵楔绞;對(duì)于外鍵關(guān)聯(lián)配置表的foreign结闸,我們到底選配置表的id,還是code+status(或者是code+version)酒朵?如果我們要求數(shù)據(jù)表中配置項(xiàng)不需要關(guān)聯(lián)最新配置膀估,而是保留當(dāng)時(shí)配置現(xiàn)場(chǎng)數(shù)據(jù),那么我們就選id為foreign耻讽;如果要求實(shí)時(shí)最新配置數(shù)據(jù)的時(shí)候察纯,我們就要選擇code+status為foreign。

數(shù)據(jù)庫(kù)級(jí)別配置

存儲(chǔ)引擎的選擇

InnoDB 存儲(chǔ)引擎支持事務(wù)针肥,一般業(yè)務(wù)系統(tǒng)特別是交易類系統(tǒng)饼记,都需要事務(wù)支持,所以只能選InnoDB慰枕。MyISAM特點(diǎn)是訪問(wèn)速度快具则,如果事務(wù)沒(méi)有要求,但有大量insert和select操作具帮,可以選擇博肋。

字符集選擇

從應(yīng)用(前后端)低斋,到數(shù)據(jù)庫(kù),我們都應(yīng)統(tǒng)一字符集匪凡,這樣可以避免字符集轉(zhuǎn)化帶來(lái)的性能損耗膊畴。推薦都使用UTF-8

事務(wù)隔離級(jí)別

MySql默認(rèn)的隔離級(jí)別是Repeatable-Read,但建議改為Read-Committed病游,更適合OLTP 業(yè)務(wù)場(chǎng)景唇跨。

表字段

1.定長(zhǎng)字符類型使用char(),但對(duì)于InnoDB存儲(chǔ)引擎衬衬,使用varchar要更好买猖。
2.變長(zhǎng)字符類型使用varchar(),但對(duì)于變長(zhǎng)字符應(yīng)該有個(gè)預(yù)估滋尉,不能統(tǒng)一初始化為varchar(500)等玉控。
3.整型定義中無(wú)需定義顯示寬度,比如:使用 INT狮惜,而不是 INT(4)高诺。
4.存儲(chǔ)精確浮點(diǎn)數(shù)必須使用 DECIMAL 替代 FLOAT 和 DOUBLE。
5.盡可能不使用 TEXT讽挟、BLOB 類型,如果必須使用丸冕,建議將過(guò)大字段或是不常用的描述型較大字段拆分到其他表中耽梅;另外,禁止用數(shù)據(jù)庫(kù)存儲(chǔ)圖片或文件胖烛。數(shù)據(jù)庫(kù)處理 TEXT眼姐、BLOB 類型相當(dāng)耗時(shí),特別是進(jìn)行刪除操作佩番。
6.日期類型選擇众旗,如果是年,用year(4)趟畏;如果是年月日贡歧,用DATE;如果是年月日時(shí)分秒赋秀,用DATETIME利朵。建議時(shí)間字段使用應(yīng)用生成,而不是數(shù)據(jù)庫(kù)猎莲。
7.建議字段定義為 NOT NULL绍弟。特別是索引列,因?yàn)镸ySQL對(duì)于null的列使得索引著洼,索引統(tǒng)計(jì)和值的比較都更復(fù)雜樟遣。
8.每個(gè)字段都要有注釋

索引使用

對(duì)于不同的存儲(chǔ)引擎而叼,支持的索引類型也不一樣,現(xiàn)在只討論InnoDB的B+樹索引豹悬,全文索引葵陵,HASH索引。但由于90%的情況都是使用B+樹索引屿衅,所以我們先討論埃难。
首先現(xiàn)解釋幾個(gè)概念
B+樹:
是一個(gè)特殊的查找樹,本文不展開篇幅進(jìn)行解釋涤久,但可以去看程序員小灰講解的B+樹涡尘,里面講解了什么是B+樹,以及為什么數(shù)據(jù)庫(kù)索引使用B+樹响迂。
聚集索引:
1.一張表有且只有一個(gè)聚集索引考抄。
2.如果表有主鍵,按表的主鍵構(gòu)造一個(gè)B+樹蔗彤,葉子節(jié)點(diǎn)存放表中行記錄數(shù)據(jù)川梅,稱為數(shù)據(jù)葉,數(shù)據(jù)頁(yè)以雙向鏈表進(jìn)行連接然遏,數(shù)據(jù)頁(yè)邏輯有序贫途。
3.如果沒(méi)有主鍵,MySQL也會(huì)建立一個(gè)聚集索引待侵,但索引列是數(shù)據(jù)庫(kù)生成的丢早。
非聚集索引(輔助索引):
1.一張表可以有多個(gè)。
2.葉子節(jié)點(diǎn)存放的是一個(gè)指向聚集索引的指針秧倾,通過(guò)該表的聚集索引查詢到數(shù)據(jù)頁(yè)怨酝,返回查詢的行數(shù)據(jù),即使用非聚集索引存在二次查詢問(wèn)題那先。
Cardinality(索引基數(shù)):
索引列中不重復(fù)記錄數(shù)量的預(yù)估值农猬。如果記錄都不重復(fù)(例如唯一約束字段,那么基數(shù)就為1)
單列索引:
定義一個(gè)索引對(duì)應(yīng)一個(gè)列售淡。
聯(lián)合索引:
定義一個(gè)索引對(duì)應(yīng)多個(gè)列斤葱。聯(lián)合索引我們要考慮最左原則,舉例說(shuō)明揖闸,建立一個(gè)聯(lián)合索引indx_abc(a,b,c)苦掘,where a=XX;where a=XX and b=XX;where a=XX and b=XX and c=XX;都是可以使用到該索引的,但是where b=XX;where c=XX;where b=XX and c=XX是不能使用到索引的楔壤。

那么總結(jié)一下我們使用索引的原則:
1.我們建表的時(shí)候一定要指定主鍵鹤啡,而且主鍵最好使用連續(xù)的數(shù)值類型,不要使用UUID蹲嚣。
2.要考慮數(shù)據(jù)列的Cardinality(索引基數(shù))递瑰,如果過(guò)小祟牲,則想想是否必要建立索引。
3.根據(jù)業(yè)務(wù)場(chǎng)景查詢的情況抖部,即where后的條件说贝,來(lái)思考如何建立索引,是建立單列索引還是聯(lián)合索引慎颗。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末乡恕,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子俯萎,更是在濱河造成了極大的恐慌傲宜,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件夫啊,死亡現(xiàn)場(chǎng)離奇詭異函卒,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)撇眯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門报嵌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人熊榛,你說(shuō)我怎么就攤上這事锚国。” “怎么了玄坦?”我有些...
    開封第一講書人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵血筑,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我营搅,道長(zhǎng)云挟,這世上最難降的妖魔是什么梆砸? 我笑而不...
    開封第一講書人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任转质,我火速辦了婚禮,結(jié)果婚禮上帖世,老公的妹妹穿的比我還像新娘休蟹。我一直安慰自己,他們只是感情好日矫,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開白布赂弓。 她就那樣靜靜地躺著,像睡著了一般哪轿。 火紅的嫁衣襯著肌膚如雪盈魁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,698評(píng)論 1 305
  • 那天窃诉,我揣著相機(jī)與錄音杨耙,去河邊找鬼赤套。 笑死,一個(gè)胖子當(dāng)著我的面吹牛珊膜,可吹牛的內(nèi)容都是我干的容握。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼车柠,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼剔氏!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起竹祷,我...
    開封第一講書人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤谈跛,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后溶褪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體币旧,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年猿妈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吹菱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡彭则,死狀恐怖鳍刷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情俯抖,我是刑警寧澤输瓜,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站芬萍,受9級(jí)特大地震影響尤揣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜柬祠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一北戏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧漫蛔,春花似錦嗜愈、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至毯盈,卻和暖如春剃毒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工赘阀, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留陪拘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓纤壁,卻偏偏與公主長(zhǎng)得像左刽,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子酌媒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 數(shù)據(jù)庫(kù)開發(fā)規(guī)范1. 數(shù)據(jù)庫(kù)命名規(guī)范前綴對(duì)象前綴命名: 前綴命名一般用小寫表的前綴: 業(yè)務(wù)模塊組名前綴存儲(chǔ)過(guò)程前綴:...
    PowerYangSoft閱讀 2,457評(píng)論 0 8
  • 回顧 字段類型(列類型):數(shù)值型欠痴,時(shí)間日期型和字符串類型 數(shù)值型:整型和小數(shù)型(浮點(diǎn)型和定點(diǎn)型) 時(shí)間日期型:da...
    翊溪閱讀 947評(píng)論 0 0
  • 索引 數(shù)據(jù)庫(kù)中的查詢操作非常普遍喇辽,索引就是提升查找速度的一種手段 索引的類型 從數(shù)據(jù)結(jié)構(gòu)角度分 1.B+索引:傳統(tǒng)...
    一凡呀閱讀 2,920評(píng)論 0 8
  • 命名規(guī)范 庫(kù)名、表名雨席、字段名必須使用小寫字母菩咨,并采用下劃線分割MySQL有配置參數(shù)lower_case_table...
    swoft_閱讀 629評(píng)論 0 0
  • 數(shù)據(jù)庫(kù)的基本是概念名詞解釋: 數(shù)據(jù)庫(kù)名詞解釋 元組:可以理解為表的每一行就是一個(gè)元組 候選碼:若關(guān)系中的某一屬性組...
    杰倫哎呦哎呦閱讀 1,114評(píng)論 0 6