有說MongoDB慢
反對:不設其他唯一索引的情況下,只用_id 在普通辦公電腦上每秒插入幾萬,在普通x86伺服器上每秒插入十幾萬,你好意思說這個效能低?比mysql強出一個數量級。
贊同:檢索是真的慢,和sql資料庫不同,越複雜的條件搜尋MangoDB越吃虧,CPU和IO的雙重壓力。面對那些直接把SQL查詢改寫成MangoDB的用法,別轉了,你不會收穫任何效能提升。
你不行:說你不行還是真的不行,MongoDB領導了NoSQL運動,NoSQL請注意,我們最主要反對的就是SQL的方法論,按SQL方法使用MangoDB你只能收穫失望。再想想MongoDB的設計思想:文檔化。_id 就是檔案名稱,MongoDB是個檔案系統。全文檢索索引?別鬧了,用檔案名稱找檔案,一個檔案名稱對應一個檔案,你絕對不會失望。
那麼MongoDB究竟應該怎麼用呢?
首先,忘記SQL
你應該忘記你學過的那些優雅無敵的SQL,不是說為了提升檢索效能,扔索引就有好處。
有一個簡單的事實如下:只有一個預設的_id 索引,此時插入效能為1,你再加一個索引,插入效能約1/2,再加一個約1/3 ,以此類推......
如果這個事實對你是很震撼的,那說明你還沒有忘記SQL,接著忘。
MongoDB的索引對插入效能有著不可忽略的拖後腿效應,所以,我們應該使用且僅使用 _id 作為插入key,作為查詢key,作為所有的那個key。
其次,直接忘記搜尋這件事。
把MongoDB當做你的硬碟,給他檔案名稱去操作檔案.這就是Key-Value資料庫的做法,你稍加設計就能這麼用。
那麼其實你所有的操作可以簡化為兩個指令,邏輯上 就是一個字典
你給他_id,往字典裡插一個資料,或者拿一個資料。
- Save({_id:xxx,.....})
- FindOne({_id:xxx})
要想高效能,善用那個_id,把你原來準備當主鍵的那個玩意,hash成_id.
把你原來準備的查詢條件,什嗎?查詢,拿_id來,別的全砍掉。
第三、這不是資料表
記住,這不是資料表,一個_id對應的東西不是一行資料,而是一個檔案。
檔案儲存體和表格儲存體有什麼不同呢?
我舉個例子,比如我們要儲存使用者列表和每個使用者的道具列表。
資料表的做法是建一張使用者表,一張道具表,道具表裡有個欄位表示他屬於哪個使用者。
然後,你就離不開萬惡的查詢了。
然後如果一個使用者有100條道具,100萬使用者意味著道具表有一億條記錄。
這時候就開始考驗你的小資料庫了,但這都是過去式了,這一億的道具,用MongoDB,根本不是個事兒
因為MongoDB的方法是當做檔案存,只設計一個使用者集合,每個使用者的資訊是一個檔案,然後這100個道具就分開存在每個使用者的檔案裡。
然後來比較一下,我們取得使用者的記錄,然後從中拿出100個道具,NoSQL方法。
查一億的表,找出屬於某個使用者的記錄。
熟快熟慢?
然後你可能回想,SQL方法,我也可以搞個道具欄位,把使用者的100個道具用某種協議打包,然後操作啊,一樣可以取得巨大的最佳化呀。
沒錯,你的想法很好,你正在用NOSQL的方式用SQL。
第四、檔案儲存體的精華之處
如果問題止於此處,MongoDB就毫無優勢可言了,如果這個方法在SQL資料庫上也是如此容易使用,那還費勁搞MongoDB幹什嗎?
我們再折騰一點,如果每個道具還要存100條轉手記錄,你還是可以打包,但你這個打包欄位已經1M了。
於是每次存取這個打包欄位都是一個系統工程了,還要負擔1M的流量。
MongoDB這邊呢?我們可以直接對檔案的一部分進行讀寫,比如我只返回一個使用者的第二個道具的資訊,和返回第二個道具的第1~30條轉手記錄。
這,是一種怎樣的差距啊。
你想要一張美女的照片,你朋友有,但是他只有一個壓縮包,他那裡沒有解包工具,於是他把整個包傳給了你。他想問你要一張照片,但是他沒有壓縮公用程式,為了存檔需要,他讓你再壓進包裡傳給他。
這個朋友就是你的使用者表的一行,如果換成真實世界的事件是多麼的不可思議,這就是在一個欄位裡打包資料的問題。
MongoDB的一條記錄就是一個腦筋更正常的朋友,你要他一張照片,他從包裡找出來給你。你給他一張照片,他分門別類的放置到他的包裡去。
用檔案的思維去訪問,MongoDB是一個更好的朋友。
審視一下你項目中的大部分的資料需求,是不是都可以用這種方式去組織呢?
如果是,加入NOSQL吧,我們的口號是:很暴力不SQL
還有什麼好處
1.不用邏輯關心的水平切分
無需多言,對MongoDB而言,這是營運人員的工作了
2.不用對齊的資料結構
不用對齊意味著你不用為以前表結構變化的遷移煩惱,有些檔案裡有一個部分,有些沒有,這對MongoDB而言,很正常。
編輯精選】
- Craigslist採用MongoDB替代MySQL
- MongoDB源碼分析--Command體系架構
- Mongodb源碼分析--記憶體檔案對應(MMAP)
- 淺析Mongodb源碼之遊標Cursor
- 如何解決PHP+MySQL出現亂碼的現象