MongoDB資料建模小案例:朋友圈評論內容管理

葉翔mongodb發表於2016-12-09

需求

社交類的APP需求,一般都會引入“朋友圈”功能,這個產品特性有一個非常重要的功能就是評論體系。
先整理下需求:

  • 這個APP希望點贊和評論資訊都要包含頭像資訊:

    1. 點贊列表,點贊使用者的暱稱,頭像;
    2. 評論列表,評論使用者的暱稱,頭像;
  • 資料查詢則相對簡單:

    1. 根據分享ID,批量的查詢出10條分享裡的所有評論內容;

建模

不好的

跟據上面的內容,先來一個非常非常”樸素”的設計:

{
  "_id": 41,
  "username": "小白",
  "uid": "100000",
  "headurl": "http://xxx.yyy.cnd.com/123456ABCDE",
  "praise_list": [
    "100010",
    "100011",
    "100012"
  ],
  "praise_ref_obj": {
    "100010": {
      "username": "小一",
      "headurl": "http://xxx.yyy.cnd.com/8087041AAA",
      "uid": "100010"
    },
    "100011": {
      "username": "mayun",
      "headurl": "http://xxx.yyy.cnd.com/8087041AAB",
      "uid": "100011"
    },
    "100012": {
      "username": "penglei",
      "headurl": "http://xxx.yyy.cnd.com/809999041AAA",
      "uid": "100012"
    }
  },
  "comment_list": [
    "100013",
    "100014"
  ],
  "comment_ref_obj": {
    "100013": {
      "username": "小二",
      "headurl": "http://xxx.yyy.cnd.com/80232041AAA",
      "uid": "100013",
      "msg": "good"
    },
    "100014": {
      "username": "小三",
      "headurl": "http://xxx.yyy.cnd.com/11117041AAB",
      "uid": "100014",
      "msg": "bad"
    }
  }
}

可以看到,comment_ref_objpraise_ref_obj兩個欄位,有非常重的關係型資料庫痕跡,猜測,這個系統之前應該是放在了普通的關係型資料庫上,或者設計者被關係型資料庫的影響較深。而在MongoDB這種文件型資料庫裡,實際上是沒有必要這樣去設計,這種建模只造成了多於的資料冗餘。

另外一個問題是,url佔用了非常多的資訊空間,這點在壓測的時候會有體現,頻寬會過早的成為瓶頸。同樣username資訊也是如此,此類資訊相對來說是全域性穩定的,基本不會做變化。並且這類資訊跟隨評論一起在整個APP中流轉,也無法結局”使用者名稱修改“的需求。

根據這幾個問題,重新做了優化的設計建議。

推薦的設計

{
  "_id": 41,
  "uid": "100000",
  "praise_uid_list": [
    "100010",
    "100011",
    "100012"
  ],
  "comment_msg_list": [
    {
      "100013": "good"
    },
    {
      "100014": "bad"
    }
  ]
}

對比可以看到,整個結構要小了幾個數量級,並且可以發現url,usrname資訊都全部不見了。那這樣的需求應該如何去實現呢?

從業務抽象上來說,url,username這類資訊實際上是非常穩定的,不會發生特別大的頻繁變化。並且這兩類資訊實際上都應該是跟uid繫結的,每個uid含有指定的url,username。是最簡單的key,value模型。所以,這類資訊非常適合做一層快取加速讀取查詢。

進一步的,每個人的好友基本上是有限的,頭像,使用者名稱等資訊,甚至可以在APP層面進行快取,也不會消耗移動端過多容量。但是反過來看,每次都到後段去讀取,不但浪費了移動端的流量頻寬,也加劇了電量消耗。

總結

MongoDB的文件模型固然強大,但絕對不是等同於關係型資料庫的粗暴聚合,而是要考慮需求和業務,合理的設計。有些人在設計時,也會被文件模型誤導,三七二十一一股腦的把資訊塞到一個文件中。反而最後會帶來各種使用問題。


相關文章