為什么你不應該使用 MongoDB

jopen 11年前發布 | 45K 次閱讀 MongoDB

免責聲明:我不構建數據庫引擎,但搭建Web應用。每年我大約跑4-6個不同項目,所以我搭建了不少Web應用。我經歷過有不同需求及不同的數據存儲需求的應用。我部署過你聽說過或沒聽說過的的大部分數據存儲。

我也有幾次做出了錯誤的選擇。這是一個關于其中一次的故事——原本我們為什么選擇它,我們是如何發現它不合適,以及我們如何修復的。這一切都發生在一個開放源碼的名為Diaspora的項目中。

Diaspora項目

Diaspora 是一個有著悠久歷史的分布式社交網絡。早在2010年初,紐約大學四名大學生創建了一個Kickstarter視頻,目的是募集10000美元,耗費一個夏天來構建一個替代非死book的分布式項目。他們將它發送給朋友和家人,并希望有最好的結果。

但他們觸到了痛處。當時正好有另一起關于非死book的隱私丑聞,當塵埃落定,回到他們的Kickstarter項目時,他們已經從6400個不同的人那里籌集了超過200000美元,而同時這個軟件項目,卻連一行代碼都還沒有寫出來。

Diaspora是第一個大大超越其目標的Kickstarter項目。其結局是,他們的項目新聞被刊登于紐約時報——但它變成了一個丑聞,因為團隊照片 的背景黑板上面有一個骯臟的笑話,直到最終印刷都沒有人注意到這一點。這可是刊登在紐約時報!這個事件的余波實際上是我第一次聽說到這個項目。

他們在Kickstarter上成功的結果,是離開學校,來到San Francisco開始寫代碼。他們最后在我的辦公室工作。那時我在Pivotal實驗室工作,他們的一個哥哥也在那工作,所以Pivotal給他們提供 了免費的辦公空間、網絡,當然,裝有啤酒的冰箱。我白天和官方客戶工作,下班后和他們一起玩,周末貢獻代碼。

他們最后在Pivotal待了兩年多的時間。雖然只是在第一個暑假的結尾,他們已經有了一個最小化的,但已經可以使用(在某種意義上說)的一個分布式社交網絡,以Ruby on Rails實現,后端用MongoDB。

這里有很多流行詞匯,讓我們把它分解來看。

“分布式社交網絡”

如果你看過《社交網絡》,你就知道了所有你需要知道的關于非死book的事。它是個web應用,它在一個單邏輯服務器上運行,它可以讓你與朋友保持聯系。一旦你登錄,Diaspora的界面在結構上與非死book很相似:

為什么你不應該使用 MongoDB

Diaspora用戶界面的截圖

在中間有個信息流,顯示你所有朋友發布的信息,在邊上有一些其他隨機的基本沒人關注過的東西。Diaspora和非死book主要的技術差異在于對終端用戶的不可見性:它是“分布的”部分。

Diaspora的基礎設施并不在一個單獨的網絡地址上。有幾百個獨立的Diaspora服務器。代碼是開源的,所以如果你愿意,你可以建立自己的服務 器。各個服務器,被稱作一個pod,有它自己的數據庫和自己的用戶集合,并可以與其他擁有各自數據庫和用戶集的Diaspora pod進行交互操作。

為什么你不應該使用 MongoDB

不同規模的Pod互相交流,而沒有一個中央樞紐。

每個pod通過基于HTTP的API與其它pod通信。一旦你在一個pod上創建了一個帳號,它其實相當無聊,除非你關注一些其他人。你可以在你的pod 上關注其他用戶,而且你也可以關注其它pod上的用戶。當你關注的人在另一個pod上發布一個更新時,將會發生這些事情:


  1. 該更新會進入作者的pod的數據庫。
  2. 你的pod會通過API收到通知。
  3. 該更新被存入你的pod的數據庫。
  4. 你可以看看近期活動,將會發現這個發布與你關注的其他人的發布混在一起。

評論按同樣的方式運作。在任何單一的發布中,一些評論的評論人可能來自與發布作者相同的pod,而還有一些可能來自其他的pod。任何有權查看這個發布的人將會看到所有的評論,就像你期待的,好像每個人都在一個單一的邏輯服務器上一樣。

誰關心?

這個架構有技術上和法律上的優勢。技術上的主要優勢在于容錯機制

為什么你不應該使用 MongoDB

這是每個辦公室都應該有的一個重要的容錯系統。

如果pod中的任意一個宕機,這不會引起其他的也宕機。系統的生存,甚至期望,網絡的分割。對于這,有一些有趣的政治上的暗示——例如,如果你在一個關閉 了外接網絡而無法訪問非死book和推ter的國家,你的pod依舊會在本地運行,并和你所在國家內的其他人相連接,即使無法訪問外部。

主要的法律優勢是服務器的獨立性。每個pod都是一個法律獨立的實體,由其創建所在地的法律所掌管。每個pod也設置自己的服務條款。對于其中的大多數, 你可以在不放棄對內容權限的條件下發布內容,這與非死book不同。Diaspora是一個免費的軟件,其意義在于“免費”和“自由”,而且大多數運 行pod的人非常在意這種事情。

所以這就是這個系統的架構。我們再來從一個單一的pod看看這個架構。

這是一個 Rails 應用

每個pod都是一個Ruby on Rails應用,后端有一個數據庫,最初是MongoDB。從某種程度來說,這個代碼庫是一個‘典型’的Rails應用——它同時具有一個可視化與可編程的UI,一些Ruby代碼,以及一個數據庫。但在其他方面,它決不是典型的。

為什么你不應該使用 MongoDB

一個 Diaspora pod的內部結構

視覺UI顯然就是網站用戶與Diaspora交互的方式。這個API被各種Diaspora移動客戶端使用——這一部分相當典型——但同時它也被用 于"federation"(聯邦),這也是描述pod之間通訊的技術名詞。(我有一次問過這與羅慕倫人的相似點在哪里,結果得到一堆白眼,擦。)所以說 這個系統的分布式特性,給代碼庫增加了典型應用中所不存在的中間層。

當然,MongoDB是一種數據存儲的典型選擇。而絕大多數的Rails應用程序是由PostgreSQL(近來不常見)或MySQL所支持。

所以代碼部分就是這樣。我們再來考慮一下我們存儲的是什么樣的數據。

(譯注:羅慕倫帝國是科幻系列《星際旅行》中虛構的外星帝國,2158年,羅慕倫帝國與當時的地球聯邦發生了一場核戰爭。這場戰爭同時威脅到了其他的一些種族,并最終促使了星際聯邦的建立。2160年羅慕倫人被打敗,后與星際聯邦簽訂合約并劃定中立區。)

我不認為單詞的意思是你認為的意思

“社交數據”是關于我們朋友、他們朋友和他們活動的網絡信息。從概念上來看,我們確實認為它是一個網絡——一個以我們為中心,朋友圍繞在我們身邊的無向網絡。

為什么你不應該使用 MongoDB

所有照片來自rubyfriends.com。感謝Matt Rogers、Steve Klabnik、Nell Shamrell、Katrina Owen、Sam Livingston-Grey、Josh Susser、Akshay Khole、Pradyumna Dandwate和Hephzibah Watharkar對#rubyfriends的貢獻!

當我們存儲社交數據時,我們存儲的是那個圖的拓撲結構,和那些隨著邊移動的活動信息。

多年之后的今天,大家公認社交數據并不是關系型的,如果你把它存儲在關系型數據庫中,你就錯了。

但是,其它方案有哪些呢? 有人說圖數據庫更自然些,不過這里我不打算介紹它,因為圖數據庫太過小眾而不適合用于生產環境。另外一些人說文檔數據庫對社交數據來說堪稱完美,而且也更為主流化足以投入實際使用。下面,讓我們看看為什么人們認為社交數據更適合放在MongoDB里,而不是放在PostgreSQL里。

MongoDB 如何存儲數據

MongoDB是一個面向文檔的數據庫。它把你的數據存儲在由獨立的文檔組成的集合中,而不是像關系型數據庫那樣,存儲在由獨立的組成的中。在MongoDB中, 一個文檔是一大塊JSON數據,沒有特定的格式或模式。

比如說,你需要對下列一組關系進行建模。這和來自于Pivotal的一個使用了MongoDB的項目類似,是我見過的最適合于文檔數據庫的用例。

為什么你不應該使用 MongoDB

根元素是電視節目。每個節目有很多季,每一季都有很多片段,每個片段都有很多評論和演員表。當用戶進入這個網站后,一般都是直接訪問一個特定電視節目的頁 面。在這個頁面里他們可以看到所有的季、所有的片段、所有的評論和所有的演員表。從應用的角度來看,當用戶訪問一個頁面時,我們就將檢索所有有關電視節目的信息。

有很多方法可以為此數據建模。在典型的關系型數據存儲中,上面的每一個方框就是一個表。你必須有一個叫電視節目的表、一個有外鍵是電視節目的每一季表、一 個有外鍵是每一季的片段表以及外鍵是片段的評論表和演員表。所以,要得到電視節目的所有信息,你必須要在5個表中查詢。

我們也可以以這樣的數據作為一組嵌套的哈希值進行建模。有關特定電視節目的信息的集合是一個大的嵌套的keyvalue數據結構。 在電視節目里有一個季 節的數組,每一個季節是一個hash。 在每個季節里,每一個episodes都是一個hash等等. 這就是Mongo如何建立數據模型的. 每一個電視節目是一個包含我們需要的所有信息的文檔。

這是一個電視節目文檔的例子, Babylon 5.

為什么你不應該使用 MongoDB

它有一些標題的元數據,然后是一個季節的數組. 每個季節本身就是一個帶有元數據的哈希數組episodes. 反過來, 每個episode 都有一些reviews和cast_members的元數據和數組。

這就像是一個巨大的分形體數據結構。

為什么你不應該使用 MongoDB

集合的集合的集合的集合。就像是個分形體!

所有我們需要的電視節目數據都在一個文檔里,所以要檢索一次所有信息時是很快的,即使這個文檔很龐大。美劇“綜合醫院”發布了50+季,超過12000 集。在我的筆記本電腦上,PostgresSQL查詢所有數據得1分鐘,而在MongoDB中用一個ID查詢時是秒級。

所以,不管怎么說,這個應用對于存儲文檔模型還是不錯的選擇。

好吧,那社交數據又是怎樣的?

好的,當你進入社交網站后,映入眼簾的唯一重要頁面部分是你的活動流。活動流顯示了你所有關注人的信息,這些信息是按最新時間排序的。每一條信息里都是網狀結構,比如說圖片,喜歡,分享以及評論。

網狀結構的活動流看起來和上面提到的電視節目很相似。

為什么你不應該使用 MongoDB

用戶有朋友,朋友有帖子,帖子有評論和喜歡,每一個評論有一個評論者,每一個喜歡有一個喜歡的人。這種關系并不比電視節目的復雜。和電視節目一樣,當用戶 登錄后,我們就想一次取出所有的數據。此外,在關系數據庫中,所有的數據都是規格化的,這就得在7個表中查詢才能得到所有數據。

7個表聯合查詢。啊!如果將每個用戶的活動流作為一個大的非標準化的網狀結構來存儲的話,要比每一次連接查詢看起來要好的多。

在2010年時,Diaspora團隊做出了這個決定,并深受Etsy有關用文檔結構存儲文章的影響,盡管當時他們曾公開遠離了MongoDB數據存儲。 同樣的,非死book的Cassandra也曾呼喚要遠離關系數據庫。Diaspora與時俱進的選擇了MongoDB。從他們的信息數據來看,這樣 的選擇是明智的。

問題可能出在哪?

Diaspora的“社交數據”和TV show的Mongo風格數據之間有一個很重要的不同點,我們在開始時都沒有注意到。

TV Show中,數據關系表的每一部分都屬于不同的數據類型。TV Show,Seasons,Episodes,Reviews,Cast members,他們各不相同。

但對于“社交數據”,有一部分具有相同的數據類型。事實上,圖表中所有綠色部分所表示的都是同一種數據類型----Diaspora users

為什么你不應該使用 MongoDB

每個user具有一些friends,而每個friend可能自身就是一個user。或者說,他們也可能不是,因為這是一個分布式的系統。(我今天只是跳過了那整個層面的復雜性。)同樣的,commenters和likers也可能是users。

這種類型的重復性使得要想將活動流正規化到一個單獨的文檔變得更難。那是因為在你的文檔的不同部分,可能引用了相同的概念——在這個例子中,就是相同的 user。在活動流中喜歡(like)那個帖子(post)的user,可能也是評論(comment)另一個不同帖子(post)的user。

重復數據重復數據

在MongoDB中我們可以用幾種不同的方式來表示它。復制是一種簡單的選擇。在第一次提交的時候,friend的所有信息都被復制下來并被保存到 like,之后在第二次提交的時候,一個單獨的副本被保存到comment。這里的好處在于,在你需要數據的任何地方,它都是存在的,而且你仍然可以把整 個活動流作為一個單獨的文檔處理。

這里就是這類完全非規范化的流程文檔的樣子。

為什么你不應該使用 MongoDB

這里有內聯的user數據的拷貝。這個是Joe的數據流,而且在最頂級有他的用戶數據,包括他的name和URL。緊接著下來是他的數據流,包含有 Jane的帖子(post)。Joe喜歡(like)Jane的帖子,所以在Jane的帖子的喜歡者(likes)中,我們有Joe的數據的一個單獨的拷 貝。

你會明白為什么這樣做很有吸引力:所有你需要的數據在你需要的地方已經存在。

你也會同樣明白為什么這么做是危險的。更新一個user的數據,就意味著要查找所有他們出現過的活動流,以便在這些不同的地方更新這個數據。這很容易出錯,經常導致不一致的數據和奇怪的錯誤,特別是在處理刪除操作的時候。

就沒有希望了嗎?

在MongoDB中你可以采用另一種方法來解決這個問題,如果你有相關背景經驗的話會對此更熟悉。與復制用戶數據不同的是,你可以在活動流文檔中保存用戶的引用。

用這個方法,代替那種在需要的地方將用戶數據內聯進來的方法,你只需給每個user一個ID。一旦用戶具有了ID,我們就只需在之前內聯數據的地方保存這個用戶的ID。下面的這些新的ID是用綠色標識的。

為什么你不應該使用 MongoDB

MongoDB實際用的是BSON IDs(譯注:BSON是由10gen開發的一個數據格式,目前主要用于MongoDB中,是MongoDB的數據存儲格式),它就像是GUID的字符串形式, 但為了讓這些例子便于閱讀,這里我只是用了整數。

這消除了我們之前的重復的問題。當用戶數據改變時,只有一個文檔需要重寫。不過我們為我們自己帶來了一個新的問題。因為我們將一些數據移到了活動流之外, 我們再也不能從一個單獨的文檔構造一個活動流了。這使得效率降低,復雜性增加。現在構造一個活動流需要 1)檢索數據流文檔,然后 2)檢索所有用戶文檔以便填寫名字和頭像。

MongoDB缺少的是SQL風格的join操作,這種操作可以通過寫一條查詢語句,得到活動流與活動流所引用的所有用戶的混合結果。因為MongoDB不具備這種能力,取而代之的是,你必須在你的應用代碼中手工做這項混合工作。

簡單的非規范化數據

我們回頭看一看電視節目(TV shows),電視節目的關系集合沒有太多的復雜性。因為關系圖中所有的盒子是不同的實體,整個查詢可以整合進一個文檔,沒有重復沒有引用。在這個文檔數據庫中,文檔之間沒有鏈接。它不需要join。

然而在一個社交網絡中,沒有什么能像這樣獨立存在。在任何時候,只要你看到什么東西看起來像是一個名字或者一幅圖像,你就會希望能點擊它,看看那個用戶, 他們的個人資料,以及他們的帖子。TV show應用不是這樣運作的。如果你位于巴比倫5(Babylon 5)的第一季第一集,你不會希望點擊綜合醫院(General Hospital)的第一季第一集。

不要鏈接文檔

我們開始在Diaspora代碼中手工做這項煩人的MongoDB joins操作時,我們很清楚這只是麻煩的第一個跡象。這個跡象表明我們的數據實際是相互關聯的,這個數據結構具有價值,而且我們正在違背文檔數據庫的基本概念。

不管你是否在復制關鍵數據(天啊),或者使用引用并在應用代碼中執行join操作(天啊天啊),只要文檔之間有鏈接,你就已經超越了MongoDB。當 MongoDB愛好者用不同的方式說“文檔”的時候,他們的意思是那些你可以在一張紙上打印出來、拿在手里的東西。一個文檔可能具有內部結構——標題 (headings)、子標題(subheadings)、段落(paragraphs)和頁腳(footers)——但這并沒有鏈接到其它文檔。它是獨 立的半結構化數據。

如果你的數據看起來是那樣的,你只需文檔。祝賀你!對Mongo而言它是一個好的用例。但是如果文檔之間鏈接具有存在價值,那么實際上你擁有的就不是文 檔。對你來說MongoDB就不是正確的解決方案。當然它也不是社交型數據的解決方案,在那種數據中文檔之間的鏈接實際上是系統中最關鍵的數據了。

因此社交型數據不是面向文檔的。那是否這就意味著它實際上是……關系型的呢?

又是那個詞

當人們說“社交數據不是關系型數據”時,并不是他們說的意思。他們的意思是下面兩個方面:

1.“從概念上說,社交數據是一個比表集合更大的圖譜。”

這絕對是正確的。但是很少有概念自然的提及模式化表是標準化的。我們用結構化表示是因為它行之有效,這樣做可以減少冗余,而且我們可以解決它變慢的問題。

2.“當在非標準化的單文檔結構中查詢所有社交數據時是很快的。”

這也是絕對正確的。當你的社交數據是按照關系型存儲時,你為特定用戶取出活動流將要在許多表中查詢,并且當表越大速達越慢。然而,我們可以用簡單的方式來解決這個問題。那就是緩存。

在牛津早些年的數據庫會議中,我曾做過一個這樣的報告,我強烈推薦你看看Neha Narula談論有關緩存的報告。無論如何,緩存讓標準化數據存儲變得復雜,但行之有效。我也曾看過緩存非標準化的活動流為一個文檔結構,比如說MongoDB,它會讓檢索數據變得更快。但存在緩存失效的問題。

“在計算機學科中有兩個頭疼的問題:緩存失效和命名” Phil Karlton
他提出緩存失效的問題是很難解決的。Phil Karlton寫過SSL版本3、X11和OpenGL,所以他對計算機了解的還是很多的。


緩存失效作為一個服務

那什么是緩存失效,為什么解決它很難?

眾所周知,緩存失效就是緩存數據過期,它需要更新或是替換了。這里有個在網絡應用中經常見的例子。我們有個后臺存儲器,典型的是PostgreSQL或MySQL,前臺有一個緩存層,典型的結構是Memcached或Redis.請求讀取用戶的活動流時直接從緩存拿數據顯然要比從數據庫拿快的多。

為什么你不應該使用 MongoDB

典型的緩存和后臺存儲安裝

應用的寫操作更加復雜。讓我們說說兩個粉絲都寫了一個消息的情況。首先發生的就是(第一部分)這些消息被復制和存儲。一旦這些動作完成,后臺將進入下一段工作(第二部分)將這些消息放入所有粉絲的活動流緩存中。

這種模式是很常見的。推ter將近期活動用戶的活動流都放入內存緩存中,當有粉絲發送消息時也將這些消息添加到緩存中。甚至是很小應用使用這樣的活動流時也是這么做的(看看:7個表聯合查詢)。

回到我們的例子。當作者修改現存的帖子(post)時,更新過程在本質上與創建是一樣的,唯一不同的是它不是增加到緩存,而是更新一個已經存在的條目。

如果步驟2的后臺作業中途失敗會怎樣呢?機器重啟了,網絡線纜插頭被拔掉了,應用重啟了。在我們的工作中,不穩定是唯一不變的變量。當那些事情發生的時 候,你將會被緩存中的非法數據整崩潰。一些帖子的拷貝是舊的標題,而另一些拷貝卻是新的標題。這是一個嚴重的問題,但是對于緩存而言,經常會有這種毀滅式 的情況。

為什么你不應該使用 MongoDB

經常的一種情況 >_<

你完全可以從緩存中刪除整個活動流記錄,并從持久化的后臺存儲中重新生成它。這或許很慢,但至少這是可能的。

如果沒有后臺存儲又會怎樣呢?如果你跳過了步驟1呢?如果你僅僅只有緩存呢?

假如你只有MongoDB的話,它就是沒有后臺存儲的一個緩存。它將會產生不一致。不是最終的一致——而一直都是純粹的、徹頭徹尾的不一致。就這一點而言,你沒有選擇。即使毀滅式的也沒有。你沒有任何辦法重新生成一致狀態的數據。

當Diaspora項目決定將關系型數據存儲于MongoDB的時候,我們將數據庫與緩存合并起來。數據庫與緩存是非常不一樣的兩種事物。對于持久化、瞬態、復制、引用、數據完整性和速度,它們有完全不一樣的思想。

轉變

一旦我們理解了我們一不小心給數據庫選擇了一個緩存,那么我們是怎樣使用這個緩存的呢?

好吧,這是一個價值百萬美元的問題。但是我們已經回答了價值十億美元的問題。在這篇文章中,我已經談到了我們是如何使用MongoDB的,相對應的是,它 是如何設計其使用方法的。我已經談過這一點了,就仿佛所有的信息都是顯而易見的,只是Diaspora團隊在做出選擇之前沒有做充足的研究。

但是這些東西一點也不顯而易見。MongoDB文檔告訴你它擅長什么,卻沒有強調它不擅長什么。這很好理解。所有項目都是這么做的。但是其結果是,這使我們花費了大約六個月,聽到許多的用戶埋怨,并且做了大量的調查,才由此斷定我們使用MongoDB的方式不對。

沒有什么別的辦法,只有將數據從MongoDB中取出來,將它們遷移到一個關系型的存儲設備,在此過程中要盡我們最大努力處理我們發現的不一致的數據。數據轉變本身——由MongoDB導出,再導入到MySQL——非常簡單明了。其中的技術細節,可以看看《你所有的基礎配置2013》中幻燈片 。

損害

我們有八個月的生產數據,這大約對應于MySQL中的120萬行。我們耗費了四個雙周來開發這個轉換代碼,當我們開始實際實施的時候,主站有大約兩個小時 的宕機時間。對于一個處于初期測試版的項目來說,這實在令人無法接受。我們應該縮短這個宕機時間的,但是卻預估了八個小時的宕機時間,這樣的話兩個小時看 起來似乎還很漂亮。

為什么你不應該使用 MongoDB

還不壞

尾聲

還記得電視劇(TV show)的應用嗎?它是MongoDB的完美用例。每個劇集都是一個文檔,完全獨立的文檔。它不引用任何東西,沒有副本,而且數據沒有不一致的可能。

距離開發約過了三個月后,電視劇應用仍然在MongoDB基礎上很好的運行著。后來的一個星期一,在每周計劃會議上,有委托人告訴我們,有個投資人想要一 項新的功能:當他們在某一集節目中看到某個演員的時候,他們想要可以點擊該演員的名字,并看到這個人的整個電視職業生涯。他們想要該演員曾經出現過的所有 不同劇集的一個時間排序的列表。

我們將每個劇集保存為MongoDB中的一個文檔,其中包含了所有嵌套的信息,包括 整個演員班底。如果同樣的演員出現于兩個不同的戲,甚至是出現于同一個劇集,他們的信息在兩個地方都有保存。除了比較他們的名 字,我們沒有辦法識別出他們是否是同一個人。所以為了實現這個功能,我們必須搜索每個文檔,找尋用戶點擊的演員,并刪除重復記錄。啊,對了。最起碼,我們 需要刪除一次重復記錄,然后再維護演員信息的一個外部索引,就像任何其它的緩存一樣,它同樣也具有失效問題。

你來看看這是怎么回事

客戶期待的功能是如此微不足道。如果數據已經在關系存儲,它會一直在哪里。由于這是我們第一次嘗試說服項目經理,客戶并不需要它MongoDB。失敗后, 我們提供了一些便宜的替代品,如鏈接到IMDB搜索演員的名字的產品。這個公司從廣告賺錢,雖然如此,他們希望用戶留在自己的網站上,而不是去上IMDB 。

此功能要求最終促使該項目的轉換到PostgreSQL。當有更多的與客戶交流后,我們意識到,客戶企業看到把電視節目連接在一起很多價值。他們期望能夠看到,正在看的節目的導演,他的其他節目。也希望能夠看到,類似正在看的節目,其他本周發布的同一主題的節目。

這從根本上是一個溝通的問題,而不是技術問題。如果這些溝通已經提前發生了,如果我們花時間去真正了解客戶端是怎么看到數據的和他們想要對數據做什么的話,我們可能會早些時候做這樣一個溝通,那個時候有較少的數據,并且變更也較容易。

一直在學習中

我從經驗學到:MongoDB的理想使用場景是比我們的電視數據更窄。唯一的事情是擅長的是存儲任意個JSON數據。“任意”,在此背景下,意味著你不稀 罕什么是JSON里面。你甚至不看。沒有模式,甚至沒有一個隱含的模式,就猶如我們的電視節目數據。每個文件僅僅是一個blob數據,其內部數據是什么完 全不在意。

在RubyConf這個周末,我跑進康拉德歐文,誰提出這個用例。他用MongoDB的存儲JSON的任意位的是來自客戶通過一個API。這是合理的。這種帽子理論是完全不在意你的數據內容是否有意義。很有趣的是在應用程序中,你的數據很有意義的。

我已經聽到很多人談論到自己的web應用下探的MongoDB來替代MySQL或PostgreSQL。任何情況下,這都不是一個好主意。架構的靈活性聽 起來像一個偉大的想法,但只有一次,它是真正有用的是當你的數據的結構沒有任何價值。如果你有一個隱含的模式 - 這意味著,如果你期待返回JSON的數據 - 那么MongoDB是錯誤的選擇。我建議采取看看PostgreSQL的hstore(現在比MongoDB的速度快的),并學習如何進行更改架構。他們 真的并不難,即使是在大表。

尋找價值 

當你選擇一個數據存儲,應該了解最重要的事情就是你的數據在哪里,你的數據如何連接,你的數據的商業價值所在。如果你還不知道(這是正常的),那么選擇不 會畫你陷入了困境的數據存儲。推JSON數據到你的數據庫聽起來很靈活,但真正的靈活性是很容易添加業務需求de 功能。 

讓有價值的東西做起來更加容易。

</div>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!