最近開始研究mysql和mongodb,發現這方面資料不多。尤其是真正的說到點子上的文章,太少了。
有一些對比測試的文章基本上都是瞎測,測試方法都測到了馬腿上,得出的結論基本上都是nosql毫無價值
容我借用russell smith 的那句話:不是mongodb不行,是你不懂。
讓我來分析一下mongodb的真正性能吧。
有說mongodb慢
反對:不設其他唯一索引的情況下,隻用_id 在普通辦公電腦上每秒插入幾萬,在普通x86伺服器上每秒插入十幾萬,你好意思說這個性能低?比mysql強出一個數量級。
贊同:檢索是真的慢,和sql資料庫不同,越複雜的條件搜尋mangodb越吃虧,cpu和io的雙重壓力。面對那些直接把sql查詢改寫成mangodb的用法,别轉了,你不會收獲任何性能提升。
你不行:說你不行還是真的不行,mongodb上司了nosql運動,nosql請注意,我們最主要反對的就是sql的方法論,按sql方法使用mangodb你隻能收獲失望。再想想mongodb的設計思想:文檔化。_id 就是檔案名,mongodb是個檔案系統。全文檢索?别鬧了,用檔案名找檔案,一個檔案名對應一個檔案,你絕對不會失望。
那麼mongodb究竟應該怎麼用呢?
<a target="_blank"></a>
你應該忘記你學過的那些優雅無敵的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而言,很正常。
<b> 原文釋出時間為:2013-05-08</b>
<b>本文來自雲栖社群合作夥伴“linux中國”</b>