從一道面試題想到的論壇數據庫設計

 一個簡單的論壇系統,以數據庫儲存如下數據:
用戶名,email,主頁,電話,聯繫地址,發帖標題,發帖內容,回覆標題,回覆內容。
每天論壇訪問量300萬左右,更新帖子10萬左右。
請給出數據庫表結構設計,並結合範式簡要說明設計思路。

    這是我看見的百度面試題,以前也在cdsn上面看見過類似的問題,沒有仔細想就寫了自己的見解和答

案,很可惜我以前的想法是錯誤的;算是誤人子弟阿,鬱悶!因此我還是先把和幾個朋友討論的結果和自

己的想法做一個總結,算是彌補我以前想法造成別人曲解的過錯;
    首先,我們先來分析一下這道面試題:用戶名,email,主頁,電話,聯繫地址,發帖標題,發帖內

容,回覆標題,回覆內容。這些字段可以基本歸爲三類:
    1、用戶基本信息:用戶名(UserName),email(Email),主頁(HomePage),電話(Tel),聯繫地址

(Address);
    2、發帖主題信息:發帖標題(Title),發帖內容(Content);
    3、回覆信息:回覆標題(RTitle),回覆內容(RContent);
     以上一步有基本開發經驗的人都知道,只是對基本的信息進行劃分;相信將用戶基本信息存放在一

張表內不會有什麼好討論的,我創建一張表叫T_Users,並建立主鍵UserID,用戶基本信息所需要存放的

內容都放置在此表內;那麼是應該把發帖主題和回覆信息分別創建兩張表存放數據呢還是應該存放在一張

表內?字段內容還是比較接近的,因此從數據冗餘的角度看,一張表和兩張表在此方面的區別並不影響設

計;假設按照大多數論壇的設計思路,將2、3設計成兩個表T_Topics和T_Reverts後,再來分析看看是否

合適這裏的要求;
    現在“每天論壇訪問量300萬左右,更新帖子10萬左右”對這句話進行分析,纔是這個面試題的關鍵

所在。面試題顯然要求在操作數據庫的性能方面要有更高的要求。而對數據庫的操作而言,檢索數據的性

能基本不會對數據造成很大的影響(精確查找的情況下),而對錶與表之間的連接卻會產生巨大的影響,

特別在有巨量數據的表之間;而對數據庫的連接也是相當消耗性能的操作(這在ADO.NET的教程中都多次

提醒的);因此對問題的定位基本可以確定:在顯示和檢索數據時,儘量減少數據庫的連接以及表與表之

間的連接;
    解決問題的指導性原則找到了,那就來看看,從上面的設計中,有哪一些地方會產生我們提到的表與

表之間的連接;(連接數據庫的次數儘量減少到每打開一個頁面只連接一次數據庫就可以得到所有的數據

)1、用戶基本信息中的用戶名在發帖主題列表以及打開一個主題查看回復內容時上面會有所顯示,需要

在T_Users和其他兩張表進行連接;2、在打開一個主題查看回復內容時,需要在T_Topics和T_Reverts之

間進行連接;其他應該是不需要產生表與表之間的連接;按照面試題來推測:T_Users的數據量應該在1萬

-10萬之間,T_Topics應該在100-1000萬之間,T_Reverts應該在1000萬-1億之間;從上面兩類連接可以看

出來,T_Users和T_Topics會在列表頁面連接一次;T_Users、T_Topics和T_Reverts三張表會連接一次;

我說不上來第一種連接是否可以允許(至少在我開發的系統裏面都是允許的),但是另外三張表連接是絕

對不會允許的!特別是T_Topics和T_Reverts兩表之間的連接會產生很大的性能損耗,因此需要避免這樣

的情況產生。
    那怎麼樣的設計可以避免T_Topics和T_Reverts兩表之間的連接呢?前面已經進行了分析:可以考慮

把發帖主題和回覆信息存放在一張表(T_Infos)裏面,看看是否可以解決這個問題;我們設計一個字段

(Flag)來標記是主題還是回覆的內容;設計一個字段(ParentID,主題此字段爲ID值)來指定是哪一個

特定主題的回覆;在開打回覆信息時,只需要按照所知道的主題ID,就可以檢索到這個主題的內容以及所

有的回覆內容,上面指出的問題就可以解決!
    爲了性能,我們再一次對T_Users和T_Infos連接對性能的影響進行一下細緻的分析,可以通過在

T_Infos表內增加UserName字段來解決和它的連接,這樣至少在顯示時,性能能夠得到保證;但是這樣的

設計因爲UserName字段是冗餘的,因此在用戶修改UserName的時候就會產生同步數據的問題,這個需要程

序來進行彌補,並是我們認爲用戶不會經常性的修改他的用戶名這樣的前提下;
    因此這道面試題的答案應該是設計兩張表,用戶基本信息表T_Users和內容表T_Infos,這兩張表的連

接還是通過UserID,但是T_Infos中增加UserName這個字段來增加性能!
    上面的面試題算是分析完了,但是從這道題目的分析中我們可以看出來,這樣的設計是建立在“一個

簡單的論壇系統”這樣的基礎上的極端事例,在我們真實的世界中,不太會有很多的人喜歡這樣簡單的論

壇,而且這樣的論壇在擴展性方面會產生很大的限制;這算不算這道題目是應試教育的產物呢?而且在設

計的時候不僅僅是爲了適應現在系統的需求還需要提供將來新的要求的變化,因此在實際的開發過程中間

並不推薦使用這道面試題的答案。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章