NoSQL入門)(詳細)

NoSQL入門

(原創:黑小子-餘)

 

一、NoSQL是什麼

NoSql(NoSQL=Not Only SQL),意即「不只僅是SQL」,泛指菲關係型數據庫。傳統的關係數據庫在應付web2.0網站,特別是超大規模和高併發的SNS類型的web2.0純動態網站已經顯得力不從心,暴露了不少難以克服的問題,而非關係型的數據庫則因爲其自己的特色獲得了很是迅速的發展。NoSQL數據庫的產生就是爲了解決大規模數據集合多重數據種類帶來的挑戰,尤爲是大數據應用難題,包括超大規模數據的存儲。html

(例如谷歌或Facebook天天爲他們的用戶收集萬億比特的數據)。這些類型的數據存儲不須要固定的模式,無需多餘操做就能夠橫向擴展。java

 

二、爲何要用NoSQL

在90年代,一個網站的訪問量通常都不大,用單個數據庫徹底能夠輕鬆應付。在那個時候,更多的都是靜態網頁,動態交互類型的網站很少。mysql

後來,隨着訪問量的上升,幾乎大部分使用MySQL架構的網站在數據庫上都開始出現了性能問題,web程序再也不僅僅專一在功能上,同時也在追求性能。程序員們開始大量的使用緩存技術來緩解數據庫的壓力,優化數據庫的結構和索引。開始比較流行的是經過文件緩存來緩解數據庫壓力,可是當訪問量繼續增大的時候,多臺web機器經過文件緩存不能共享,大量的小文件緩存也帶了了比較高的IO壓力。在這個時候,Memcached(分佈式緩存)就天然的成爲一個很是時尚的技術產品。linux

 

(1)Memcached(緩存)+MySQL+垂直拆分git

Memcached做爲一個獨立的分佈式的緩存服務器,爲多個web服務器提供了一個共享的高性能緩存服務,在Memcached服務器上,又發展了根據hash算法來進行多臺Memcached緩存服務的擴展,而後又出現了一致性hash(Hash算法也被稱爲散列算法,Hash算法雖然被稱爲算法,但實際上它更像是一種思想。Hash算法沒有一個固定的公式,只要符合散列思想的算法均可以被稱爲是Hash算法)來解決增長或減小緩存服務器致使從新hash帶來的大量緩存失效的弊端。程序員

 

(2)Mysql主從讀寫分離github

因爲數據庫的寫入壓力增長,Memcached只能緩解數據庫的讀取壓力。讀寫集中在一個數據庫上讓數據庫不堪重負,大部分網站開始使用主從複製技術來達到讀寫分離,以提升讀寫性能和讀庫的可擴展性。Mysql的(主)master-slave(從)模式成爲這個時候的網站標配了。web

 

(3)分表分庫+水平拆分+mysql集羣面試

在Memcached的高速緩存,MySQL的主從複製,讀寫分離的基礎之上,這時MySQL主庫的寫壓力開始出現瓶頸,而數據量的持續猛增,因爲MyISAM使用表鎖,在高併發下會出現嚴重的鎖問題,大量的高併發MySQL應用開始使用InnoDB引擎代替MyISAM。算法

MyISAM:默認表類型,屬於索引組織表;它是基於傳統的ISAM類型,ISAM是Indexed Sequential Access Method (有索引的順序訪問方法) 的縮寫,它是存儲記錄和文件的標準方法。不是事務安全的,並且不支持外鍵,若是執行大量的select,insert MyISAM比較適合。

InnoDB:有兩種存儲方式,共享表空間存儲和多表空間存儲,兩種存儲方式的表結構和myisam同樣,以表名開頭,擴展名是.frm。支持事務安全的引擎,支持外鍵、行鎖、事務是他的最大特色。若是有大量的update和insert,建議使用InnoDB,特別是針對多個併發和QPS(Queries Per Second意思是「每秒查詢率」)較高的狀況,是一臺服務器每秒可以相應的查詢次數,是對一個特定的查詢服務器在規定時間內所處理流量多少的衡量標準。

同時,開始流行使用分表分庫來緩解寫壓力和數據增加的擴展問題。這個時候,分表分庫成了一個熱門技術,是面試的熱門問題也是業界討論的熱門技術問題。也就在這個時候,MySQL推出了還不太穩定的表分區,這也給技術實力通常的公司帶來了但願。雖然MySQL推出了MySQL Cluster(集羣),但性能也不能很好知足互聯網的要求,只是在高可靠性上提供了很是大的保證。

 

(4)MySQL的擴展性瓶頸

MySQL數據庫也常常存儲一些大文本字段,致使數據庫表很是的大,在作數據庫恢復的時候就致使很是的慢,不容易快速恢復數據庫。好比1000萬4KB大小的文本就接近40GB的大小,若是能把這些數據從MySQL省去,MySQL將變得很是的小。關係數據庫很強大,可是它並不能很好的應付全部的應用場景。MySQL的擴展性差(須要複雜的技術來實現),大數據下IO壓力大,表結構更改困難,正是當前使用MySQL的開發人員面臨的問題。

 

 

(5)爲何使用NoSQL ?

今天咱們能夠經過第三方平臺(如:Google,Facebook等)能夠很容易的訪問和抓取數據。用戶的我的信息,社交網絡,地理位置,用戶生成的數據和用戶操做日誌已經成倍的增長。咱們若是要對這些用戶數據進行挖掘,那SQL數據庫已經不適合這些應用了, NoSQL數據庫的發展也卻能很好的處理這些大的數據。

 

三、NoSQL能幹什麼

 易擴展:NoSQL能幹什麼?簡單來講:它的特色就是去掉關係數據庫的關係型提醒。數據之間無關係,這樣就很是容易擴展,也無形之間,在架構的層面上帶來了可擴展的能力。

大數據量高性能:.NoSql數據庫都具備很是高的讀寫性能,尤爲在大數據下,一樣表現優秀。這得益於它的無關係行、數據庫結構簡單。

通常MySQL使用Query Cache(查詢緩存),每次表的更新Cache就失效,是一種大粒度的Cache。在針對web2.0的交互頻繁的應用,Cache性能不高,而NoSQL的Cache是記錄級的。是一種細粒度的Cache,因此NoSQL在這個層面上來講就要性能高不少了。

多樣靈活的數據模型:NoSql無需事先爲要存儲的數據創建字段,隨時能夠存儲自定義,也就是建立本身的數據格式。而在關係數據庫中,增、刪字段是一件很是麻煩的事情,若是是很是大的數據量的表,增長一個字段那你就會想死。

 

(1)傳統RDBMS VS NoSql:

RDBMS(傳統的關係型數據庫)高度組織化結構化數據結構化查詢語言(SQL)、數據和關係都存儲在單獨的表中、數據操縱語言,數據定義語言、嚴格的一致性。

ACID原則A(Atomicity)原子性、C (Consistency)一致性、I (Isonlation)隔離性、D (Durability)持久性

 

NoSQl(非關係型數據庫)表明着不只僅是SQL、沒有聲明性查詢語言、沒有預約義的模式、鍵-值對存儲,列查詢,文檔存儲,圖形數據庫、最終一致性,而非ACID屬性、高性能,高可用和高可伸縮性,

CAP原則:(又稱CAP定理)指的是在一個分佈式系統中,

一致性(Consistency),數據一致更新,全部數據變更都是同步的。

可用性(Availability),好的響應性能。

分區容錯性(Partition tolerance),可靠性。這三個要素最多隻能同時實現兩點,要麼AP,要麼CP,要麼AC,可是不存在CAP,也就是不能三者兼顧,就像「魚和熊掌二者不可兼得」。

 

四、分類

(1)鍵值(Key-Value)存儲數據庫

這一類數據庫主要會使用到一個哈希表,這個表中有一個特定的鍵和一個指針指向特定的數據。Key/value模型對於IT系統來講的優點在於簡單、易部署。可是若是DBA只對部分值進行select或update的時候,Key/value就顯得效率低下了。(舉例如:Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB)。

(2)列存儲數據庫

這部分數據庫一般是用來應對分佈式存儲的海量數據。鍵仍然存在,可是它們的特色是指向了多個列。這些列是由列家族來安排的。如:Cassandra(開源分佈式混合型的非關係的數據庫), HBase(分佈式的、面向列的開源數據庫), Riak(分佈式高可用鍵值對數據庫)。

(3)文檔型數據庫

文檔型數據庫的靈感是來自於Lotus Notes(是一個世界領先的企業級通信、協同工做及Internet/Intranet平臺)辦公軟件的,並且它同第一種鍵值存儲相相似。該類型的數據模型是版本化的文檔,半結構化的文檔以特定的格式存儲,好比JSON。文檔型數據庫可 以看做是鍵值數據庫的升級版,容許之間嵌套鍵值。並且文檔型數據庫比鍵值數據庫的查詢效率更高。如:CouchDB(開源的面向文檔的數據庫管理系統), MongoDb(分佈式文件存儲的數據庫,介於關係數據庫和非關係數據庫之間的產品), 國內也有文檔型數據庫SequoiaDB(金融級分佈式關係型數據庫),已經開源。

(4)圖形(Graph)數據庫

圖形結構的數據庫同其餘行列以及剛性結構的SQL數據庫不一樣,它是使用靈活的圖形模型,而且可以擴展到多個服務器上。NoSQL數據庫沒有標準的查詢語言(SQL),所以進行數據庫查詢須要制定數據模型。許多NoSQL數據庫都有REST式的數據接口或者查詢API。如:Neo4J(高性能的,NOSQL圖形數據庫,它將結構化數據存儲在網絡上而不是表中), InfoGrid(post關係web應用程序的平臺), Infinite Graph(圖形類數據庫)。

 

 

五、體系框架

NoSQL框架體系NosoL總體框架分爲四層,由下至上分爲數據持久層(data persistence)、總體分佈層(data distribution model)、數據邏輯模型層(data logical model)、和接口層(interface),層次之間相輔相成,協調工做。

(1)數據持久層:定義了數據的存儲形式,主要包括基於內存、基於硬盤、內存和硬盤接口、訂製可拔插四種形式。基於內存形式的數據存取速度最快,但可能會形成數據丟失。基於硬盤的數據存儲可能保存好久,但存取速度較基於內存形式的慢。內存和硬盤相結合的形式,結合了前兩種形式的優勢,既保證了速度,又保證了數據不丟失。訂製可拔插則保證了數據存取具備較高的靈活性。

(2)數據分佈層:定義了數據是如何分佈的,相對於關係型數據庫,NoSQL可選的機制比較多,主要有三種形式:一是CAP支持,可用於水平擴展。二是多數據中心支持,能夠保證在橫跨多數據中心是也可以平穩運行。三是動態部署支持,能夠在運行着的集羣中動態地添加或刪除節點。

(3)數據邏輯層:表述了數據的邏輯變現形式,與關係型數據庫相比,NoSQL在邏輯表現形式上至關靈活,主要有四種形式:一是鍵值模型,這種模型在表現形式上比較單一,但卻有很強的擴展性。二是列式模型,這種模型相比於鍵值模型可以支持較爲複雜的數據,但擴展性相對較差。三是文檔模型,這種模型對於複雜數據的支持和擴展性都有很大優點。四是圖模型,這種模型的使用場景很少,一般是基於圖數據結構的數據定製的。

(4)接口層:爲上層應用提供了方便的數據調用接口,提供的選擇遠多於關係型數據庫。接口層提供了五種選擇:Rest,Thrift,Map/Reduce,Get/Put,特定語言API,使得應用程序和數據庫的交互更加方便。

 

小結:NoSQL分層架構並不表明每一個產品在每一層只有一種選擇。相反,這種分層設計提供了很大的靈活性和兼容性,每種數據庫在不一樣層面能夠支持多種特性。

 

 

MongoDB(分佈式文件存儲 的數據庫

着重介紹一下MongoDB,MongoDB:是一個介於關係數據庫和非關係數據庫之間的產品,是非關係數據庫中功能最豐富,最像關係數據庫的。它支持的數據結構很是鬆散,是相似Json的Bjson格式,所以能夠存儲比較複雜的數據類型。MongoDB最大的特色是它支持的查詢語言很是強大,其語法有點相似於面向對象的查詢語言,幾乎能夠實現相似關係數據庫單表查詢的絕大部分功能,還支持爲數據創建索引。它的特色是高性能、易部署、易使用、存儲數據很是方便。

 

 

 

 

 

 

主要功能特性:

(1)面向集合存儲,易存儲對象類型的數據

「面向集合」( Collenction-oriented),意思是數據被分組,存儲在數據集中,被稱爲一個集合。每一個集合在數據庫中都有一個惟一的標識名,而且能夠包含無限數目的文檔。集合的概念相似關係型數據庫裏的表,不一樣的是它不須要定義任何模式( Schema)。

(2)模式自由

模式自由,意味着對於存儲在Mongodb數據庫中的文件,咱們不須要知道它的任何結構定義。若是須要的話,你徹底能夠把不一樣結構的文件存儲在同一個數據庫裏,有點相似於「雌雄同體」的感受。

(3)MongoDB已經在多個站點部署,

 

主要場景以下:

一、網站實時數據處理。它很是適合實時的插入、更新與查詢,並具有網站實時數據存儲所需的複製及高度伸縮性。

二、緩存。因爲性能很高,它適合做爲信息基礎設施的緩存層。在系統重啓以後,由它搭建的持久化緩存層能夠避免下層的數據源過載。

三、高伸縮性的場景。很是適合由數十或數百臺服務器組成的數據庫,它的路線圖中已經包含對MapReduce引擎的內置支持。

 

不適用的場景以下:

一、要求高度事務性的系統。

二、傳統的商業智能應用。

三、複雜的跨文檔(表)級聯查詢。

 

Mongodb官網下載地址:https://www.mongodb.com/download-center#community

Windows平臺安裝教程:https://www.runoob.com/mongodb/mongodb-window-install.html

Linux平臺安裝教程:https://www.runoob.com/mongodb/mongodb-linux-install.html

Mac OSX 平臺安裝教程:https://www.runoob.com/mongodb/mongodb-osx-install.html

 

一、環境配置

(教程網址:https://www.runoob.com/mongodb/mongodb-java.html

在 Java 程序中若是要使用 MongoDB,你須要確保已經安裝了 Java 環境及 MongoDB JDBC 驅動。

 

(1)首先你必須下載mongo jar包,下載地址:https://mongodb.github.io/mongo-java-driver/, 請確保下載最新版本。

 

(2)你須要將 mongo-java-driver-3.12.0.jar (找到合適的版本)包含在你的 classpath 中。

 

 

 

(3)國內 mongodb-driver jar 下載地址:http://central.maven.org/maven2/org/mongodb/mongo-java-driver/

 

(4)鏈接數據庫(java代碼示例)

import com.mongodb.MongoClient;import com.mongodb.client.MongoDatabase;

public class MongoDBJDBC{

public static void main( String args[] ){

try{   

 // 鏈接到 mongodb 服務

 MongoClient mongoClient = new MongoClient( "localhost" , 27017 );

 // 鏈接到數據庫

  MongoDatabase mongoDatabase = mongoClient.getDatabase("ycs");  

  System.out.println("Connect to database successfully");

   }catch(Exception e){

   System.err.println( e.getClass().getName() + ": " + e.getMessage() );

    }

    }}

 

二、MongoDB 命令

備註這裏用ycs做爲建立的數據庫,用aaa做爲集合(相似表),bbb做爲文檔

建立數據庫:use DATABASE_NAME  #若是數據庫不存在,則建立數據庫,不然切換到指定數據庫

例如:use ycs (>use 數據庫名。建立完畢後輸入 >db ,就會顯示你剛剛建立的實例:ycs)

查看全部數據庫:show dbs

 

插入數據:db.ycs.insert({"name":"黑小子教程"})WriteResult({ "age" : 21 })

注意:MongoDB 中默認的數據庫爲 test,若是你沒有建立新的數據庫,集合將存放在 test 數據庫中。

 

刪除數據庫:db.dropDatabase()

注意:刪除當前數據庫,默認爲 test,你可使用 show dbs 或者 db 命令查看當前數據庫名,而後命令:use ycs 切換到你要刪除的數據庫,再執行命令:db.dropDatabase()進行刪除。

 

建立集合:db.createCollection("aaa")  # 集合,相似數據庫中的表。name: 要建立的集合名稱,options:可選參數, 指定有關內存大小及索引的選項。

例如: >use ycs   >db.createCollection("aaa")     

options 參數:

capped布爾):(可選)若是爲 true,則建立固定集合。固定集合是指有着固定大小的集合,當達到最大值時,它會自動覆蓋最先的文檔。注意:當該值爲 true 時,必須指定 size 參數。

autoIndexId布爾):如爲 true,自動在 _id 字段建立索引。默認爲 false。

Size數值):(可選)爲固定集合指定一個最大值,以千字節計(KB)。若是 capped 爲 true,也須要指定該字段。

Max數值):(可選)指定固定集合中包含文檔的最大數量。

 

查看已有集合: show collections 或 show tables

 

刪除集合:db.collection.drop()

例如: >use ycs    >show collections    >db.aaa.drop()

 

插入文檔:db.COLLECTION_NAME.insert(document)   #使用 insert() 或 save() 方法向集合中插入文檔

例如:>db.bbb.insert({title: 'MongoDB 教程',

         description: 'MongoDB 是一個 Nosql 數據庫',

         by: '黑小子教程',

         url: 'http://www.runoob.com',

         tags: ['mongodb', 'database', 'NoSQL'],

         likes: 100})

 

查看已插入文檔:db.bbb.find()

 

更新文檔:db.collection.update( <query>,<update>,

              {

               upsert: <boolean>, multi: <boolean>, writeConcern: <document>

               })   #使用 update() 和 save() 方法來更新集合中的文檔

參數說明:

query : update的查詢條件,相似sql update查詢內where後面的。

update : update的對象和一些更新的操做符(如$,$inc...)等,也能夠理解爲sql update查詢內set後面的

upsert : 可選,這個參數的意思是,若是不存在update的記錄,是否插入objNew,true爲插入,默認是false,不插入。

multi : 可選,mongodb 默認是false,只更新找到的第一條記錄,若是這個參數爲true,就把按條件查出來多條記錄所有更新。

writeConcern :可選,拋出異常的級別。

例如:(在上面插入文檔示例基礎上進行修改)

 

>db.bbb.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})      #如需修改多條:則須要設置 multi 參數爲 true。

例如:      >db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}},{multi:true})

 

查看是否更新文檔成功: find()

例如:>db.bbb.find().pretty()

 

刪除文檔:remove()

語法:db.bbb.remove(

     <query>,

{

     justOne: <boolean>,writeConcern: <document>

    })

列如:>db.aaa.remove({'title':'MongoDB 教程'})

參數說明:

query :(可選)刪除的文檔的條件。

justOne : (可選)若是設爲 true 或 1,則只刪除一個文檔,若是不設置該參數,或使用默認值 false,則刪除全部匹配條件的文檔。

writeConcern :(可選)拋出異常的級別。

 

查詢文檔:db.collection.find(query, projection)

參數說明:

query :可選,使用查詢操做符指定查詢條件

projection :可選,使用投影操做符指定返回的鍵。查詢時返回文檔中全部鍵值, 只需省略該參數便可(默認省略)。

 

排序: sort()     #語法:>db.COLLECTION_NAME.find().sort({KEY:1})

注意:skip(), limilt(), sort()三個放在一塊兒執行的時候,執行的順序是先 sort(), 而後是 skip(),最後是顯示的 limit()。

 

 

 

指定數量的數據記錄(分頁):limit()   #語法: >db.COLLECTION_NAME.find().limit(NUMBER)

注意:limit()方法接受一個數字參數,該參數指定從MongoDB中讀取的記錄條數。

 

跳過指定數量的數據(篩選):skip()   #語法:>db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)

 

建立索引:createIndex()  #語法:>db.collection.createIndex(keys, options)

注意: Key 值爲你要建立的索引字段,1 爲指定按升序建立索引,若是你想按降序來建立索引指定爲 -1 便可。

 

#createIndex() 方法中你也能夠設置使用多個字段建立索引(關係型數據庫中稱做複合索引)。

語法:>db.aaa.createIndex({"title":1,"description":-1})

 

 

聚合:aggregate()  #主要用於處理數據(諸如統計平均值,求和等),並返回計算後的數據結果。有點相似sql語句中的 count(*)。

語法:>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)

 

 

數據備份:mongodump  

#語法:>mongodump -h dbhost -d dbname -o dbdirectory

參數說明:

-h : MongDB所在服務器地址,例如:127.0.0.1,固然也能夠指定端口號:127.0.0.1:27017

-d : 須要備份的數據庫實例,例如:ycs

-o : 備份的數據存放位置,例如:c:\data\dump,固然該目錄須要提早創建,在備份完成後,系統自動在dump目錄下創建一個test目錄,這個目錄裏面存放該數據庫實例的備份數據。

 

數據恢復:mongorestore  

#語法:mongorestore -h <hostname><:port> -d dbname <path>

參數說明:

--host <:port>, -h <:port>:MongoDB所在服務器地址,默認爲: localhost:27017

--db , -d :須要恢復的數據庫實例,例如:test,固然這個名稱也能夠和備份時候的不同,好比test2

--drop:恢復的時候,先刪除當前數據,而後恢復備份的數據。就是說,恢復後,備份後添加修改的數據都會被刪除,慎用哦!

<path>:mongorestore 最後的一個參數,設置備份數據所在位置,例如:c:\data\dump\test。你不能同時指定 <path> 和 --dir 選項,--dir也能夠設置備份目錄。

--dir:指定備份的目錄,你不能同時指定 <path> 和 --dir 選項。

 

監控:mongostat  和 mongotop 

在你已經安裝部署並容許MongoDB服務後,你必需要了解MongoDB的運行狀況,並查看MongoDB的性能。這樣在大流量的狀況下能夠很好的應對並保證MongoDB正常運做。

示例:啓動你的Mongod服務,進入到你安裝的MongoDB目錄下的bin目錄, 而後輸入mongostat命令,以下所示:

D:\set up\mongodb\bin>mongostat

D:\set up\mongodb\bin>mongotop

 

MongodDB很強大,這裏只詮釋了它的背景和用處還有經常使用的一些操做,還有許多沒有功能和用處沒有展現出來,能夠去官網瞭解,也根據文中提供的網址去詳細瞭解。若是本文有不合格的地方,能夠指正,三人行,必有我師!

 

 

qq:2931445528

---------------------------------------------------------END----------------------------------------------------------------

相關文章
相關標籤/搜索