1. 程式人生 > >MongoDB系統學習教程

MongoDB系統學習教程

                                               Mongo 非關係型資料庫

大綱:

   1:非關係型資料庫的概念

   2:mongodb 的安裝

   3:mongodb的增刪改查

   4:mongodb 的索引

   5 :mongodb 當中的固定集合

   6 :mongodb 當中的資料備份

   7:mongdb 的資料安全

   8:mongodb 的叢集(

兩種方式:主從複製

副本集:

9:mongodb 的分散式()

10:使用java 程式碼呼叫mongdb(java 程式碼的增刪改查)

1:  mongodb 安裝,直接配置環境變數到bin 目錄下就ok

資料庫為我們提供儲存資料的服務,它肯定是佔用一個埠對外提供服務  預設的埠為27017

2:啟動客戶端連線到monodb 上面,怎麼增刪改查非關係型的資料庫..

mongo  的命令 連線到資料庫

建立集合:

顯示建立:db.createCollection("heima1")

隱式建立:直接在建立集合的同時往集合裡新增資料

增刪改查語法,過一遍即可

//更新   update tableName  set   ""  where condito

1:用於設定更新的條件

2:用於設定更新的內容的物件

3:如果記錄已經存在,更新它,否則新增一個記錄,取值為0或1

4:如果有多條記錄被滿足,是否全部更新.. (1更新全部)(0更新1條)

db.collectionName("condition","objectValue")

  db.collection.update(criteria,objNew,upsert,multi)

引數說明:

criteria:用於設定查詢條件的物件

objNew:用於設定更新內容的物件

upsert:如果記錄已經存在,更新它,否則新增一個記錄,取值為0或1(是否更新一條資料)

multi:如果有多個符合條件的記錄,是否全部更新,取值為0或1

注意:預設情況下,只會更新第一個符合條件的記錄

一般情況下後兩個引數分別為0,1 ,即:

db.collection.update(criteria,objNew,0,1)

3:建立索引的目的就是加速查詢..

普通索引:

db.collectionName.ensureIndex({key:1})

唯一索引:

db.collectionName.ensureIndex({key:1},{unique:true})

在某一個key 上面建立的唯一索引,這個key 對應的值不能重複新增..

Db.help()  查詢幫助

4:固定集合:固定集合指的是事先建立而且大小固定的集合 。

固定集合很像環形佇列,如果空間不足,最早的文件就會被刪除,

為新的文件騰出空間。一般來說,固定集合適用於任何想要自動淘汰過期屬性的場景,沒有太多的操作限制。

Mongodb 27107/itcast

5:備份 與 恢復

//先把資料從資料庫當中通過命令匯出來,然後我們刪掉資料庫當中的資料,再把匯出來的資料恢復到資料庫當中...

mongodb bin 目錄下提供的命

mongodump 備份

mongorestore 恢復..

6:匯入匯出

mongoexport

mongoimport

7:資料庫安全:

1:至少需要有個管理員賬號,admin 資料庫當中的使用者都會被視為管理員

(連線到admin 資料庫當中,新增一個管理員賬號)

2:我有了管理員的賬號為其它的資料庫分配賬號(操作資料來說,讀,寫)

(為test 分配讀,寫的賬號)

3:重啟我的mongodb ,開啟安全檢查

4:客戶端重新連線mongdb ,接下來操作資料的部分都需要登入。。

5:叢集

1:主從叢集

2:副本集:副本集就是有自動故障恢復功能的主從叢集。

主從叢集和副本集最大的區別就是副本集沒有固定的“主節點”

2.1:副本集當中最少保證要有兩個節點

2.2:副本集當中的備份節點只做資料備份或者故障恢復的功能

6:分散式儲存

分片(sharding)是指將資料拆分,將其分散存在不同的機器上的過程。有時也用分割槽(partitioning)來表示這個概念。將資料分散到不同的機器上,不需要功能強大的大型計算機就可以儲存更多的資料,處理更多的負載。

重點理解片鍵

7:使用java 程式碼 來呼叫mongodb

連線其它的資料庫的時候連線的驅動包

使用mongodb 提供的客戶端的api

java  nio  netty  mina

                                              mongoDb 詳細說明  

關係型資料庫中的表都是儲存一些結構化的資料,每條記錄的欄位的組成都一樣,即使不是每條記錄都需要所有的欄位,但資料庫會為每條資料分配所有的欄位。而非關係型資料庫以鍵值對(key-value)儲存,它的結構不固定,每一條記錄可以有不一樣的鍵,每條記錄可以根據需要增加一些自己的鍵值對,這樣就不會侷限於固定的結構,可以減少一些時間和空間的開銷。

  1. 常見的關係型資料庫:

CouchDB, Redis ,MongoDB,BigTable,Neo4j ,HBase

  1. 非關係型資料庫的優缺點

在優勢方面主要體現在下面幾點:

簡單的擴充套件

快速的讀寫

低廉的成本

靈活的資料模型

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

不提供對SQL的支援

支援的特性不夠豐富

現有的產品不夠成熟

3 mongoDb 的簡介:

MongoDB是用C++語言編寫的非關係型資料庫。特點是高效能、易部署、易使用,儲存資料十分方便,主要特性有:

面向集合儲存,易於儲存物件型別的資料

模式自由

支援動態查詢

支援完全索引,包含內部物件

支援複製和故障恢復

使用高效的二進位制資料儲存,包括大型物件

檔案儲存格式為BSON(一種JSON的擴充套件)

4 對比

 5 MongoDB基本概念介紹

文件(document)是MongoDB中資料的基本單元,非常類似於關係型資料庫系統中的行(但是比行要複雜的多)

集合(collection)就是一組文件,如果說MongoDB中的文件類似於關係型資料庫中的行,那麼集合就如同表

MongoDB的單個計算機可以容納多個獨立的資料庫,每一個數據庫都有自己的集合和許可權

MongoDB自帶簡潔但功能強大的JavaScript shell,這個工具對於管理MongoDB例項和操作資料作用非常大

每一個文件都有一個特殊的鍵"_id",它在文件所處的集合中是唯一的,相當於關係資料庫中的表的主鍵

 6 mongodb 的資料型別

資料型別       描述                    舉例

布林值       真或者假: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 只需要解壓並且配置環境變數

 指定資料存放的位置即可:

mongod --dbpath=E:\mongodb\mongodata

服務資料庫預設的埠:27017

7 啟動資料庫服務,連線客戶端,實現增刪改查

在命令列中可以使用mongo命令連線到MongoDB伺服器,如下,輸入mongo命令預設連線到本地的名稱為test的資料庫,如果希望連線到遠端資料庫,可以使用mongo ip:port

 8 常用命令

   Show dbs 檢視有哪些資料庫

   Db  檢視當前所在的資料庫

   建立資料庫,使用命令 use 資料庫名稱 ,如:

use mydb1

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

顯示建立可以使用命令 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()  查詢第一個文件

 查詢集合中的文件,返回某些特定的鍵值

  Db.xgs.find({name:”zs”}})

加入查詢的條件

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

//大於: 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主要用來查詢陣列中的包含關係,查詢條件中只要有一個不包含就不返回

 查詢集合中的文件 ,$in,類似於關係型資料庫中的IN

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

 查詢集合中的文件 ,$or,相當於關係型資料庫中的OR,表示或者的關係,例如查詢name為user2或者age為3的文件,命令為:

db.customer.find({$or:[{name:”user2”},{age:3}]})

 查詢集合中的文件 ,$nor,表示根據條件過濾掉某些資料,例如查詢name不是user2,age不是3的文件,命令為:

db.customer.find({$nor:[{name:”user2”},{age:3}]})

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

$exists:1表示真,指存在

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

 查詢集合中的文件 ,類似於關係型資料庫,mongodb中也有遊標的概念

  更新集合中的文件,語法如下:

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

 更新集合中的文件, $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表示使某個鍵值加減指定的數值

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

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

索引

索引就是用來加速查詢的。資料庫索引與書籍的索引類似:有了索引就不需要翻遍整本書,資料庫則可以直接在索引中查詢,使得查詢速度能提高几個數量級。在索引中找到條目以後,就可以直接跳轉到目標文件的位置。

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

 檢視關於索引的相關資訊,使用命令 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指定文件的數量

當指定文件數量上限時,必須同時指定大小。淘汰機制只有在容量還沒有滿時才會依據文件數量來工作。要是容量滿了,淘汰機制會依據容量來工作。

   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目錄,這個目錄裡面存放該資料庫例項的備份資料。

備份(mongodump)和恢復(mongorestore)

恢復資料使用下面的命令:

>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 指明要匯出的檔名

安全和認證

每個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

主從複製(主從叢集 )

主從複製是MongoDB最常用的複製方式。這種方式非常靈活,可用於備份、故障恢復、讀擴充套件等。

最基本的設定方式就是建立一個主節點和一個或者多個從節點,每個從節點要知道主節點的地址。執行mongod --master就啟動了主伺服器。執行mongod --slave --source master_address 則啟動了從伺服器,其中master_address就是上面主節點的地址為了方便演示,可以在一臺計算機上來模擬主節點和從節點。在D盤建立兩個目錄master和slave,master目錄作為主節點的資料檔案的目錄,slave目錄作為從節點的資料檔案的目錄。

注意:主節點和從節點要指定不同的埠。

啟動主節點:mongod --dbpath d:\master --port 10000 --master

啟動從節點:mongod --dbpath d:\slave --port 10001 --slave --source localhost:10000

啟動成功後就可以連線主節點進行操作了,而這些操作會同步到從節點。

副本集

副本集就是有自動故障恢復功能的主從叢集。

主從叢集和副本集最大的區別就是副本集沒有固定的“主節點”;整個叢集會選出一個“主節點”,當其掛掉後,又在剩下的從節點中選中其他節點為“主節點”,副本集總有一個活躍點(primary)和一個或多個備份節點(secondary)。

以三個節點為例:

節點1:

HOST:localhost:10001

Log File:D:\mongodb\logs\node1\logs.txt

Data File:D:\mongodb\dbs\node1

節點2:

HOST:localhost:10002

Log File:D:\mongodb\logs\node2\logs.txt

Data File:D:\mongodb\dbs\node2

節點3:

HOST:localhost:10003

Log File:D:\mongodb\logs\node3\logs.txt

Data File:D:\mongodb\dbs\node3

啟動節點1:

mongod --dbpath D:\mongodb\dbs\node1 --logpath D:\mongodb\logs\node1\logs.txt --logappend --port 10001 --replSet itcast/localhost:10002  --master

啟動節點2:

mongod --dbpath D:\mongodb\dbs\node2 --logpath D:\mongodb\logs\node2\logs.txt --logappend --port 10002 --replSet itcast/localhost:10001

啟動節點3:  

mongod --dbpath D:\mongodb\dbs\node3 --logpath D:\mongodb\logs\node3\logs.txt --logappend --port 10003 --replSet itcast/localhost:10001,localhost:10002

初始化節點(只能初始化一次):隨便登入一個節點,以10001為例

 mongo localhost:10001/admin

 db.runCommand({  "replSetInitiate":{   "_id":“itcast",   "members":[    {      "_id":1,      "host":"localhost:10001",       "priority":3    },    {      "_id":2,      "host":"localhost:10002",      "priority":2    },    {      "_id":3,      "host":"localhost:10003",       "priority":1    }   ]}});

查詢當前主庫,登入10002

mongo localhost:10002

db.$cmd.findOne ( {ismaster: 1 } );

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

   分片(sharding)是指將資料拆分,將其分散存在不同的機器上的過程。有時也用分割槽(partitioning)來表示這個概念。將資料分散到不同的機器上,不需要功能強大的大型計算機就可以儲存更多的資料,處理更多的負載。

MongoDB分片的基本思想就是將集合切分成小塊。這些塊分散到若干片裡面,每個片只負責總資料的一部分。應用程式不必知道哪片對應哪些資料,甚至不需要知道資料已經被拆分了,所以在分片之前要執行一個路由程序,該程序名為mongos。這個路由器知道所有資料的存放位置,所以應用可以連線它來正常傳送請求。對應用來說,它僅知道連線了一個普通的mongod。路由器知道資料和片的對應關係,能夠轉發請求到正確的片上。如果請求有了迴應,路由器將其收集起來回送給應用。

   設定分片時,需要從集合裡面選一個鍵,用該鍵的值作為資料拆分的依據。這個鍵稱為片鍵(shard key)。

{name:"zhangsan",age:1}

用個例子來說明這個過程:假設有個文件集合表示的是人員。如果選擇名字("name")作為片鍵,第一片可能會存放名字以A~F開頭的文件,第二片存的G~P的名字,第三片存的Q~Z的名字。隨著新增或者刪除片,MongoDB會重新平衡資料,使每片的流量都比較均衡,資料量也在合理範圍內。

1、建立三個目錄,分別存放兩個mongod服務的資料檔案和config服務的資料檔案

2、開啟config伺服器 。mongos要把mongod之間的配置放到config伺服器裡面,所以首先開啟它,這裡就使用2222埠。 命令為:

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

3、開啟mongos伺服器 。這裡要注意的是我們開啟的是mongos,埠3333,同時指定下config伺服器。命令為:

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

4、啟動mongod伺服器 。對分片來說,也就是要新增片了,這裡開啟兩個mongod服務,埠分別為:4444,5555。命令為:

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

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

5、服務配置 。client直接跟mongos打交道,也就說明我們要連線mongos伺服器,然後將4444,5555的mongod交給mongos,新增分片也就是addshard()。

6、開啟資料庫分片功能,命令很簡單 enablesharding(),這裡就開啟test資料庫。

7、指定集合中分片的片鍵,這裡就指定為person.name鍵。

8、通過mongos插入10w記錄,然後通過printShardingStatus命令檢視mongodb的資料分片情況。

使用java操作MongoDB

下載mongoDB對Java支援的驅動包

驅動包下載地址:https://github.com/mongodb/mongo-java-driver/downloads

1、查詢集合中所有文件

Mongo mongo = new Mongo("localhost",27017);

DB db = mongo.getDB("test");

DBCollection collection = db.getCollection("customer");

DBCursor dbCursor = collection.find();

System.out.println(collection.getCount());

while(dbCursor.hasNext()){

System.out.println(dbCursor.next());

}

mongo.close();

2、刪除集合中的文件

Mongo mongo = new Mongo("localhost",27017);

DB db = mongo.getDB("test");

DBCollection collection = db.getCollection("customer");

BasicDBObject o = new BasicDBObject("_id", new ObjectId("5199ee647d5fc789bc760c07"));

collection.remove(o);

mongo.close();

3、向集合中插入文件

Mongo mongo = new Mongo("localhost",27017);

DB db = mongo.getDB("test");

DBCollection collection = db.getCollection("customer");

DBObject c = new BasicDBObject();

c.put("name", “jack");

c.put("age", 24);

collection.insert(c);

mongo.close();

4、更新集合中的文件

Mongo mongo = new Mongo("localhost",27017);

DB db = mongo.getDB("test");

DBCollection collection = db.getCollection("customer");

BasicDBObject query = new BasicDBObject("_id",new ObjectId("519e2e393296cf3baccdb10c"));

BasicDBObject object = (BasicDBObject) collection.findOne(query);

object.put("name", “wangwu");

int n = collection.update(query, object).getN();

System.out.println(n);

mongo.close();