【轉載】 做者:曾健生,公衆號ID:appbackendmysql
比目科技 Bmob後端雲程序員
app後端的開發中,常常要面臨的一個問題是:數據放在哪裏? mysql ?redis?mongodb?redis
如今有這麼多優秀的開源數據庫產品,怎麼根據業務場景來選擇合適的數據?sql
經常使用的數據庫產品的優缺點又是什麼呢?mongodb
經過閱讀這篇文章,能幫你解決以上的疑惑,使你在碰到數據存儲選擇問題時思路更清晰。數據庫
1. redis,mongodb,mysql存儲數據的區別後端
數據,就涉及讀和寫這兩個問題.出於性能的考慮,固然但願讀和寫的速度越快越好.緩存
計算機中,數據通常都放在內存或硬盤,衆所周知,內存的讀寫速度比硬盤快多了。所以,爲了得到更快的讀寫速度,數據儘量放在內存中。安全
可是,內存的容量是很是有限的,例如,在ucloud的服務器上,最多隻能擁有64G的內存,而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吧^-^