我叫MongoDb,不懂我的看完我的故事您就入門啦!

 

 

這是mongo基礎篇,後續會連續更新4篇

大家好我叫MongoDb,自從07年10月10gen團隊把我帶到這個世界來,我已經13歲多啦,現在越來越多的小夥伴在擁抱我,我很高興。我是NoSQL大家族的一員,我是C++的親兒子啦。為了大家更好的熟悉我,今天我先簡單從簡單的使用角度來介紹我自己。

首先還是先介紹一下我們的大家族NoSQL吧

NoSQL只是他簡稱,他的中文名叫 非關係型數據庫,外文名叫Not Only SQL。他是對關係型數據庫的一個補充(RDBMS)。RDBMS追求數據存儲和查詢的高度結構化、嚴格的數據一致性;NOSQL不在乎形式,重點關心效率,NOSQL是高性能、無模式、高可擴展的分佈式數據庫,NOSQL存儲包括四種類型:鍵值對存儲、列存儲、文檔存儲、圖形數據存儲。NoSQL就簡單介紹到這,這不是今天的重點,下面還是重點介紹一下我自己(MongoDb),呵呵!

MongoDb自我介紹

MongoDb是一個面向文檔存儲的鍵值對NOSQL數據庫,是一個最接近關係型數據庫的非關係數據庫。在數據存儲結構和查詢上使用BJOSN(類似於JSON)結構,BJOSN支持多層機構,在具體的使用過程中,更像是操作Javascript腳本。正因為MongoDb的無模式化,在實際應用中變得更加靈活,易於擴展。與RDBMS一樣,支持主鍵、索引、檢索等操作,由於非結構化所以不支持join查詢。

MongoDb的基本概念

具體的數據庫安裝就不在介紹了,網上一搜一大推。MongoDb採用BJON化的文檔存儲,所以其基本結構概念可以結合JSON聯想一下:字段、文檔、集合、數據庫,這和RDBMS的屬性、列、表、數據庫是一一對應關係。下面以一個表格來對比說明一下:

 

RDBMS

MongoDb

概念

說明

概念

說明

database

數據庫

database

數據庫

table

collection

集合

row

document

文檔:對應的一個BJSON

column

field

字段:BJSON中的具體某一個字段

 

簡單的一個表格顯示還不夠直觀,那我們在來一張形象的圖片來說明一下吧!

 

 

 

 

 

   

用戶權限管理

在生成環境數據庫管理中,數據庫權限是一個很重要的功能。在具體的權限上,需要針對全局的權限控制,需要精確到具體的數據的權限,在具體的權限分類上包括:讀、讀寫、管理員等權限。下面列表介紹mongodb的內置權限:

權限名稱

權限說明

read

允許用戶讀取指定數據庫

readWrite

允許用戶讀寫指定數據庫

dbAdmin

允許用戶在指定數據庫中執行管理函數,如索引創建、刪除,查看統計或訪問system.profile

userAdmin

允許用戶向system.users集合寫入,可以找指定數據庫里創建、刪除和管理用戶

clusterAdmin

只在admin數據庫中可用,賦予用戶所有分片和複製集相關函數的管理權限。

readAnyDatabase

只在admin數據庫中可用,賦予用戶所有數據庫的讀權限

readWriteAnyDatabase

只在admin數據庫中可用,賦予用戶所有數據庫的讀寫權限

userAdminAnyDatabase

只在admin數據庫中可用,賦予用戶所有數據庫的userAdmin權限

dbAdminAnyDatabase

只在admin數據庫中可用,賦予用戶所有數據庫的dbAdmin權限。

root

只在admin數據庫中可用。超級賬號,超級權限

通過上面的表,我們可以得出:根據權限的作用範圍上來看,權限分為了兩大類權限:針對每一庫的權限、針對全部數據庫的權限。根據不同的權限分類,在賦值格式上也有一定差異,在具體的用戶權限分配上,一個用戶可以同時分配多個權限。

新增用戶時權限初始化格式為:

針對全部數據庫權限初始化命令格式:

db.createUser({user:”用戶名”,pwd:”密碼”,roles:[“權限值”]})

針對指定數據庫權限初始化命令格式:

db.createUser({user:”用戶名”,pwd:”密碼”,roles:[ {role:”權限值”,db:”對應的數據庫”},{role:”權限值”,db:”對應的數據庫”}….]})

這樣說可能不怎麼好理解,那麼我們還是以實際工作的使用情況來舉例說明。

條件假設:有3個數據庫:testdb001、testdb002

需要給如用戶分配對應的權限

用戶

需要分配的權限

具體的命令

adminRoot

超級賬號,具有所有數據庫的全部操作權限

use admin

db.createUser({user:”adminRoot”,pwd:”123″,roles:[“root”]})

adminWrite

超級寫賬號,具有所有數據庫的讀寫操作權限

use admin

db.createUser({user:”adminWrite”,pwd:”123″,roles:[“readWriteAnyDatabase”]})

adminRead

超級寫賬號,具有所有數據庫的讀操作權限

use admin

db.createUser({user:”adminRead”,pwd:”123″,roles:[“readAnyDatabase”]})

001Write

具有數據庫testdb001的讀寫操作權限

use admin

db.createUser({user:”001Write”,pwd:”123″,roles:[ {role:”readWrite”,db:” testdb001″}]})

001Read

具有數據庫testdb001的讀操作權限

use admin

db.createUser({user:”001Read”,pwd:”123″,roles:[ {role:”read”,db:” testdb001″}]})

012Write

具有數據庫testdb001、testdb002的讀寫操作權限

use admin

db.createUser({user:”001Write”,pwd:”123″,roles:[ {role:”readWrite”,db:” testdb001″},{role:”readWrite”,db:” testdb002″}]})

通過實際舉例,應該對權限的新增初始化操作命令有了理解,那麼下面我們就來對權限的根據新操作命令簡單聊聊,其實根系和初始化具體的權限格式是一至的,具體如下:

針對全部數據庫權限更新命令格式:

db.updateUser(“被更新用戶名”,{pwd:”更新後的密碼”,roles:[“權限值”]})

針對指定數據庫權限更新命令格式:

db.updateUser(“被更新用戶名”,{pwd:”更新後的密碼”,roles:[{role:”權限值”,db:”對應的數據庫”},{role:”權限值”,db:”對應的數據庫”}….]})

注意:updateUser的第二個參數有兩個節點:pwd和roles。如果不需要更新某一節點的數據,那麼直接不要該節點即可。

實例:繼續上面的實例繼續操作

用戶更新述求

具體的命令

更新用戶adminRoot的密碼為111111

use admin

db.updateUser(“adminRoot”,{pwd:”111111″})

更新001Write的同時具有testdb001和testdb002的寫權限

use admin

db.updateUser(“adminWrite”,{roles:[ {role:”readWrite”,db:” testdb001″},{role:”readWrite”,db:” testdb002″}]})

更新001Read的同時具有testdb001和testdb002的讀權限,並且密碼也更新為111111

use admin

db.updateUser(“001Read”,{ pwd:”111111″,roles:[ {role:”read”,db:” testdb001″},{role:”read”,db:” testdb002″}]})

 

數據庫(database)

具體的數據庫概念和RDBMS一致,一個mongodb可以創建多個數據庫,不同數據庫也可以存儲在不同的mongodb。系統的默認數據庫包括:admin(存儲用戶權限相關)、config(配置信息)、local(日誌信息)。針對數據庫我們常用的操作包括:創建、刪除。具體的實現如下:

創建:use 數據庫名稱

當數據庫名稱不存在時,系統自動創建(創建後不能顯示,需要向裏面插入數據才會顯示),存在則切換。

刪除:首先要切換到對於的數據庫,然後在執行dropDatabase命令

use 被刪除的數據庫名稱

db.dropDatabase()

 

集合(Collection)

集合是mongodb中對數據存儲的一個分組,和關係數據庫中的表是對應關係。集合中存儲的文檔數據的無固定格式,可以自由存儲不同格式的bjson數據,但是在實際使用中,我們還是存儲同一類型的bjson數據。集合的常見的操作命令如下:

創建集合:

db.createCollection(集合名稱,集合規則),其中第二次參數為一個json數據,非必填,具體的參數節點為:

集合規則:{ capped :選填bool類型:設置改集合是否為一個固定集合,

true:代表固定集合,集合中的數據不可修改,與size配對使用,代表當集合達到指定大小後,會自動覆蓋歷史數據(最先添加的數據),

size:選填數字類型:指定集合的最大存儲數據(位元組數),當集合達到指定大小後,會自動覆蓋歷史數據(最先添加的數據) }

max: 選填數字類型:指定集合的最大存儲的文檔總個數,當文檔個數大於max值時,會自動替換歷史文檔

}

collection刪除:

db.集合名稱.drop();

 

文檔(Document)

文檔就一組鍵值(key-value)對數據(一個BJON),具體的一個文檔結構可以多層嵌套,不同文檔間的數據結構可以不一樣,並且相同節點的數據類型也可不一樣,這是與RDBMS最大的區別所在,這也奠定了MongoDB的高可擴展性。其實簡單的說就是一個一個的jon格式的數據。

文檔常見的幾個操作命令匯總:

操作

命令格式

插入數據

db.集合名稱.insert(json對象)  json可以是單個數據,也可以是一個集合列表

更新數據

db. 集合名稱.update(query , update,option)

query :被更新文檔條件json

update:更新後的文檔json

option:更新方式json,參數格式為{ upsert: boolean, multi : boolean }

upsert:非必填參數,如果不存在是否新增,當值為true時,如果沒有符合條件的數據,就插入數據, ,默認為false

multi: 非必填參數,是否更新符合要求的所有數據,當值為true時,符合條件的數據全部更新,默認為false

刪除數據

db.集合名稱.remove(query , justOne )

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

justOne : (可選)如果設為 true 或 1,則只刪除一個文檔,如果不設置該參數,或使用默認值 false,則刪除所有匹配條件的文檔。

查詢數據

db.集合名稱.find(jison對象查詢條件)

 

字段

字段就很好理解了,就是文檔中的json數據的每一個節點。

 

 

 

通過對mongodb的操作簡單介紹,其實我們不難發現以下一些特性:

1.無論是對文檔的增、刪、改、查操作的參數一切皆json,在實際操作的時候,按照json方式來操作即可。

2.數據庫和集合都可以在使用是自動創建:

2.1 use 切換數據庫時,如果沒有數據庫自動創建;

2.2 db.集合.insert() 當集合不存在時,系統自動創建集合。

Mongodb的這一些特性用起來是不是很爽的感覺。下面從數據庫的創建,到文檔的整體操作流程寫一些演示實例,來加深印象。

操作

命令格式

連接到mongdb

mongo

use admin

db.auth(“用戶名”,”用戶密碼”)

創建數據庫 bd001和表user001

use bd001

db.createCollection(“user001”)

創建數據庫 bd002和user002

use bd002

db.createCollection(“user002”)

查看所有數據庫

show dbs

輸出結果

admin   0.000GB

config  0.000GB

local   0.000GB

bd001  0.000GB

bd002  0.000GB

刪除集合user002

use db002

db.user002.drop()

刪除數據庫db002

use db002

db. dropDatabase()

向表user001插入一條數據

use db001

db.user001.insert({name:」程序員修鍊之旅」,age:2})

向表user001插入兩條數據

use db001

db.user001.insert([

{name:”mongodb”,age:12,type:”database”},

{“name”:”.net”,from:”U.S.A”}

])

向表user001插入三條數據

use db001

db.user001.insert([

{name:”zhangsan”,age:12,sex:”man”},

{name:”zhangsan”,age:18,sex:”woman”},

{name:”zhangsan”,age:22,sex:”man”}

])

查詢一下表中的數據情況

use db001

db.user001.find()

查詢結果:

{ “_id” : ObjectId(“5fa0ab4195368a0bf20f38cd”), “name” : “程序員修鍊之旅”, “age” : 2 }

{ “_id” : ObjectId(“5fa0abb495368a0bf20f38d0”), “name” : “.net”, “from” : “U.S.A” }

{ “_id” : ObjectId(“5fa0ad3b95368a0bf20f38d1”), “name” : “zhangsan”, “age” : 12, “sex” : “man” }

{ “_id” : ObjectId(“5fa0ad3b95368a0bf20f38d2”), “name” : “zhangsan”, “age” : 18, “sex” : “woman” }

{ “_id” : ObjectId(“5fa0ad3b95368a0bf20f38d3”), “name” : “zhangsan”, “age” : 22, “sex” : “man” }

查詢表中name=”程序員修鍊之旅”的數據

use db001

db.user001.find({name: “程序員修鍊之旅”})

查詢結果:

{ “_id” : ObjectId(“5fa0ab4195368a0bf20f38cd”), “name” : “程序員修鍊之旅”, “age” : 2 }

修改表中name=”程序員修鍊之旅”的數據的age=66,並新增一個節點from節點

use db001

db.user001.update({name: “程序員修鍊之旅”},{$set:{age:66,from: “CDU”}})

查看修改後的數據

use db001

db.user001.find({name: “程序員修鍊之旅”})

查詢結果:

{ “_id” : ObjectId(“5fa0ab4195368a0bf20f38cd”), “name” : “程序員修鍊之旅”, “age” : 66,from: “CDU”}

數據已經是修改後的數據了

修改表中name=” zhangsan”的數據的age=88,並且只修改一條符合要求的數據

use db001

db.user001.update({name: “zhangsan”},{$set:{age:88}},{ multi:false})

查看name=” zhangsan”修改後的數據,是否只有一條數據的age被修改為88?

use db001

db.user001.find({name: “zhangsan”})

查詢結果:

{ “_id” : ObjectId(“5fa0ad3b95368a0bf20f38d1”), “name” : “zhangsan”, “age” : 88, “sex” : “man” }

{ “_id” : ObjectId(“5fa0ad3b95368a0bf20f38d2”), “name” : “zhangsan”, “age” : 18, “sex” : “woman” }

{ “_id” : ObjectId(“5fa0ad3b95368a0bf20f38d3”), “name” : “zhangsan”, “age” : 22, “sex” : “man” }

只有第一條的age被修改為了88

修改表中name=” zhangsan”的數據的age=99,修改符合要求的所有數據

use db001

db.user001.update({name: “zhangsan”},{$set:{age:99}},{ multi:true})

查看name=” zhangsan”修改後的數據,是否只所有數據的age被修改為99?

use db001

db.user001.find({name: “zhangsan”})

查詢結果:

{ “_id” : ObjectId(“5fa0ad3b95368a0bf20f38d1”), “name” : “zhangsan”, “age” : 99, “sex” : “man” }

{ “_id” : ObjectId(“5fa0ad3b95368a0bf20f38d2”), “name” : “zhangsan”, “age” : 99, “sex” : “woman” }

{ “_id” : ObjectId(“5fa0ad3b95368a0bf20f38d3”), “name” : “zhangsan”, “age” : 99, “sex” : “man” }

name=”zhangsan”的所有數據age被修改為了99

修改name=”lisi”的age=77

use db001

db.user001.update({name: “lisi”},{$set:{age:77}})

查看數據修改結果

由於沒有name=lisi的數據,所有查詢不到數據

use db001

db.user001.find({name: “lisi”})

查詢結果:

無數據

修改name=”lisi”的age=77,如果沒有則新增

use db001

db.user001.update({name: “lisi”},{$set:{age:77}},{ upsert:true})

查看數據修改結果

新增了一條name=”lisi”的數據

use db001

db.user001.find({name: “lisi”})

查詢結果:

{ “_id” : ObjectId(“5fa0b3731b875939723ffe26”), “name” : “lisi”, “age” : 77 }

刪除一條name=”zhangsan”的數據

use db001

db.user001.rmove({name: “zhangsan”},1)

查看刪除結果

use db001

db.user001.find({name:”zhangsan”})

查詢結果:

{ “_id” : ObjectId(“5fa0ad3b95368a0bf20f38d2”), “name” : “zhangsan”, “age” : 18, “sex” : “woman” }

{ “_id” : ObjectId(“5fa0ad3b95368a0bf20f38d3”), “name” : “zhangsan”, “age” : 22, “sex” : “man” }

name=”zhangsan”的數據數據由原來的3條變為了2條,被刪除了一條

刪除所有name=”zhangsan”的數據

use db001

db.user001.rmove({name: “zhangsan”})

查看刪除結果

use db001

db.user001.find({name:”zhangsan”})

查詢結果:

無數據

name=”zhangsan”的數據數據被全部刪除了

通過上面的實際操作,我們發現所有新增文檔都會自動生成一個節點」_id」( ObjectId),該_id是mongodb系統自動生成的類似唯一主鍵,可以很快的去生成和排序,包含 12 bytes,含義是:

 

 

1.前 4 個位元組表示創建 unix 時間戳,格林尼治時間 UTC 時間,比北京時間晚了 8 個小時

2.接下來的 3 個位元組是機器標識碼

3.緊接的兩個位元組由進程 id 組成 PID

4.最後三個位元組是隨機數

當然_id也可以根據實際需要自定義賦值。

好了今天就先寫到這,通過本篇文章對mongo有了一個初步的認識了解,下一篇文章,我們在一起詳聊查詢,mongo的查詢還是有很多聊的。謝謝您的查看。

 

END
為了更高的交流,歡迎大家關注我的公眾號,掃描下面二維碼即可關注,謝謝: