標籤:style blog color ar os 使用 sp strong 檔案
序)Nosql並不是要取代原有的資料產品,而是為不同的應用情境提供更多的選擇。
一)結構類型
傳統資料庫的領域在於結構化文檔,對於非結構化文檔和半結構化文檔,它能處理,但是有一定的缺陷,那麼什麼又是結構化文檔,概括如下:
結構化資訊——這種資訊可以在關聯式資料庫中找到,多年來一直主導著IT應用。這是關鍵任務OLTP系統業務所依賴的資訊,另外,還可對結構資料庫資訊進行排序和查詢;
半結構化資訊——這是IT的第二次浪潮,包括電子郵件,文文書處理檔案以及大量儲存和發布在網路上的資訊。半結構化資訊是以內容為基礎,可以用於搜尋,這也是Google存在的理由;
非結構化資訊——該資訊在本質形式上可認為主要是位映射資料。資料必須處於一種可感知的形式中(諸如可在音頻、視頻和多媒體檔案中被聽或被看)。許多大資料都是非結構化的,其龐大規模和複雜性需要進階分析工具來建立或利用一種更易於人們感知和互動的結構。
二)MongoDB和行導向資料庫的區別
老實說,我覺得Nosql領域比較奇葩的東西算是Hive,不過在此不介紹它,對於項目中使用到MongoDB,也是有一定原因的,我一直以為Nosql這種東西和行導向資料庫並不衝突,它僅僅是行導向資料的一個補充,對於MongoDB,它和我們用的mysql,Oracle等有什麼區別,曾經我也尋找過一些東西,發現網上很多相關的文章都是千篇一律,幾乎一模一樣,沒啥價值,於是捉摸自己總結下。
舉個栗子:
在上面的表中,很直接,資料也很直觀,但是如果我們需要儲存另外一個東西:頭像,一般人會這樣幹:
uid |
name |
age |
photo |
1 |
張三 |
18 |
./upload/1.png |
儘管不同資料庫都提供了直接儲存二進位的資料庫欄位,但是我還是會選擇以上的儲存方式,我相信也有很多人也會這樣做,這樣做其實沒有什麼不好,但是如果我們的檔案很大,幾個GB,那麼無論讀還是寫都會很耗時,成為系統的瓶頸,基於這種情況,才會誕生雲端運算以及Nosql這些東西,也就是說Hadoop,Hbase等誕生的原因是:
多年來磁碟儲存容量快速增加的同時,訪問速度-磁碟資料讀取速度卻未能與時俱進,定址時間的提高遠遠慢於傳輸速率的提高,定址是將磁碟移動到特定磁碟位置進行讀寫操作,它是導致磁碟操作延遲的主要原因,而傳輸速率取決與磁碟的頻寬。
於是人們想出了一個辦法:既然在一個伺服器讀取一個檔案需要100個小時,那麼將檔案放在100個伺服器,每個伺服器放1%的資料,那麼1小時就搞定了,這也是Hadoop的核心思想,MongoDB資料庫繼承了這一思想,它的區塊劃分,以及節點分裂,都延續了這樣的思想,另一方面,MongoDB又吸取了memcached的東西,提前申請一片記憶體地區以及檔案地區,將記憶體中的地址和物理地址對應起來,可以極高的提高速度,這也是MongoDB相當的消耗記憶體和磁碟的原因之一。
三)MongoDB應用範圍
1:MongoDB與傳統資料庫整合:
id |
user_id |
title |
content |
time |
1 |
張三 |
文章標題 |
文章內容 |
時間 |
在以上表中,如果內容是一個包含上千上萬字的文章,一般會該欄位的內容丟入MongoDB,然後在此放入MongoDB的ID。
2:MongoDB取代傳統資料庫:
在某些事物要求不高的場合,以及允許出現部分錯誤的系統中,可以使用MongoDB取代傳統資料庫,例如論壇,部落格等系統,舉個栗子:
部落格有人發表了一篇文章,MongoDB儲存如下:
> db.article.insert({"title":"測試文章","content":"測試內容", "time":"17822455", "uid":"1"});WriteResult({ "nInserted" : 1 })> db.article.findOne();{ "_id" : ObjectId("546168c9573c0742d8be1544"), "title" : "測試文章", "content" : "測試內容", "time" : "17822455", "uid" : "1"}>
現在有一個人對這篇文章進行了評論,如下:
> var articleInfo = db.article.findOne({"_id":ObjectId("54616db1d92589121def0c70")});> articleInfo;{ "_id" : ObjectId("54616db1d92589121def0c70"), "title" : "測試文章", "content" : "測試內容", "time" : "17822455", "uid" : "1"}> articleInfo.commentary={"uid":"2",info :{"content":"這篇文章不錯","times":"145881444"}};{ "uid" : "2", "info" : { "content" : "這篇文章不錯", "times" : "145881444" }}> db.article.update({"_id": ObjectId("54616db1d92589121def0c70")},articleInfo);WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.article.findOne({"_id":ObjectId("54616db1d92589121def0c70")});{ "_id" : ObjectId("54616db1d92589121def0c70"), "title" : "測試文章", "content" : "測試內容", "time" : "17822455", "uid" : "1", "commentary" : { "uid" : "2", "info" : { "content" : "這篇文章不錯", "times" : "145881444" } }}>
現在又有一個人對它評論如下:
於是MongoDB的儲存結構成了這樣:
> db.article.update({"_id":ObjectId("54617115d92589121def0c72")}, {"$push": {"commentary":{"uid":3,info :{"content":"我也這篇文章不錯","times":"1444"}}}});WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.article.findOne({"_id":ObjectId("54617115d92589121def0c72")});{ "_id" : ObjectId("54617115d92589121def0c72"), "title" : "測試文章", "content" : "測試內容", "time" : "17822455", "uid" : "1", "commentary" : [ { "uid" : 2, "info" : { "content" : "這篇文章不錯", "times" : "1444" } }, { "uid" : 3, "info" : { "content" : "我也這篇文章不錯", "times" : "1444" } } ]}>
由此可見,如果再有評論,繼續往後加就OK,MongoDB對此的儲存是一目瞭然,伸縮性很強,如果不能夠在代碼中實現對資料一致性的處理,那麼還是使用回關係型資料庫為妙,在這種事務性不太強的場合,使用MongoDB是可以取代掉關係型資料庫的。
四)MongoDB使用
由於之前使用logback處理日誌,自己還得寫一大堆的shell指令碼,各種awk處理文本分析使用者行為丟入postgres,可能自己技術不到家,但是自己能夠想出的東西也就這些,於是在這個項目中毅然決定用MongoDB作為日誌分析系統。如果不在分布式中,使用Nosql沒有價值,碼字太辛苦了。。
(原)MongoDB在系統中的使用