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