NoSql MongoDB

NoSql簡介java

NoSQL(Not Only SQL ),意即「不只僅是SQL」 ,指的是非關係型的數據庫 。是一項全新的數據庫革命性運動,早期就有人提出,發展至2009年趨勢愈加高漲。NoSQL的擁護者們提倡運用非關係型的數據存儲,相對於鋪天蓋地的關係型數據庫運用,這一律念無疑是一種全新的思惟的注入。 關係型數據庫中的表都是存儲一些結構化的數據,每條記錄的字段的組成都同樣,即便不是每條記錄都須要全部的字段,但數據庫會爲每條數據分配全部的字段。而非關係型數據庫以鍵值對(key-value)存儲,它的結構不固定,每一條記錄能夠有不同的鍵,每條記錄能夠根據須要增長一些本身的鍵值對,這樣就不會侷限於固定的結構,能夠減小一些時間和空間的開銷。node

常見的NoSql(非關係型數據庫)數據庫mysql

 

鍵值(Key-Value)存儲數據庫 
* Riak:一個開源、分佈式鍵值數據庫,支持數據複製和容錯 
* Redis:一個開源的鍵值存儲數據庫,支持主從式複製、事務,Pub/Sub、Lua腳本,還支持給Key添加時限 
* Dynamo:一個鍵值分佈式存儲數據庫,直接由亞馬遜Dynamo數據庫實現 
* Oracle NoSQL Database:來自Oracle的鍵值NoSQL數據庫,支持事務ACID和JSON 
* Oracle NoSQL Database:具有數據備份和分佈式鍵值存儲系統 
* Voldemort:具有數據備份和分佈式鍵值存儲系統 
* Aerospike:一個鍵值存儲數據庫,支持混合內存架構,經過強一致性和可調一致性保證數據的完整性git

 

列存儲數據庫 
* Cassandra:支持跨數據中心的數據複製,提供列索引 
* HBase:一個開源、分佈式、面向列存儲的模型 
* Amazon SimpleDB:一個非關係型數據存儲 
* Apache Accumulo:有序的、分佈式鍵值數據存儲,基於Google的BigTable設計 
* Hypertable:一個開源、可擴展的數據庫,模仿Bigtable,支持分片 
* Azure Tables:爲要求大量非結構化數據存儲的應用提供NoSQL性能github

 

文檔型數據庫 
* MongoDB:開源、面向文檔 
* CounchDB:一個使用JSON的文檔數據庫,使用Javascript作MapReduce查詢,也是一個使用HTTP的API 
* Couchbase:基於JSON模型 
* RavenDB:一個基於.net語言的面向文檔數據庫 
* MarkLogic:用來存儲基於XML和以文檔爲中心的信息,支持靈活的模式正則表達式

 

圖形(Graph)數據庫 
* Neo4j:一個圖數據庫,支持ACID事務 
* InfiniteGraph:用來維持和遍歷對象間的關係,支持分佈式數據存儲 
* AllegroGraph:結合使用了內存和磁盤,提供了高可擴展性,支持SPARQ、RDFS++和Prolog推理sql

 

NoSql數據庫優缺點mongodb

  在優點方面主要體如今下面幾點:shell

         簡單的擴展 數據庫

        快速的讀寫

        低廉的成本

        靈活的數據模型

  在不足方面主要有下面幾點:

      不提供對SQL的支持   

      支持的特性不夠豐富

       現有的產品不夠成熟

 

MongoDB簡介

  MongoDB是用C++語言編寫的非關係型數據庫。特色是高性能、易部署、易使用,存儲數據十分方便,主要特性有: 
  面向集合存儲,易於存儲對象類型的數據 
  模式自由 
  支持動態查詢 
  支持徹底索引,包含內部對象 
  支持複製和故障恢復 
  使用高效的二進制數據存儲,包括大型對象 
  文件存儲格式爲BSON(一種JSON的擴展)

MongoDB和關係數據庫的對比

對比項 mongoDB mysql oracle
集合 二維表table
表的一行數據 文檔document 一條記錄recoder
表字段 鍵key 字段filed
字段值 值value 值value
主外鍵 PK FK
靈活度擴展性 極高

MongoDB基本概念

  • 文檔(document)是MongoDB中數據的基本單元,很是相似於關係型數據庫系統中的行(可是比行要複雜的多)。
  • 集合(collection)就是一組文檔,若是說MongoDB中的文檔相似於關係型數據庫中的行,那麼集合就如同表。
  • MongoDB的單個計算機能夠容納多個獨立的數據庫,每個數據庫都有本身的集合和權限。
  • MongoDB自帶簡潔但功能強大的JavaScript shell,這個工具對於管理MongoDB實例和操做數據做用很是大。
  • 每個文檔都有一個特殊的鍵」_id」,它在文檔所處的集合中是惟一的,至關於關係數據庫中的表的主鍵。

MongoDB數據類型

數據類型 描述 舉例
null 表示空值或者未定義的對象 {「x」:null}
布爾值 真或者假:true或者false {「x」:true}
32位整數 32位整數。shell是不支持該類型的,shell中默認會轉換成64位浮點數  
64位整數 64位整數。shell是不支持該類型的,shell中默認會轉換成64位浮點數  
64位浮點數 64位浮點數。shell中的數字就是這一種類型 {「x」:3.14,」y」:3}
字符串 UTF-8字符串 {「foo」:」bar」}
符號 shell不支持,shell會將數據庫中的符號類型的數據自動轉換成字符串  
對象id 文檔的12字節的惟一id {「id」: ObjectId()}
日期 從標準紀元開始的毫秒數 {「date」:new Date()}
正則表達式 文檔中能夠包含正則表達式,遵循JavaScript的語法 {「foo」:/foobar/i}
代碼 文檔中能夠包含JavaScript代碼 {「x」:function() {}}
未定義 undefined {「x」:undefined}
數組 值的集合或者列表 {「arr」: [「a」,」b」]}
內嵌文檔 文檔能夠做爲文檔中某個key的value {「x」:{「foo」:」bar」}}

MongoDB使用

MongoDB的安裝很是簡單,只須要將下載的MongoDB的壓縮文件解壓到任意目錄,並將其中的bin目錄加入到系統的path環境變量中便可

在啓動MongoDB以前,要手動建立一個存放MongoDB數據文件的目錄,如D:\mongo_data 在命令行執行 mongod --dbpath=D:\mongo_data

在命令行中可使用mongo命令鏈接到MongoDB服務器,以下,輸入mongo命令默認鏈接到本地的名稱爲test的數據庫,若是但願鏈接到遠程數據庫,可使用mongo ip:port

建立數據庫,使用命令 use 數據庫名稱 ,如: use mydb1

刪除當前數據庫,使用命令 db.dropDatabase()

MongoDB經常使用操做

查看全部數據庫,使用命令 show dbs

查看當前所在數據庫,使用命令 db

 查看當前數據庫中全部的集合,使用命令 show collections 或使用show tables

建立集合有兩種方式,顯示建立和隱式建立

  顯示建立可使用命令 db.createCollection(「集合名稱")

  隱式建立可使用命令 db.集合名稱.insert({}),指建立集合並同時向集合中插入數據,例如:db.customer.insert({name:」jack」})  

  向集合添加文檔,使用命令 db.集合名稱.insert({}),例如: db.user1.insert({name:」jack」,age:20})

  刪除集合中的文檔,使用命令 db.集合名稱.remove({刪除條件}),不加刪除條件爲刪除集合中的全部文檔,例如,db.c1.remove() 爲刪除c1集合中的全部文檔,db.c1.remove({name:」user1」})爲刪除c1集合中name爲user1的文檔  

  查詢集合中的文檔,可使用命令 db.集合名稱.find({條件}),或者使用 db.集合名稱.findOne() 查詢第一個文檔 

  查詢集合中的文檔 ,使用條件表達式(<, <=, >, >=,!=)   

    //大於: field > value   db.collection.find({field:{$gt:value}});

    //小於: field < value   db.collection.find({field:{$lt:value}});

    //大於等於: field >= value   db.collection.find({field:{$gte:value}});

    //小於等於: field <= value   db.collection.find({field:{$lte:value}});

     //不等於: field != value   db.collection.find({field:{$ne:value}});

  查詢集合中的文檔 ,統計(count)、排序(sort)、分頁(skip、limit)

    db.customer.count();

    db.customer.find().count();

    db.customer.find({age:{$lt:5}}).count();

    db.customer.find().sort({age:1});降序-1

    db.customer.find().skip(2).limit(3);

    db.customer.find().sort({age:-1}).skip(2).limit(3);

    db.customer.find().sort({age:-1}).skip(2).limit(3).count();

    db.customer.find().sort({age:-1}).skip(2).limit(3).count(0);

    db.customer.find().sort({age:-1}).skip(2).limit(3).count(1);

  查詢集合中的文檔 ,$all主要用來查詢數組中的包含關係,查詢條件中只要有一個不包含就不返回

    db.customer.find({post:{$all:[1,2]}})

  查詢集合中的文檔 ,$in,相似於關係型數據庫中的IN

    db.customer.find({age:{$in:[1,2]}})

  查詢集合中的文檔 ,$nin,與$in相反

  查詢集合中的文檔 ,$or,至關於關係型數據庫中的OR,表示或者的關係,例如查詢name爲user2或者age爲3的文檔,命令爲: db.customer.find({$or:[{name:」user2」},{age:3}]})

  查詢集合中的文檔 ,$exists,用於查詢集合中存在某個鍵的文檔或不存在某個鍵的文檔,例如查詢customer集合中存在name鍵的全部文檔,可使用 db.customer.find({name:{$exists:1}}),

    $exists:1表示真,指存在 $exists:0表示假,指不存在

  更新集合中的文檔,語法以下:

    db.collection.update(criteria,objNew,upsert,multi) 參數說明:

      criteria:用於設置查詢條件的對象

      objNew:用於設置更新內容的對象

      upsert:若是記錄已經存在,更新它,不然新增一個記錄,取值爲0或1

      multi:若是有多個符合條件的記錄,是否所有更新,取值爲0或1 注意:默認狀況下,只會更新第一個符合條件的記錄 通常狀況下後兩個參數分別爲0,1 ,即:                      db.collection.update(criteria,objNew,0,1)  

  更新集合中的文檔,將集合中name爲user1的文檔改爲name爲jack

    db.collection.update({name:"user1"},{name:"jack"})

  更新集合中的文檔, $set 用來指定一個鍵的值,若是這個鍵不存在,則建立它。例如: 給name爲user1的文檔添加address,可使用命令:

    db.c1.update({name:」user1」},{$set:{address:」bj」}},0,1) 將name爲user1的文檔修改address爲tj,其它鍵值對不變,命令爲:

    db.c1.update({name:」user1」},{$set:{address:」tj」}},0,1)

  更新集合中的文檔,使用 $inc 將集合中name爲user1的age加1,其它鍵不變, $inc表示使某個鍵值加減指定的數值

    db.c1.update({name:」user1」},{$inc:{age:1}})

  更新集合中的文檔, $unset 用來刪除某個鍵,例如刪除name爲user1的文檔中的address鍵,可使用命令:

    db.c1.update({name:」user1」},{$unset:{address:1}},0,1)

 

索引 

  建立普通索引,使用命令 db.collection.ensureIndex({key:1})   

  建立惟一索引,使用命令 db.collection.ensureIndex({key:1},{unique:true})

  查看關於索引的相關信息,使用命令 db.collection.stats()

   查看查詢使用索引的狀況,使用命令 db.collection.find({key:value}).explain()

  刪除索引,使用命令 db.collection.dropIndex({key:1})

  刪除集合,也會將集合中的索引所有刪除

固定集合(capped collection) 

  固定集合指的是事先建立並且大小固定的集合 。

  固定集合特性:固定集合很像環形隊列,若是空間不足,最先的文檔就會被刪除,爲新的文檔騰出空間。通常來講,固定集合適用於任何想要自動淘汰過時屬性的場景,沒有太多的操做限制。

  建立固定集合使用命令:db.createCollection(「collectionName」,{capped:true,size:100000,max:100});

  size指定集合大小,單位爲KB,max指定文檔的數量 當指定文檔數量上限時,必須同時指定大小。淘汰機制只有在容量尚未滿時纔會依據文檔數量來工做。要是容量滿了,淘汰機制會依據容量來工做。備份(mongodump)和恢復(mongorestore)

  MongoDB提供了備份和恢復的功能,分別是MongoDB下載目錄下的mongodump.exe和mongorestore.exe文件

  備份數據使用下面的命令:

    >mongodump -h dbhost -d dbname -o dbdirectory

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

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

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

  恢復數據使用下面的命令:

    >mongorestore -h dbhost -d dbname -directoryperdb dbdirectory

      -h:MongoDB所在服務器地址

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

      -directoryperdb:備份數據所在位置,例如:c:\data\dump\test

導入(mongoimport)和導出(mongoexport)

 

  導出數據可使用命令:

    mongoexport -h dbhost -d dbname -c collectionName -o output

      參數說明:

        -h 數據庫地址   

        -d 指明使用的庫

        -c 指明要導出的集合

        -o 指明要導出的文件名

  導入數據可使用命令:

    mongoimport -h dbhost -d dbname -c collectionname 文件的地址...

     參數說明:

      -h 數據庫地址

      -d 指明使用的庫   

      -c 指明要導入的集合

      本地的文件地址...

 

安全和認證

 

    每一個MongoDB實例中的數據庫均可以有許多用戶。若是開啓了安全性檢查,則只有數據庫認證用戶才能執行讀或者寫操做。在認證的上下文中,MongoDB會將普通的數據做爲admin數據庫處理。admin數據庫中的用戶被視爲超級用戶(即管理員)。 在認證以後,管理員能夠讀寫全部數據庫,執行特定的管理命令,如listDatabases和shutdown。 在開啓安全檢查以前,必定要至少有一個管理員帳號。

  在admin數據庫中建立管理員帳號:

    use admin; db.addUser(「root」,」root」);

  在test數據庫中建立普通帳號:

     use test; db.addUser(「zhangsan」,」123」); db.addUser(「lisi」,」123」,true);

      注意:用戶zhangsan,密碼爲123,對test數據庫擁有讀寫權限 用戶lisi,密碼爲123,對test數據庫擁有隻讀權限

  從新啓動數據庫服務,並開啓安全檢查: mongod --dbpath d:\mongo_data --auth

 

分片(sharding)分佈式存儲..

 

    分片(sharding)是指將數據拆分,將其分散存在不一樣的機器上的過程。有時也用分區(partitioning)來表示這個概念。將數據分散到不一樣的機器上,不須要功能強大的大型計算機就能夠儲存更多的數據,處理更多的負載。

    MongoDB分片的基本思想就是將集合切分紅小塊。這些塊分散到若干片裏面,每一個片只負責總數據的一部分。應用程序沒必要知道哪片對應哪些數據,甚至不須要知道數據已經被拆分了,因此在分片以前要運行一個路由進程,該進程名爲mongos。這個路由器知道全部數據的存放位置,因此應用能夠鏈接它來正常發送請求。對應用來講,它僅知道鏈接了一個普通的mongod。路由器知道數據和片的對應關係,可以轉發請求到正確的片上。若是請求有了迴應,路由器將其收集起來回送給應用。

    設置分片時,須要從集合裏面選一個鍵,用該鍵的值做爲數據拆分的依據。這個鍵稱爲片鍵(shard key)。 {name:"zhangsan",age:1}

    用個例子來講明這個過程:假設有個文檔集合表示的是人員。若是選擇名字("name")做爲片鍵,第一片可能會存放名字以A~F開頭的文檔,第二片存的G~P的名字,第三片存的Q~Z的名字。隨着添加或者刪除片,MongoDB會從新平衡數據,使每片的流量都比較均衡,數據量也在合理範圍內。

                      

    一、建立三個目錄,分別存放兩個mongod服務的數據文件和config服務的數據文件

    二、開啓config服務器 。mongos要把mongod之間的配置放到config服務器裏面,因此首先開啓它,這裏就使用2222端口。 命令爲:

       mongod --dbpath E:\sharding\config_node --port 2222

    三、開啓mongos服務器 。這裏要注意的是咱們開啓的是mongos,端口3333,同時指定下config服務器。命令爲:

      mongos --port 3333 --configdb=127.0.0.1:2222

    四、啓動mongod服務器 。對分片來講,也就是要添加片了,這裏開啓兩個mongod服務,端口分別爲:4444,5555。命令爲:

      mongod --dbpath E:\sharding\mongod_node1 --port 4444 mongod --dbpath E:\sharding\mongod_node2 --port 5555

    五、服務配置 。client直接跟mongos打交道,也就說明咱們要鏈接mongos服務器,而後將4444,5555的mongod交給mongos,添加分片也就是addshard()。

    六、開啓數據庫分片功能,命令很簡單 enablesharding(),這裏就開啓test數據庫。

    七、指定集合中分片的片鍵,這裏就指定爲person.name鍵。

    八、經過mongos插入10w記錄,而後經過printShardingStatus命令查看mongodb的數據分片狀況。

 

使用java操做MongoDB

 

    下載mongoDB對Java支持的驅動包 驅動包下載地址:https://github.com/mongodb/mongo-java-driver/downloads

    一、查詢集合中全部文檔

       

    二、刪除集合中的文檔

       

    三、向集合中插入文檔

      

    四、更新集合中的文檔

      

相關文章
相關標籤/搜索