標籤:
app後端的開發中,經常要面臨的一個問題是:資料放在哪裡? mysql ?redis?mongodb?
現在有這麼多優秀的開來源資料庫產品,怎麼根據業務情境來選擇合適的資料?
常用的資料庫產品的優缺點又是什麼呢?
通過閱讀這篇文章,能幫你解決以上的疑惑,使你在碰到資料存放區選擇問題時思路更清晰。
1. redis,mongodb,mysql儲存資料的區別
資料,就涉及讀和寫這兩個問題.出於效能的考慮,當然希望讀和寫的速度越快越好.
電腦中,資料一般都放在記憶體或硬碟,眾所周知,記憶體的讀寫速度比硬碟快多了。因此,為了獲得更快的讀寫速度,資料儘可能放在記憶體中。
但是,記憶體的容量是非常有限的,例如,在ucloud的伺服器上,最多隻能擁有16G的記憶體,而ucloud的伺服器上的單個硬碟,最多可高達1000G。
redis的資料是放在伺服器的記憶體中,當記憶體用滿了,redis就沒折了(現在只有第三方的分布式解決方案,官方的分布式方案要在3.0版本才會出。)。當然了,為了防止資料丟失,可通過設定檔,把資料在硬碟上做一個備份。
mongodb的資料主要是放在記憶體中,如果mongodb發現記憶體滿了,資料再也放不下了,mongodb就把新增的資料放在硬碟中。如果是採用分布式架構,那基本不用考慮資料會放在硬碟中。
mysql的資料是放在硬碟中。雖然mysql也有緩衝,但mysql緩衝的是查詢的結果,而不是快取資料。
2. redis,mongodb,mysql尋找資料的區別
如果你想在一棟大樓裡找某個房間,但是你不知道這個房間的門牌號,只記得這個房間的門是非常特別的,那找到這個房間唯一的方式只能每層樓逐個房間找一次,直到找到這個房間為止。
如果你知道了這個房間的門牌號,那很簡單,直奔那個樓層就是了。
redis的資料是基於“鍵值對”儲存,“鍵”相當於門牌號,“值”相當於房間。redis尋找資料,每次都是直奔目標,讀寫速度當然高。
mongodb和mysql中,每組資料都有一個id(或者可以為每組資料建索引),這個id或索引就相當於門牌號。
mongodb和mysql中尋找資料,有兩種模式,知道id或索引,和不知道知道id或索引。知道id或索引,就相當於知道門牌號,那就直奔目標就行了,效率很高。如果不知道id或索引的情況下尋找資料,那就相當於每層樓逐個房間找,效率很低。
3. redis,mongodb,mysql適用情境
redis適用情境:
資料讀寫速度快,但由於redis資料只存放在一台伺服器的記憶體中(現在只有第三方的分布式解決方案,官方的分布式方案要在3.0版本才會出來),所以儲存資料有限。
同時,由於redis存放的資料必須是鍵值對(key-value)的形式,在讀寫redis的資料時必須要知道鍵,這點需要考慮。
所以,在app後端中,最講求讀寫效率,最頻繁讀的資料一般都會放在redis中(當然,這部分資料同時也存在於mysql 或者mongodb中, redis中的資料是一個冗餘,當資料更新的時候,兩部分都要更新)。
舉例,在社交app中,很多操作都需要驗證使用者的登入資訊,那一般怎麼做的呢?
使用者登入後,伺服器會把一個token符串返回給使用者,假設這個token字串為"abcdsdf", 伺服器中已經登記了這個token符串,而且把這個tokentoken符串和使用者的資訊關聯在一起,通過這個token符串就能查詢到使用者的資訊。
當遇到需要驗證使用者的登入資訊,就把這個token字串傳給伺服器,伺服器根據這個token的資訊,在伺服器中尋找這個使用者的資訊。
在社交app中,大多數的操作都需要這個驗證,可以看出,是個很頻繁的操作,而且這個操作需要在極短的時間內完成。
那麼,這個token字串和使用者的資訊,就很適合放在redis中,把token字串當成一個key(鍵),使用者的資訊當成是value(值),尋找起來非常方便和高效。
當然了,驗證使用者的登入資訊還需要很多安全的措施,這裡只講一個最簡單的模型,在以後的《app通訊安全性》一文中會講完善的安全措施。
mongodb適用情境:
a.網站資料:mongo非常適合即時的插入,更新與查詢,並具備網站即時資料儲存所需的複製及高度伸縮性。
b.緩衝:由於效能很高,mongo也適合作為資訊基礎設施的緩衝層。在系統重啟之後,由mongo搭建的持久化緩衝可以避免下層的資料來源過載。
c.大尺寸、低價值的資料:使用傳統的關聯式資料庫儲存一些資料時可能會比較貴,在此之前,很多程式員往往會選擇傳統的檔案進行儲存。
d.高伸縮性的情境:mongo非常適合由數十或者數百台伺服器組成的資料庫。
e.儲存地理座標的資料。mongo支援非常強大的地理座標的查詢,例如,可以在某個矩形範圍內的使用者。非常適合於LBS的應用。
mongodb不適合的情境:
a.高度事物性的系統:例如銀行或會計系統。傳統的關係型資料庫目前還是更適用於需要大量原子性複雜事務的應用程式。
例如,涉及金錢的操作,假設要把轉賬,必須從一個帳號上扣錢,再在另外一個帳號上把錢轉賬。這個操作必須保證要麼兩個都完成,要麼兩個都不做,不能只做一個。但很遺憾,由於mongodb不支援事務,所以沒法保證。
b. 傳統的商業智慧應用:針對特定問題的BI資料庫會對產生高度最佳化的查詢方式。對於此類應用,資料倉儲可能是更合適的選擇。
c. 需要SQL的問題。雖然mongodb支援類似於sql的查詢方式,但它的查詢比起mysql還是有一定的差距。
mysql適用情境:
a. 事物性的系統。例如,在mongodb中舉例的轉賬的例子
b. 需要複雜SQL的問題。
簡單地來說,綜合考慮後,探索資料不適合放在redis和mongodb後,那就把資料放在mysql吧^-^
---------------------------------------------------------------------------------------------------------------------------
開啟連結 app後端系列文章總目錄 總目錄 ,能查看本人發表過的所有原創“app後端”文章。
【作者】曾健生
【QQ】190678908
【qq群】254659220
【公眾號】 appbackend
【新浪微博】 @newjueqi
【部落格】http://blog.csdn.net/newjueqi
12.app後端如何選擇合適的資料庫產品