kalman03

          每天早上看一遍《福布斯》富翁排行榜,如果上面沒(méi)有我的名字,我就去學(xué)習(xí)......
          隨筆 - 22, 文章 - 0, 評(píng)論 - 86, 引用 - 0
          數(shù)據(jù)加載中……

          一個(gè)微博數(shù)據(jù)庫(kù)設(shè)計(jì)帶來(lái)的簡(jiǎn)單思考

                 在微博系統(tǒng)中,當(dāng)前用戶、關(guān)注者(也就是粉絲)、被關(guān)注者(崇拜對(duì)象)這三種角色是少不了的。他們之間看似簡(jiǎn)單的關(guān)系,但是其中數(shù)據(jù)庫(kù)表將如何設(shè)計(jì),卻讓我很難琢磨,在如下解決方案中,你們會(huì)選擇哪種?為什么要選擇這種?是否有更好的解決方案?

          解決方案一:

          表名

          用戶信息表

          字段名

          字段代碼

          字段類型

          描述

          用戶名

          User_id

          Varchar(20)

          主鍵

          登陸密碼

          Password

          Varchar(20)

          ……

          ……

          ……

          表名

          關(guān)注和被關(guān)注者表

          字段名

          字段代碼

          字段類型

          描述

          用戶名

          User_id

          Varchar(20)

          主鍵

          關(guān)注者

          Funs

          Text

           

          被關(guān)注者

          Wasfuns

          Text

              這是我最初想到的一種設(shè)計(jì),這里“關(guān)注者”和“被關(guān)注者”都是采用拼接一些特殊字符分割存儲(chǔ)的,比如A用戶有只有關(guān)注者BCDE,那么存入數(shù)據(jù)庫(kù)關(guān)注者字段的數(shù)據(jù)將是B;C;D;E(暫且認(rèn)為分割字符為;)。

          基于上述方案,我提出一個(gè)問(wèn)題:當(dāng)這個(gè)用戶的“關(guān)注者”或“被關(guān)注者”數(shù)量很大的情況下(比如10萬(wàn)個(gè)關(guān)注者)將是怎樣的一串字符呢?而且當(dāng)我們需要查詢“關(guān)注者”或者“被關(guān)注者”最近的博客信息,將面臨和博文信息表的一些時(shí)間排序查詢,處理難度是要浪費(fèi)性能的。

          解決方案二:

              基于上述面臨的問(wèn)題,有人給我提供了一個(gè)擴(kuò)展性的解決方案,同時(shí)也很好的解決了一個(gè)字段海量數(shù)據(jù)的問(wèn)題。將方案一中的關(guān)注和被關(guān)注者表分解成兩張表,如下:

          表名

          關(guān)注者表

          字段名

          字段代碼

          字段類型

          描述

          編號(hào)

          Id

          Number

          主鍵

          用戶名

          User_id

          Varchar(20)

          關(guān)注者編號(hào)

          Funs_id

          Varchar(20)

           

          表名

          被關(guān)注者表

          字段名

          字段代碼

          字段類型

          描述

          編號(hào)

          Id

          Number

          主鍵

          用戶名

          User_id

          Varchar(20)

          被關(guān)注者編號(hào)

          Wasfuns_id

          Varchar(20)

           

          我看到這樣的設(shè)計(jì)我很吃驚,試想一下,假如我一個(gè)用戶對(duì)應(yīng)有1W個(gè)關(guān)注者,那么該用戶就會(huì)在關(guān)注者表中存在一萬(wàn)條他的記錄,這難道不是嚴(yán)重的數(shù)據(jù)冗余嗎?這甚至不符合數(shù)據(jù)庫(kù)的設(shè)計(jì)規(guī)范。但是事實(shí)上證明,這種設(shè)計(jì)對(duì)大數(shù)據(jù)量的擴(kuò)展是很不錯(cuò)的,既然如此,那假如用戶和用戶之間的關(guān)系不只是限于關(guān)注和被關(guān)注的關(guān)系,是不是又要新增表

          解決方案三:

                   話說(shuō)“合久必分,分久必合”,對(duì)上述的設(shè)計(jì)再進(jìn)一步修改,于是將方案二的兩張表又合二為一,如下:

          表名

          關(guān)注和被關(guān)注者表

          字段名

          字段代碼

          字段類型

          描述

          編號(hào)

          Id

          Int

          主鍵

          用戶名

          User_id

          Varchar(20)

          目標(biāo)對(duì)象

          Operate_object

          Varchar(20)

           

          狀態(tài)

          Status

          Number

          當(dāng)目標(biāo)對(duì)象為關(guān)注者,標(biāo)示為1;

          當(dāng)目標(biāo)對(duì)象為被關(guān)注者,標(biāo)示為2;

          當(dāng)雙方互相關(guān)注,標(biāo)示為3;

          當(dāng)目標(biāo)對(duì)象為OO,標(biāo)示為XX。

          OK,這樣的設(shè)計(jì)不僅解決了相當(dāng)一部分的數(shù)據(jù)冗余,而且還能表示用戶之間的多種關(guān)系,方便系統(tǒng)日后的擴(kuò)展。但是問(wèn)題又出來(lái)了,很明顯這樣設(shè)計(jì)對(duì)狀態(tài)的維護(hù)也是存在疑問(wèn)的,用一張表代替多張表,數(shù)據(jù)肯定是成倍的增長(zhǎng),是否不符合當(dāng)前常說(shuō)的“拆庫(kù)拆表”的戰(zhàn)略方針(好像這樣的狀態(tài)一般用于“標(biāo)記男女”或者“是否刪除了”之類的,貌似用于這種場(chǎng)合比較的少)。

          在上述用戶關(guān)系的解決方案中,可以很簡(jiǎn)單的歸結(jié)為就是一對(duì)多,多對(duì)一,多對(duì)多的關(guān)系嘛,那么究竟如何設(shè)計(jì),究竟哪種更好,我很難理解,期待大家拍磚!

          posted on 2010-07-19 19:23 kalman03 閱讀(8291) 評(píng)論(13)  編輯  收藏 所屬分類: 數(shù)據(jù)庫(kù)

          評(píng)論

          # re: 一個(gè)微博數(shù)據(jù)庫(kù)設(shè)計(jì)帶來(lái)的簡(jiǎn)單思考  回復(fù)  更多評(píng)論   

          我認(rèn)為方案二是最清晰的
          2010-07-20 09:31 | cxh8318

          # re: 一個(gè)微博數(shù)據(jù)庫(kù)設(shè)計(jì)帶來(lái)的簡(jiǎn)單思考  回復(fù)  更多評(píng)論   

          方案3, 以后可以根據(jù)狀態(tài)做分區(qū)或者路由.
          2010-07-20 09:48 | dead_lee

          # re: 一個(gè)微博數(shù)據(jù)庫(kù)設(shè)計(jì)帶來(lái)的簡(jiǎn)單思考  回復(fù)  更多評(píng)論   

          為什么不是這樣呢
          create user (
          user_id varchar(20) primary key,
          password varchar(160)
          );
          create watches (
          id int primary key,
          watcher varchar(20),
          watchee varcher(20)
          );
          2010-07-20 09:54 | anon

          # re: 一個(gè)微博數(shù)據(jù)庫(kù)設(shè)計(jì)帶來(lái)的簡(jiǎn)單思考[未登錄](méi)  回復(fù)  更多評(píng)論   

          用戶表,用戶-崇拜對(duì)象表,用戶-粉絲視圖

          需要關(guān)注的是后兩者的數(shù)據(jù)量
          2010-07-20 10:16 | Wade

          # re: 一個(gè)微博數(shù)據(jù)庫(kù)設(shè)計(jì)帶來(lái)的簡(jiǎn)單思考  回復(fù)  更多評(píng)論   

          我認(rèn)為這三個(gè)方案的優(yōu)劣順序?yàn)?2>1>3, 3會(huì)讓處理邏輯變得非常復(fù)雜,其實(shí)方案2應(yīng)該只要一個(gè)表就可以了,fans表,因?yàn)殛P(guān)注和被關(guān)注是互逆的,查不同列就可以了,這樣的關(guān)系表最能體現(xiàn)數(shù)據(jù)庫(kù)管理數(shù)據(jù)的長(zhǎng)處。
          2010-07-20 15:21 | HiMagic!

          # re: 一個(gè)微博數(shù)據(jù)庫(kù)設(shè)計(jì)帶來(lái)的簡(jiǎn)單思考  回復(fù)  更多評(píng)論   

          很想知道sina圍脖的庫(kù)是怎么設(shè)計(jì)的,有知道的分享一下。
          2010-07-21 10:57 | Robin's Java World

          # re: 一個(gè)微博數(shù)據(jù)庫(kù)設(shè)計(jì)帶來(lái)的簡(jiǎn)單思考  回復(fù)  更多評(píng)論   

          @Robin's Java World
          我也很想知道
          2010-07-22 11:44 | kalman03

          # re: 一個(gè)微博數(shù)據(jù)庫(kù)設(shè)計(jì)帶來(lái)的簡(jiǎn)單思考  回復(fù)  更多評(píng)論   

          贊同@anon
          2010-07-26 16:15 | watcher

          # re: 一個(gè)微博數(shù)據(jù)庫(kù)設(shè)計(jì)帶來(lái)的簡(jiǎn)單思考  回復(fù)  更多評(píng)論   

          不知道為什么這么多人說(shuō)方案2好
          2011-04-08 13:15 | dohkoos

          # re: 一個(gè)微博數(shù)據(jù)庫(kù)設(shè)計(jì)帶來(lái)的簡(jiǎn)單思考  回復(fù)  更多評(píng)論   

          寫(xiě)錯(cuò)了,沒(méi)看清。
          如同HiMagic!和anon講的,其實(shí)方案2只要一張表就可以了
          create users (
          user_id varchar(20) primary key,
          password varchar(160)
          );
          create watches (
          id int primary key,
          watcher varchar(20),
          watchee varcher(20)
          );

          方案3是根本看不懂,不知道Operate_object這個(gè)是什么東西
          2011-04-08 13:19 | dohkoos

          # re: 一個(gè)微博數(shù)據(jù)庫(kù)設(shè)計(jì)帶來(lái)的簡(jiǎn)單思考[未登錄](méi)  回復(fù)  更多評(píng)論   

          可不可以這樣呢,讓數(shù)據(jù)適當(dāng)?shù)娜哂嘞拢?br>
          user
          {
          user_id,
          user_pwd,
          ……
          fansid,
          followersid
          }

          relationship --這個(gè)是互逆的
          {
          id,
          uid,
          fanid
          }
          2011-06-28 17:32 | shine

          # re: 一個(gè)微博數(shù)據(jù)庫(kù)設(shè)計(jì)帶來(lái)的簡(jiǎn)單思考[未登錄](méi)  回復(fù)  更多評(píng)論   

          方案2較好

          一個(gè)用戶,不會(huì)去關(guān)注數(shù)以萬(wàn)計(jì)的人。。。實(shí)踐證明,有幾千,已經(jīng)很很大了。

          但一個(gè)用戶,可能被數(shù)千萬(wàn)人關(guān)注,這個(gè)是重點(diǎn)要解決的數(shù)據(jù)膨脹。這個(gè)容易實(shí)現(xiàn)水平分割。
          2012-03-01 10:25 | allen

          # re: 一個(gè)微博數(shù)據(jù)庫(kù)設(shè)計(jì)帶來(lái)的簡(jiǎn)單思考  回復(fù)  更多評(píng)論   

          @anon
          比較贊成這種方式!第一種數(shù)據(jù)冗余,在數(shù)據(jù)量大時(shí),關(guān)系變更時(shí)操作復(fù)雜。第三種方案同樣的邏輯,關(guān)系變更時(shí)操作復(fù)雜!
          2016-02-17 13:50 | ManKane
          主站蜘蛛池模板: 天柱县| 洞口县| 竹山县| 茶陵县| 山阴县| 常宁市| 屯昌县| 宁夏| 仁寿县| 鄂托克前旗| 景德镇市| 海丰县| 永胜县| 犍为县| 清丰县| 怀来县| 松桃| 香港 | 彭山县| 姜堰市| 黄平县| 兴业县| 宁化县| 白城市| 澜沧| 清新县| 新沂市| 甘肃省| 仁怀市| 通州区| 武冈市| 勃利县| 昭觉县| 九台市| 兰考县| 永顺县| 庄浪县| 紫云| 岳普湖县| 榆社县| 张家川|