MongoDB學習


1 下載安裝

安裝MongoDB非常的簡單,僅需下載壓縮包解壓運行命令即可,
下載地址: http://www.mongodb.org/downloads,本文為windows平台,
 
MongoDB運行命令:>bin/ mongod
 
提示:首先要創建存儲數據的文件夾,MongoDB 默認存儲數據目錄為 /data/db/ (或者 c:/data/db),當然你也可以修改成不同目錄,只需要指定 --dbpath 參數,eg:
 
>bin/ mongod --dbpath=d:/mgdata/db

 

2 建庫建表

 

MongoDB創建數據庫,MongoDB創建數據庫,MongoDB創建數據庫,MongoDB創建數據庫

MongoDB創建數據庫完全可以使用use

如下:

use mydb;

這樣就創建了一個數據庫。

這一步很重要如果什么都不操作離開的話 這個庫就會被系統刪除。

驗證-------------------------------

然后使用插入語句:

db.usr.insert({'name':'tompig'});

db.usr.insert({'name':'tompig1','id':1});

在使用下列命令查看

show collections;  ---查看‘表’

 > show collections;
system.indexes
usr

show dbs 查看庫。

> show dbs;
local   (empty)
test    0.078125GB

 

查詢記錄

> db.usr.find();
{ "_id" : ObjectId("4f459f01bb327e6587380b58"), "name" : "lein" }
{ "_id" : ObjectId("4f45a14dbb327e6587380b59"), "name" : "leinchu", "id" : 2 }
>

 

 

打開游覽器輸入URL “http://localhost:27017/”,如果出現下面的頁面則說明已正常啟動:

 

You are trying to access MongoDB on the native driver port. For http diagnostic access, add 1000 to the port number

http://localhost:28017/

 

3 優點和特性

使用JSON風格語法,易於掌握和理解:MongoDB使用JSON的變種BSON作為內部存儲的格式和語法。針對MongoDB的操作都使用JSON風格語法,客戶端提交或接收的數據都使用JSON形式來展現。相對於SQL來說,更加直觀,容易理解和掌握。

Schema-less,支持嵌入子文檔:MongoDB是一個Schema-free的文檔數據庫。一個數據庫可以有多個Collection,每個Collection是Documents的集合。Collection和Document和傳統數據庫的Table和Row並不對等。無需事先定義Collection,隨時可以創建

作品和評論可以設計為一個collection,評論作為子文檔內嵌在art的comments屬性中,評論的回復則作為comment子文檔的子文檔內嵌於replies屬性。按照這種設計模式,只需要按照作品id檢索一次,即可獲得所有相關的信息了。在MongoDB中,不強調一定對數據進行Normalize ,很多場合都建議De-normalize,開發人員可以扔掉傳統關系數據庫各種范式的限制,不需要把所有的實體都映射為一個Collection,只需定義最頂級的class。MongoDB的文檔模型可以讓我們很輕松就能將自己的Object映射到collection中實現存儲。

 

Collection中可以包含具有不同schema的文檔記錄。 這意味着,你上一條記錄中的文檔有3個屬性,而下一條記錄的文檔可以有10個屬性,屬性的類型既可以是基本的數據類型(如數字、字符串、日期等),也可以是數組或者散列,甚至還可以是一個子文檔(embed document)。這樣,可以實現逆規范化(denormalizing)的數據模型,提高查詢的速度。

 

CRUD更加簡單,支持in-place update:只要定義一個數組,然后傳遞給MongoDB的insert/update方法就可自動插入或更新;對於更新模式,MongoDB支持一個upsert選項,即:“如果記錄存在那么更新,否則插入”。MongoDB的update方法還支持Modifier,通過Modifier可實現在服務端即時更新,省去客戶端和服務端的通訊。這些modifer可以讓MongoDB具有和Redis、Memcached等KV類似的功能:較之MySQL,MonoDB更加簡單快速。Modifier也是MongoDB可以作為對用戶行為跟蹤的容器。在實際中使用Modifier來將用戶的交互行為快速保存到MongoDB中以便后期進行統計分析和個性化定制。

 

所有的屬性類型都支持索引,甚至數組:這可以讓某些任務實現起來非常的輕松。在MongoDB中,“_id”屬性是主鍵,默認MongoDB會對_id創建一個唯一索引。

 

服務端腳本和Map/Reduce:MongoDB允許在服務端執行腳本,可以用Javascript編寫某個函數,直接在服務端執行,也可以把函數的定義存儲在服務端,下次直接調用即可。MongoDB不支持事務級別的鎖定,對於某些需要自定義的“原子性”操作,可以使用Server side腳本來實現,此時整個MongoDB處於鎖定狀態。Map/Reduce也是MongoDB中比較吸引人的特性。Map/Reduce可以對大數據量的表進行統計、分類、合並的工作,完成原先SQL的GroupBy等聚合函數的功能。並且Mapper和Reducer的定義都是用Javascript來定義服務端腳本。

性能高效,速度快: MongoDB使用c++/boost編寫,在多數場合,其查詢速度對比MySQL要快的多,對於CPU占用非常小。部署也很簡單,對大多數系統,只需下載后二進制包解壓就可以直接運行,幾乎是零配置。

支持多種復制模式: MongoDB支持不同的服務器間進行復制,包括雙機互備的容錯方案。

Master-Slave是最常見的。通過Master-Slave可以實現數據的備份。在我們的實踐中,我們使用的是Master-Slave模式,Slave只用於后備,實際的讀寫都是從Master節點執行。

Replica Pairs/Replica Sets允許2個MongoDB相互監聽,實現雙機互備的容錯。

MongoDB只能支持有限的雙主模式(Master-Master),實際可用性不強,可忽略

 

內置GridFS,支持大容量的存儲:這個特點是最吸引我眼球的,也是讓我放棄其他NoSQL的一個原因。GridFS具體實現其實很簡單,本質仍然是將文件分塊后存儲到files.file和files.chunk 2個collection中,在各個主流的driver實現中,都封裝了對於GridFS的操作。由於GridFS自身也是一個Collection,你可以直接對文件的屬性進行定義和管理,通過這些屬性就可以快速找到所需要的文件,輕松管理海量的文件,無需費神如何hash才能避免文件系統檢索性能問題, 結合下面的Auto-sharding,GridFS的擴展能力是足夠我們使用了。在實踐中,我們用MongoDB的GridFs存儲圖片和各種尺寸的縮略圖

 

內置Sharding,提供基於Range的Auto Sharding機制:一個collection可按照記錄的范圍,分成若干個段,切分到不同的Shard上。Shards可以和復制結合,配合Replica sets能夠實現Sharding+fail-over,不同的Shard之間可以負載均衡。查詢是對客戶端是透明的。客戶端執行查詢,統計,MapReduce等操作,這些會被MongoDB自動路由到后端的數據節點。這讓我們關注於自己的業務,適當的時候可以無痛的升級。MongoDB的Sharding設計能力最大可支持約20 petabytes,足以支撐一般應用。

第三方支持豐富: MongoDB社區非常活躍,很多開發框架都迅速提供了對MongDB的支持。不少知名大公司和網站也在生產環境中使用MongoDB,越來越多的創新型企業轉而使用MongoDB作為和Django,RoR來搭配的技術方案。

 

實施MonoDB的過程是令人愉快的。我們對自己的PHP開發框架進行了修改以適應MongoDB。在PHP中,對MongoDB的查詢、更新都是圍繞Array進行的,實現代碼變得很簡潔。由於無需建表,MonoDB運行測試單元所需要的時間大大縮短,對於TDD敏捷開發的效率也提高了。當然,由於MongoDB的文檔模型和關系數據庫有很大不同,在實踐中也有很多的困惑,幸運的是,MongoDB開源社區給了我們很大幫助。最終,我們使用了2周就完成了從MySQL到MongoDB的代碼移植比預期的開發時間大大縮短。從我們的測試結果看也是非常驚人,數據量約2千萬,數據庫300G的情況下,讀寫2000rps,CPU等系統消耗是相當的低(我們的數據量還偏小,目前陸續有些公司也展示了他們的經典案例:MongoDB存儲的數據量已超過 50億,>1.5TB)。目前,我們將MongoDB和其他服務共同部署在一起,大大節約了資源。

一些小提示

切實領會MongoDB的Document模型,從實際出發,扔掉關系數據庫的范式思維定義,重新設計類;在服務端運行的JavaScript代碼避免使用遍歷記錄這種耗時的操作,相反要用Map/Reduce來完成這種表數據的處理;屬性的類型插入和查詢時應該保持一致。若插入時是字符串“1”,則查詢時用數字1是不匹配的;優化MongoDB的性能可以從磁盤速度和內存着手;MongoDB對每個Document的限制是最大不超過4MB;在符合上述條件下多啟用Embed Document, 避免使用DatabaseReference;內部緩存可以避免N+1次查詢問題(MongoDB不支持joins)。

 

 

用Capped Collection解決需要高速寫入的場合,如實時日志;大數據量情況下,新建同步時要調高oplogSize的大小,並且自己預先生成數據文件,避免出現客戶端超時;Collection+Index合計數量默認不能超過24000;當前版本(<v1.6)刪除數據的空間不能被回收,如果你頻繁刪除數據,那么需要定期執行repairDatabase,釋放這些空間。

 

 

-----------------------------------------------------

 

MongoDB授權和權限

  官方文檔開啟MongoDB 服務時不添加任何參數時,可以對數據庫任意操作,而且可以遠程訪問數據庫,所以推薦只是在開發是才這樣不設置任何參數。如果啟動的時候指定--auth參數,可以從阻止根層面上的訪問和連接

 

  (1)、只允許某ip訪問

  mongod --bind_ip 127.0.0.1

  (2)、指定服務端口

  mongod --bind_ip 127.0.0.1 --port27888

  (3)、添加用戶認證

  mongod --bind_ip 127.0.0.1 --port27888 –auth

  (4)、添加用戶

  在剛安裝完畢的時候MongoDB都默認有一個admin數據庫,而admin.system.users中將會保存比在其它數據庫中設置的用戶權限更大的用戶信息。

  當admin.system.users中一個用戶都沒有時,即使mongod啟動時添加了--auth參數,如果沒有在admin數據庫中添加用戶,此時不進行任何認證還是可以做任何操作,直到在admin.system.users中添加了一個用戶。

  下面分別創建兩個用戶, 在foo中創建用戶名為user1密碼為pwd1的用戶,如下:

 

[root@localhost bin]# ./mongo --port 27888
MongoDB shell version: 1.8.1
connecting to: test
> use foo
switched to db foo
> db.addUser("user1","pwd1")
{
        "user" : "user1",
        "readOnly" : false,
        "pwd" : "35263c100eea1512cf3c3ed83789d5e4"
}

  在admin中創建用戶名為root密碼為pwd2的用戶,如下:

> use admin
switched to db admin
> db.addUser("root", "pwd2")
{
        "_id" : ObjectId("4f8a87bce495a88dad4613ad"),
        "user" : "root",
        "readOnly" : false,
        "pwd" : "20919e9a557a9687c8016e314f07df42"
}
> db.auth("root", "pwd2")
1
>

在admin庫建立的用戶對所有庫有權限,而在指定庫的就只能在指定庫有權限

 

  (1)、mongoexport導出工具

  MongoDB提供了mongoexport工具,可以把一個collection導出成json格式或csv格式的文件。可以指定導出哪些數據項,也可以根據給定的條件導出數據。工具幫助信息如下:

[root@localhost bin]# ./mongoexport --help
options:
  --help                  produce help message
  -v [ --verbose ]        be more verbose (include multiple times for more 
                          verbosity e.g. -vvvvv)
  -h [ --host ] arg       mongo host to connect to ( <set name>/s1,s2 for sets)
  --port arg              server port. Can also use --host hostname:port
  --ipv6                  enable IPv6 support (disabled by default)
  -u [ --username ] arg   username
  -p [ --password ] arg   password
  --dbpath arg            directly access mongod database files in the given 
                          path, instead of connecting to a mongod  server - 
                          needs to lock the data directory, so cannot be used 
                          if a mongod is currently accessing the same path
  --directoryperdb        if dbpath specified, each db is in a separate 
                          directory
  -d [ --db ] arg         database to use
  -c [ --collection ] arg collection to use (some commands)
  -f [ --fields ] arg     comma separated list of field names e.g. -f name,age
  --fieldFile arg         file with fields names - 1 per line
  -q [ --query ] arg      query filter, as a JSON string
  --csv                   export to csv instead of json
  -o [ --out ] arg        output file; if not specified, stdout is used
  --jsonArray             output to a json array rather than one object per 
                          line
[root@localhost bin]#

 

  下面我們將以一個實際的例子說明,此工具的用法:

  將foo庫中的表t1導出成json格式:

[root@localhost bin]# ./mongoexport -d foo -c t1 -o /data/t1.json
connected to: 127.0.0.1
exported 1 records
[root@localhost bin]#

 

  導出成功后我們看一下/data/t1.json文件的樣式,是否是我們所希望的:

[root@localhost data]# more t1.json 
{ "_id" : { "$oid" : "4f927e2385b7a6814a0540a0" }, "age" : 2 }
[root@localhost data]#

 

  通過以上說明導出成功,但有一個問題,要是異構數據庫的遷移怎么辦呢?例如我們要將MongoDB的數據導入到MySQL該怎么辦呢?MongoDB提供了一種csv的導出格式,就可以解決異構數據庫遷移的問題了. 下面將foo庫的t2表的age和name列導出, 具體如下:

[root@localhost bin]# ./mongoexport -d foo -c t2 --csv -f age,name -o /data/t2.csv 
connected to: 127.0.0.1
exported 1 records
[root@localhost bin]#

 

  查看/data/t2.csv的導出結果:

[root@localhost data]# more t2.csv
age,name
1,"wwl"
[root@localhost data]#

 

  可以看出MongoDB為我們提供了一個強在的數據導出工具。

  (2)、mongoimport導入工具

  MongoDB提供了mongoimport工具,可以把一個特定格式文件中的內容導入到某張collection中。工具幫助信息如下:

 

[root@localhost bin]# ./mongoimport --help
options:
  --help                  produce help message
  -v [ --verbose ]        be more verbose (include multiple times for more 
                          verbosity e.g. -vvvvv)
  -h [ --host ] arg       mongo host to connect to ( <set name>/s1,s2 for sets)
  --port arg              server port. Can also use --host hostname:port
  --ipv6                  enable IPv6 support (disabled by default)
  -u [ --username ] arg   username
  -p [ --password ] arg   password
  --dbpath arg            directly access mongod database files in the given 
                          path, instead of connecting to a mongod  server - 
                          needs to lock the data directory, so cannot be used 
                          if a mongod is currently accessing the same path
  --directoryperdb        if dbpath specified, each db is in a separate 
                          directory
  -d [ --db ] arg         database to use
  -c [ --collection ] arg collection to use (some commands)
  -f [ --fields ] arg     comma separated list of field names e.g. -f name,age
  --fieldFile arg         file with fields names - 1 per line
  --ignoreBlanks          if given, empty fields in csv and tsv will be ignored
  --type arg              type of file to import.  default: json (json,csv,tsv)
  --file arg              file to import from; if not specified stdin is used
  --drop                  drop collection first 
  --headerline            CSV,TSV only - use first line as headers
  --upsert                insert or update objects that already exist
  --upsertFields arg      comma-separated fields for the query part of the 
                          upsert. You should make sure this is indexed
  --stopOnError           stop importing at first error rather than continuing
  --jsonArray             load a json array, not one item per line. Currently 
                          limited to 4MB.

  下面我們將以一人實際的例子說明,此工具的用法:

  先看一下foo庫中的t1表數據:

> db.t1.find();
{ "_id" : ObjectId("4f937a56450beadc560feaa9"), "age" : 5 }
>

  t1其中有一條age=5的記錄, 我們再看一下json文件中的數據是什么樣子的:

[root@localhost data]# more t1.json 

{ "_id" : { "$oid" : "4f937a56450beadc560feaa7" }, "age" : 8 }    

[root@localhost data]#

  可以看到t1.json文件中有一條age=8的數據,下面我們將用mongoimport工具將json文件中的記錄導入到t1表中:

[root@localhost bin]# ./mongoimport -d foo -c t1 /data/t1.json 
   
connected to: 127.0.0.1 
  
imported 1 objects

  工具返回信息說明向表中插入了一條記錄. 我們進庫里實際驗證一下:

[root@localhost bin]# ./mongo
MongoDB shell version: 1.8.1
connecting to: test
> use foo
switched to db foo
> db.t1.find();
{ "_id" : ObjectId("4f937a56450beadc560feaa9"), "age" : 5 }
{ "_id" : ObjectId("4f937a56450beadc560feaa7"), "age" : 8 }
>

 結果跟我們期待的是一樣的,數據成功插入到表中。

MongoDB備份和恢復

  MongoDB提供了兩個命令來備份(mongodump )和恢復(mongorestore )數據庫。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM