在微博系統(tǒng)中,當(dāng)前用戶、關(guān)注者(也就是粉絲)、被關(guān)注者(崇拜對象)這三種角色是少不了的。他們之間看似簡單的關(guān)系,但是其中數(shù)據(jù)庫表將如何設(shè)計,卻讓我很難琢磨,在如下解決方案中,你們會選擇哪種?為什么要選擇這種?是否有更好的解決方案?
解決方案一:
|
用戶信息表
|
字段名
|
字段代碼
|
字段類型
|
描述
|
用戶名
|
User_id
|
Varchar(20)
|
主鍵
|
登陸密碼
|
Password
|
Varchar(20)
|
|
……
|
……
|
……
|
|
|
|
|
|
|
關(guān)注和被關(guān)注者表
|
字段名
|
字段代碼
|
字段類型
|
描述
|
用戶名
|
User_id
|
Varchar(20)
|
主鍵
|
關(guān)注者
|
Funs
|
Text
|
|
被關(guān)注者
|
Wasfuns
|
Text
|
|
這是我最初想到的一種設(shè)計,這里“關(guān)注者”和“被關(guān)注者”都是采用拼接一些特殊字符分割存儲的,比如A用戶有只有關(guān)注者B、C、D、E,那么存入數(shù)據(jù)庫關(guān)注者字段的數(shù)據(jù)將是B;C;D;E(暫且認(rèn)為分割字符為;)。
基于上述方案,我提出一個問題:當(dāng)這個用戶的“關(guān)注者”或“被關(guān)注者”數(shù)量很大的情況下(比如10萬個關(guān)注者)將是怎樣的一串字符呢?而且當(dāng)我們需要查詢“關(guān)注者”或者“被關(guān)注者”最近的博客信息,將面臨和博文信息表的一些時間排序查詢,處理難度是要浪費(fèi)性能的。
解決方案二:
基于上述面臨的問題,有人給我提供了一個擴(kuò)展性的解決方案,同時也很好的解決了一個字段海量數(shù)據(jù)的問題。將方案一中的關(guān)注和被關(guān)注者表分解成兩張表,如下:
|
關(guān)注者表
|
字段名
|
字段代碼
|
字段類型
|
描述
|
編號
|
Id
|
Number
|
主鍵
|
用戶名
|
User_id
|
Varchar(20)
|
|
關(guān)注者編號
|
Funs_id
|
Varchar(20)
|
|
|
被關(guān)注者表
|
字段名
|
字段代碼
|
字段類型
|
描述
|
編號
|
Id
|
Number
|
主鍵
|
用戶名
|
User_id
|
Varchar(20)
|
|
被關(guān)注者編號
|
Wasfuns_id
|
Varchar(20)
|
|
我看到這樣的設(shè)計我很吃驚,試想一下,假如我一個用戶對應(yīng)有1W個關(guān)注者,那么該用戶就會在關(guān)注者表中存在一萬條他的記錄,這難道不是嚴(yán)重的數(shù)據(jù)冗余嗎?這甚至不符合數(shù)據(jù)庫的設(shè)計規(guī)范。但是事實(shí)上證明,這種設(shè)計對大數(shù)據(jù)量的擴(kuò)展是很不錯的,既然如此,那假如用戶和用戶之間的關(guān)系不只是限于關(guān)注和被關(guān)注的關(guān)系,是不是又要新增表?
解決方案三:
話說“合久必分,分久必合”,對上述的設(shè)計再進(jìn)一步修改,于是將方案二的兩張表又合二為一,如下:
|
關(guān)注和被關(guān)注者表
|
字段名
|
字段代碼
|
字段類型
|
描述
|
編號
|
Id
|
Int
|
主鍵
|
用戶名
|
User_id
|
Varchar(20)
|
|
目標(biāo)對象
|
Operate_object
|
Varchar(20)
|
|
狀態(tài)
|
Status
|
Number
|
當(dāng)目標(biāo)對象為關(guān)注者,標(biāo)示為1;
當(dāng)目標(biāo)對象為被關(guān)注者,標(biāo)示為2;
當(dāng)雙方互相關(guān)注,標(biāo)示為3;
當(dāng)目標(biāo)對象為OO,標(biāo)示為XX。
|
OK,這樣的設(shè)計不僅解決了相當(dāng)一部分的數(shù)據(jù)冗余,而且還能表示用戶之間的多種關(guān)系,方便系統(tǒng)日后的擴(kuò)展。但是問題又出來了,很明顯這樣設(shè)計對狀態(tài)的維護(hù)也是存在疑問的,用一張表代替多張表,數(shù)據(jù)肯定是成倍的增長,是否不符合當(dāng)前常說的“拆庫拆表”的戰(zhàn)略方針(好像這樣的狀態(tài)一般用于“標(biāo)記男女”或者“是否刪除了”之類的,貌似用于這種場合比較的少)。
在上述用戶關(guān)系的解決方案中,可以很簡單的歸結(jié)為就是一對多,多對一,多對多的關(guān)系嘛,那么究竟如何設(shè)計,究竟哪種更好,我很難理解,期待大家拍磚!