我們先看看在mongodb下,Blog表是如何描述的:
var BlogScheme = new db.Schema({
title : String,
desc : String,
author : String,
body : String,
tags : [String],
count: { type:Number, default:0 },
hidden : { type: Boolean, default: false },
date : { type: Date, default: Date.now },
comments : [{ img: String, name: String, body: String, date: Date }],
meta : {
votes: Number,
favs: Number
}
});
按照mongodb的設計,每篇Blog都是整篇儲存的,與其它表基本沒有關聯,這也是NoSQL的精髓啊!但是這樣子,我們該如何去統計Blog的標籤tag呢?
這是我在網上摘抄的一篇文章。
其中關於NOSQL設計的一些原則。就是一篇文章就是一個表,基本上不與其他表聯絡,裡面的評論直接放在了blog裡面。我想問的是,如果這樣做,怎麼分頁呢???
比如評論分頁,,
還有就是nosql的設計原則是什嗎?有類似於關係型資料庫的範式之說嗎?
我還找到了一篇文章:
http://www.cnblogs.com/AllenDang/p/3507821.html#!comments
基本上其設計思路就是上面我提到的:將blog和評論放在一起。
這樣做是減少了很多查詢的。
但是出現了一個問題,如果使用者的暱稱變了。
那豈不是每一個這個使用者評論的的blog都要去修改了????
關係型資料庫,修改一下,然後join查詢自然就是最新結果。
請問在mongodb裡面該如何設計或者處理這種問題?
回複內容:
我們先看看在mongodb下,Blog表是如何描述的:
var BlogScheme = new db.Schema({
title : String,
desc : String,
author : String,
body : String,
tags : [String],
count: { type:Number, default:0 },
hidden : { type: Boolean, default: false },
date : { type: Date, default: Date.now },
comments : [{ img: String, name: String, body: String, date: Date }],
meta : {
votes: Number,
favs: Number
}
});
按照mongodb的設計,每篇Blog都是整篇儲存的,與其它表基本沒有關聯,這也是NoSQL的精髓啊!但是這樣子,我們該如何去統計Blog的標籤tag呢?
這是我在網上摘抄的一篇文章。
其中關於NOSQL設計的一些原則。就是一篇文章就是一個表,基本上不與其他表聯絡,裡面的評論直接放在了blog裡面。我想問的是,如果這樣做,怎麼分頁呢???
比如評論分頁,,
還有就是nosql的設計原則是什嗎?有類似於關係型資料庫的範式之說嗎?
我還找到了一篇文章:
http://www.cnblogs.com/AllenDang/p/3507821.html#!comments
基本上其設計思路就是上面我提到的:將blog和評論放在一起。
這樣做是減少了很多查詢的。
但是出現了一個問題,如果使用者的暱稱變了。
那豈不是每一個這個使用者評論的的blog都要去修改了????
關係型資料庫,修改一下,然後join查詢自然就是最新結果。
請問在mongodb裡面該如何設計或者處理這種問題?
nosql比較寬泛,不同的資料庫設計原則不同。
比如mongoDB和redis都屬於nosql,但是一個是文檔型,一個是KV型,設計原則的區別特別大。
mongoDB的設計原則還是比較靠近關係型資料庫,它的collection和table比較類似,也是insert、remove、update、find這幾個基本操作,可以參考關係型資料庫來設計。但是它比關係型關係靈活。
比如:一條微博可以插入9張圖片,如果在MySQL中,可能這樣設計:微博是一個table,圖片資訊是一個table,兩隻表做關聯。或者這樣設計:在微博那個table中加一個足夠大的字串類型的欄位叫img_info,裡面存放9張圖片資訊的json字串。
而在mongoDB中,天生就是支援上述的第二種設計的。記住,是天生支援,也是就天生對img_info裡面內容crud操作都異常方便。
然後回到你說的分頁的問題:
分頁主要就是用到2個函數:limit和skip
但是,資料量太大的時候,就不適合用skip分頁了。
《MongoDB權威指南》中給出的解決方案是:擷取上一頁的最後一條資料,然後使用gt和limit擷取下一頁的資料。
關於redis的,@馬鈴薯2015 同學已經說的很詳細了,就不累述了。
提醒@馬鈴薯2015 一下,mongoDB是將部分資料做記憶體映射,最大化利用記憶體,持久化還是會儲存在磁碟中的。如果沒有持久化,把mongoDB重啟一下,資料不就都沒有了啊。就算是redis這樣純記憶體型資料庫,也是有資料持久化的。
你說的精髓的確是這樣,但是只說對了一半,對於一篇博文來說評論的確可以做屬性,但是評論的鍵你卻沒有選好,應該使用user_id來規避你說的暱稱改變帶來的問題。(你沒有辦法把所有東西全部塞到一個document裡面對吧,你總有user_info集對吧)
所以mongodb的設計精髓並不是一味提倡你反範式,而是要懂得取捨。
再說說你問的統計tag的問題。
單看你的blog實體的tag設計成了list結構
就像是
tags = { "blog_id_111_tag": ["NBA", "姚明", "季後賽"],}
要統計的辦法其實很多,你應該是想統計topic_1下的博文有多少,topic_2下的博文又有多少對吧。其實也很好統計,在python中你可以使用字典推導式把這個tag反轉。如下:
tag_mapper = {v:k for k in tags for v in tags[k]}#這樣你就得到了{ "NBA": "blog_id_111_tag", "姚明": "blog_id_111_tag", "季後賽": "blog_id_111_tag"}
每篇博文都採取這樣的方式統計,就能夠統計出每個tag下面有哪些同類的博文了。
1.非關係型資料庫產品的實質是關係型資料庫產品的功能閹割版。通過閹割【關係】等功能,來擷取更高的效能,以及更方便的使用性。
2.從上述實質出發,非關係型資料庫產品適合用來做資料倉儲。因為資料倉儲中的資料的特點是量大、關係鬆散。
3.但是,非關係型資料庫由於效能高,因此不少的人開始打它的主意,想把關係型資料也丟進來。這樣做肯定有問題,因為你站在代碼層上,試圖自己在沒有關係功能的非關係型資料庫引擎上,自己來維護關係功能,肯定會付出昂貴的代價。這個代價可能是:
----1.非常低的效率。比如試圖把一個分布在關係型資料庫中多個屬性工作表中的對象,組合回一個大對象放在非關係型資料庫裡,導致每次查詢一個屬性時,引擎不得不把整個大對象提取出來。
----2.非常髒的資料。由於大部分非關係型資料庫產品無多表、庫事務,因此有人通過建立單獨的關係庫,來維繫兩個不同對象的庫的關係。但由於無事務,導致幾個操作無法保證事務原子,因此經常產生衝突,導致資料“變髒”。
4.綜上,當你滿腦子都是如何處理強關係時,請不要堅持用非關係型資料庫,不然你肯定會被坑。
對於關係型資料庫來說,ACID是強一致性的四個要求(ACID:atomicity, consistency, isolation, durability;)
而BASE是NoSQL資料庫通常對可用性及一致性的弱要求原則,BASE:Basically Available, Soft-state, Eventually Consistent。
nosql是不管關係結構的,但是我們可以利用已有的資料庫結構來構造關係!
mongodb我沒用過,我nosql用的redis.處理分頁如下:
先有一個全量的blog list,只存blog.id。比如名字叫list:blog.
再有一個hash對應blog資料結構.命名可以這樣blog:<#id>。
建立一個blog的時候,結合redis的transaction>>start
redis:rpush('list:blog', <#blog.id>);//先往list存id
redis:hmset('blog:'+<#blog.id>, 'title', ..., 'content', ....)//再存hash
transaction<<
分頁的時候結合sort limit命令操作list和hash
sort list:blog limit 0 10 get # get blog:->title get blog:->content
當然還可以根據blog的某些屬性進行sort
sort list:blog by blog:->createtime desc limit 0 10 get # get blog:->title get blog:*->content
至於評論的分頁做法類似。
從你的問題上看出來,你的資料完全依賴mongodb,完全是依賴記憶體的,你的資料持久化是在哪裡呢?
我來發表一下自己的見解吧:
講要更新的資料放在一個集合,而不是將要顯示的資料放在一個集合。那麼將評論放在blog表就是錯誤的了。
因為無法解決這樣的問題:
使用者的暱稱更新了怎麼辦。
因此,設計原則就是將要更新的放在一起。
去範式,分布式