數(shù)據(jù)庫(kù)設(shè)計(jì)的重要性與原則

隨著工作經(jīng)驗(yàn)的積累,我日益感覺(jué)到,對(duì)一名程序員來(lái)說(shuō),擁有良好的數(shù)據(jù)庫(kù)設(shè)計(jì)能力是很重要的,甚至是最重要的。

程序員界有一句著名的話

Talk is cheap, show me the code

把這句話演變一下,就成了

Code is boring, show me the data structure

數(shù)據(jù)庫(kù)的種類很多,對(duì)于像作者這樣的web后端程序員來(lái)說(shuō),可以把范圍縮小到關(guān)系型數(shù)據(jù)庫(kù)、非關(guān)系型數(shù)據(jù)庫(kù)與NoSQL數(shù)據(jù)庫(kù)。

數(shù)據(jù)結(jié)構(gòu)為何如此重要

一切代碼都是圍繞數(shù)據(jù)結(jié)構(gòu)運(yùn)行的。

客戶端展現(xiàn)的動(dòng)態(tài)數(shù)據(jù),都是存儲(chǔ)在數(shù)據(jù)庫(kù)中,這對(duì)程序員來(lái)說(shuō)一定是常識(shí)了。拿你正在瀏覽的這個(gè)頁(yè)面為例,文章的作者、標(biāo)題、正文、評(píng)論、喜歡等等,只要你打開(kāi)任意兩篇文章,兩個(gè)頁(yè)面不一樣的地方,幾乎都是因?yàn)樵跀?shù)據(jù)庫(kù)中存儲(chǔ)的內(nèi)容不同。

良好的數(shù)據(jù)結(jié)構(gòu)可以提升性能,使代碼變得簡(jiǎn)單、清晰。數(shù)據(jù)結(jié)構(gòu)清晰了,圍繞著數(shù)據(jù)運(yùn)行的代碼自然就清晰了。

數(shù)據(jù)庫(kù)設(shè)計(jì)需考慮的因素

提到數(shù)據(jù)庫(kù)設(shè)計(jì)原則,首先會(huì)想到第一、第二、第三范式,這些理論能了解最好,但這不是本文探討的主題。

面對(duì)一個(gè)具體的應(yīng)用場(chǎng)景,設(shè)計(jì)數(shù)據(jù)庫(kù)時(shí)應(yīng)考慮哪些因素?為了能夠言之有物,我們拿簡(jiǎn)書(shū)的文章頁(yè)面來(lái)現(xiàn)身說(shuō)法。

當(dāng)前可用性

數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)要能達(dá)到應(yīng)用場(chǎng)景的要求,這是最基本的。舉個(gè)例子,這篇文章的正文存儲(chǔ)在了數(shù)據(jù)表中的某個(gè)字段,該字段的長(zhǎng)度被設(shè)定為1000字,這顯然不能滿足應(yīng)用場(chǎng)景的要求,文章寫到這里已經(jīng)超過(guò)了1000字(估計(jì)的,我沒(méi)有數(shù))。

適當(dāng)超前

超前到什么程度需要根據(jù)對(duì)應(yīng)用的預(yù)期來(lái)定。拿QQ來(lái)說(shuō),馬化騰最初肯定預(yù)見(jiàn)不到QQ能有目前的用戶量與活躍度,畢竟那是近20年前的事情了。

對(duì)于本文設(shè)定的應(yīng)用場(chǎng)景,我們把超前設(shè)定為網(wǎng)站的文章數(shù)量達(dá)到了千萬(wàn)級(jí)。這時(shí)如果只把文章存在一張數(shù)據(jù)表里,讀寫性能必然是會(huì)急劇下降的,這必然會(huì)導(dǎo)致用戶體驗(yàn)變差,用戶流失。老板不能容忍,DBA也不能容忍。

合理的解決方案之一是分為兩張數(shù)據(jù)表,一張存儲(chǔ)熱門文章,另一張存儲(chǔ)非熱門文章。畢竟熱門文章占少數(shù),熱門文章的加載速度相對(duì)就更快了。還有別的解決方案嗎?肯定有,留給您自己思考。

分離易變與不易變部分

對(duì)于一篇文章來(lái)說(shuō),哪些是易變的,哪些是不易變(不變)的?

不易變(不變)

作者

標(biāo)題

正文(字?jǐn)?shù))

發(fā)布時(shí)間

更新時(shí)間

易變

閱讀次數(shù)

評(píng)論

喜歡該文章的用戶與數(shù)量

拆分的好處在于,首先數(shù)據(jù)結(jié)構(gòu)更清晰了,其次可以提高讀寫性能,當(dāng)文章有了新評(píng)論,只需更新存放評(píng)論的數(shù)據(jù)表。如果不拆分,需要更新的記錄占用的磁盤空間很大,這對(duì)磁盤IO速度是個(gè)考驗(yàn)。

對(duì)于拆分出的部分,可以繼續(xù)運(yùn)用這些原則進(jìn)行設(shè)計(jì)。

應(yīng)對(duì)可能出現(xiàn)的新需求

互聯(lián)網(wǎng)應(yīng)用的迭代周期很短,設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)時(shí)應(yīng)考慮到可能出現(xiàn)的新需求。拿喜歡該文章的用戶與數(shù)量舉例。

為了達(dá)到應(yīng)用的要求,最簡(jiǎn)單的方式是將這些用戶放在一條記錄里,存儲(chǔ)的字段可以是數(shù)組類型。這樣設(shè)計(jì),喜歡文章的用戶信息與用戶數(shù)量都能輕易獲取,讀寫性能也很好。

某天,產(chǎn)品經(jīng)理找到了你:“商量個(gè)新需求唄”,在文章下方加個(gè)模塊,就叫“喜歡該文章的人還喜歡了”。你就懵逼了,沒(méi)法破,除非重新設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu),然后就帶來(lái)了遷移數(shù)據(jù)一系列事情。其實(shí)這個(gè)需求挺合理的,說(shuō)得高大上一點(diǎn),這叫“精準(zhǔn)推薦”。

很明顯,將用戶放在數(shù)組里只能支持“查詢喜歡某文章的用戶”,不支持“查詢某用戶喜歡的文章”。

適當(dāng)?shù)娜哂?/p>

或許你已經(jīng)注意到了,文章的標(biāo)題下面有這篇文章的字?jǐn)?shù)。計(jì)算文章的字?jǐn)?shù),有兩個(gè)時(shí)機(jī):

保存文章時(shí)

讀取文章時(shí)

后者的優(yōu)勢(shì)在于數(shù)據(jù)表中少了一個(gè)字段,而且這個(gè)字段不是必需的。哪個(gè)時(shí)機(jī)更好?個(gè)人覺(jué)得前者更好,理由如下:

計(jì)算長(zhǎng)篇文章的字?jǐn)?shù)是比較耗時(shí)的,應(yīng)盡量減少計(jì)算次數(shù)

總體來(lái)看,文章的保存次數(shù)遠(yuǎn)小于讀取次數(shù)

如果能夠提高應(yīng)用的性能,適當(dāng)?shù)娜哂嗍潜匾摹?/p>

結(jié)尾

本文總結(jié)了設(shè)計(jì)數(shù)據(jù)庫(kù)時(shí)需遵守的幾個(gè)原則

可用性

適當(dāng)超前

應(yīng)對(duì)新需求

分離易變與不易變部分

適當(dāng)冗余

因?yàn)樽灾€未達(dá)到數(shù)據(jù)庫(kù)專家的水準(zhǔn),寫出的內(nèi)容肯定有不準(zhǔn)確的地方,歡迎批評(píng)指正。

寫這篇文章的想法醞釀很久了,但一直沒(méi)時(shí)間動(dòng)筆。適逢中秋佳節(jié),上海下著大雨,不便出門行走,便安坐在電腦前敲下了這千八百字,前后花了兩個(gè)多小時(shí)。如果喜歡就點(diǎn)贊,能指出不足或提出意見(jiàn)就更好了。

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

相關(guān)閱讀更多精彩內(nèi)容

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