MongoDB數(shù)據(jù)庫學(xué)習(xí)

MongoDB

MongoDB是面向文檔的數(shù)據(jù)庫,而非關(guān)系型數(shù)據(jù)庫亏钩。它擴(kuò)展了關(guān)系型數(shù)據(jù)庫的眾多有用功能沛婴,如輔助查詢、范圍查詢和排序昔汉。

它將原來的行的概念換成更加靈活的文檔模型懈万。它沒有模式:文檔的鍵不會事先定義也不會固定不變。

MongoDB 將數(shù)據(jù)存儲為一個文檔靶病,數(shù)據(jù)結(jié)構(gòu)由鍵值(key=>value)對組成会通。MongoDB 文檔類似于 JSON 對象。字段值可以包含其他文檔娄周,數(shù)組及文檔數(shù)組涕侈。

有些關(guān)系型數(shù)據(jù)庫的常見功能MongoDB并不具備,比如聯(lián)接(join)和復(fù)雜的多行事務(wù)煤辨。

MongoDB 的擴(kuò)展性強(qiáng)驾凶,其采用的面向文檔的數(shù)據(jù)模型使其可以自動在多臺服務(wù)器之間分割數(shù)據(jù)。

MongoDB性能優(yōu)越掷酗。它將內(nèi)存管理工作交由操作系統(tǒng)處理;它利用查詢優(yōu)化器記住執(zhí)行查詢最高效的方式窟哺;它利用預(yù)分配數(shù)據(jù)文件的方式(用空間)換取性能的穩(wěn)定泻轰。

MongoDB的管理理念就是盡可能的讓服務(wù)器自動配置,簡化數(shù)據(jù)庫的管理且轨。比如如果主服務(wù)器掛掉浮声,它會自動切換到備份服務(wù)器上虚婿,并且將備份服務(wù)器提升為活躍服務(wù)器。

NoSQL簡介
NoSQL(NoSQL = Not Only SQL )泳挥,意即"不僅僅是SQL"然痊。但事實(shí)上很多NoSQL數(shù)據(jù)庫都放棄了對 SQL語言的支持。

MongoDB安裝啟動和停止

安裝方法見:

開啟mongod:

sudo service mongod start

進(jìn)入mongo shell:

mongo

列出數(shù)據(jù)庫:

show dbs

顯示當(dāng)前數(shù)據(jù)庫對象:

db

默認(rèn)是 test 屉符。

切換數(shù)據(jù)庫:

use <database>

停止 mongod:

sudo service mongod stop

或者使用下面更加穩(wěn)妥的方式停止MongoDB:

# 切換到admin數(shù)據(jù)庫(讓自己具有管理員權(quán)限)
use admin
db.shutdownServer()

剛安裝的mongodb并沒有開啟用戶權(quán)限驗證剧浸;所以連接時不需要認(rèn)證。

MongoDB的基本概念

在mongodb中基本的概念是文檔矗钟、集合唆香、數(shù)據(jù)庫。

SQL術(shù)語/概念 MongoDB術(shù)語/概念 解釋/說明
database database 數(shù)據(jù)庫
table collection 數(shù)據(jù)庫表/集合
row document 數(shù)據(jù)記錄行/文檔
column field 數(shù)據(jù)字段/域
index index 索引
table joins 表連接,MongoDB不支持
primary key primary key 主鍵,MongoDB自動將_id字段設(shè)置為主鍵

文檔

文檔類似于關(guān)系數(shù)據(jù)庫中的行吨艇。多個鍵及其關(guān)聯(lián)的值有序的放置在一起便是文檔躬它。在JS中,文檔表示為對象东涡。

每個文檔都有一個特殊的鍵_id冯吓,它在文檔所處的集合中是唯一的。

幾個重要的概念:

  • 文檔中的鍵/值對是有序的疮跑。

  • 文檔的鍵是字符串组贺。一般情況鍵可以使用UTF-8字符。

    • 鍵不能有\0空字符祸挪。它是用來表示鍵的結(jié)尾锣披。
    • .$只有在特定環(huán)境才能使用
    • _開頭的鍵是保留的
  • MongoDB不但區(qū)分類型,也區(qū)分大小寫贿条。下面是兩組不同的文檔:

    {"foo":3}
    {"foo":"3"}
    
    {"foo":3}
    {"Foo":3}
    

    ?

  • MongoDB的文檔不能有重復(fù)的鍵雹仿。

集合

集合可以被看作沒有模式的表。

子集合:

組織集合的一種慣例是使用 . 字符分開的命名空間劃分的子集合整以。比如:

blog.post和blog.authors胧辽,這樣做只是了使組織結(jié)構(gòu)更好些,也就是說blog這個集合(這里根本就不需要存在)及其子集合沒有任何關(guān)系公黑。

數(shù)據(jù)庫

一個MongoDB實(shí)例可以承載多個數(shù)據(jù)庫邑商。不同的數(shù)據(jù)庫存放在不同的文件中

要記住數(shù)據(jù)庫名最終會變成文件系統(tǒng)里的文件,所以數(shù)據(jù)庫名必須遵守一些約定凡蚜。

保留的特殊數(shù)據(jù)庫:

  • admin:從權(quán)限角度上看人断,這是 root 數(shù)據(jù)庫。
  • local:這個數(shù)據(jù)庫永遠(yuǎn)不會被復(fù)制朝蜘,可以用來存儲限于本地服務(wù)器的任意集合恶迈。
  • config:但Mongo用于分片設(shè)置時,config數(shù)據(jù)庫在內(nèi)部使用谱醇,用于保存分片的相關(guān)信息暇仲。

命名空間:把數(shù)據(jù)庫的名字放到集合名前面步做,得到的集合的完全限定名稱。

數(shù)據(jù)類型

MongoDB的文檔類似于JSON奈附,在概念上和JavaScript中的對象神似全度。MongoDB在保留JSON基本的鍵/值對特性的基礎(chǔ)上,添加了其它一些數(shù)據(jù)類型斥滤。在不同的編程語言下這些類型表示有些許差異将鸵。

  • null:

  • 布爾:

  • 32位整數(shù):

  • 64位整數(shù):

  • 64位浮點(diǎn)數(shù):

  • 字符串

  • 符號

  • 對象id:ObjectId()。(文檔必須有一個"_id"鍵中跌;這個鍵的值可以是任意類型咨堤,默認(rèn)是ObjectId對象。)

  • 日期: new Date()

  • 正則表達(dá)式:采用JavaScript的正則表達(dá)式語法

  • 代碼: 文檔中還可以包含JavaScript代碼

    {"x" : function(){/* */}}
    
  • 二進(jìn)制數(shù)據(jù):

  • 最大值

  • 最小值

  • undefined

  • 數(shù)組:值的集合或者列表可以表示成數(shù)組

    {"x" : ["a","b","c"]}
    
  • 內(nèi)嵌文檔:
    文檔可以包含別的文檔漩符,也可以作為值嵌入到父文檔中

    {"x" : {"foo" : "bar"}}
    

數(shù)據(jù)庫管理

默認(rèn)數(shù)據(jù)目錄 /data/db一喘,并使用27017端口。它還會啟動一個非呈缺基本的http服務(wù)器凸克,監(jiān)聽數(shù)字比主端口號高 1000 的端口,比如 28017 端口闷沥。

MongoDB Shell

MongoDB自帶一個 JavaScript shell萎战,可以從命令行與MongoDB實(shí)例交互。它也是一個完備的JS解釋器舆逃,可以運(yùn)行任何JS程序蚂维。

開啟的時候,shell會連接到MongoDB服務(wù)器的 test 數(shù)據(jù)庫路狮,并將這個數(shù)據(jù)庫連接賦值給全局變量 db 虫啥。這個變量是通過 shell 訪問 MongoDB的主要入口點(diǎn)。

shell還提供了一些語法糖奄妨,比如選擇數(shù)據(jù)庫的 usr dbName 涂籽,執(zhí)行該操作后 db 變量的值也會發(fā)生改變。

# 運(yùn)行 mongo 啟動 shell
mongo

# 列出數(shù)據(jù)庫
show dbs
# 切換數(shù)據(jù)庫砸抛,如果該數(shù)據(jù)庫不存在則創(chuàng)建該數(shù)據(jù)庫
use imooc
# 刪除數(shù)據(jù)庫
db.dropDatabase()

增刪改查

插入文檔

對目標(biāo)集使用insert方法评雌,插入一個文檔:

db.foo.insert({"bar":"baz"})

該操作會自動增加一個 "_id" 鍵(要是原來沒有)再保存到數(shù)據(jù)庫

批量插入:
批量插入能傳遞一個由文檔構(gòu)成的數(shù)組給數(shù)據(jù)庫。

插入數(shù)據(jù)時:數(shù)據(jù)庫只會驗證是否包含"_id"鍵直焙,然后就簡單的將文檔原樣的存入數(shù)據(jù)庫景东。

MongoDB在插入時并不執(zhí)行代碼,所以這塊沒有注入式攻擊的可能奔誓。

刪除文檔

刪除users集合中的所有文檔斤吐,但不刪除集合本身:

db.users.remove()

remove函數(shù)可以接受一個查詢文檔作為可選參數(shù)。這樣只有符合條件的文檔才能被刪除。
示例:所有"optout"為true的將被刪除:

db.mailing.list.remove({"opt-out" : true})

直接刪除集合: db.drop_collection("bar")

更新文檔

使用update方法曲初。該方法由兩個參數(shù),一個是查詢文檔杯聚,用來找出要更新的文檔臼婆;另一個是修改器(modifier)文檔,描述對找到的文檔做哪些更改幌绍。

更新操作是原子的:若是兩個更新同時發(fā)生颁褂,先到達(dá)服務(wù)器的先執(zhí)行,接著執(zhí)行另外一個傀广。

更新修改器:是一種特殊的鍵颁独,用來指定復(fù)雜的更新操作。

"$set"修改器

"$set"修改器用來指定一個鍵的值伪冰。如果這個鍵不存在誓酒,則創(chuàng)建它。
示例:添加喜歡的書籍到某用戶信息

db.users.update(
  {"_id":ObjectId("4fksdftudkf4964trub")}, //查詢文檔 
  {"$set":{"favorite book" : "war and peace"}} //修改器文檔
  )

對應(yīng)的可以使用 "$unset" 將鍵完全刪除贮聂。

"$inc"修改器

"$inc"修改器:用來增加已有的值靠柑,如果鍵不存在則創(chuàng)建一個鍵。

它只能用于整數(shù)吓懈、長整數(shù)活浮點(diǎn)數(shù)歼冰。

db.games.update({"game":"pinball","user":"joe"}, //查詢文檔
               {"$inc":{"score":50}})  //修改器文檔

上面示例:滿足條件的玩家加50分,如果分?jǐn)?shù)鍵(score)不存在則先創(chuàng)建該鍵耻警。這里增量為50隔嫡。

"$push"修改器

用于數(shù)組。"$push"修改器會向已有的數(shù)組末尾加入一個元素甘穿,若是該鍵不存在則會創(chuàng)建一個新的數(shù)組腮恩。

注意:這里是指集合中的某個鍵的值為數(shù)組,現(xiàn)在要向這個數(shù)組中添加元素扒磁。

比如 blog.post集合如下:

{
    id : ObjectId("4dkfs53rt9rufhvjr0fv"),
    title : "A blog post",
    content : "...",
    comments : [
        {
            name : "joe",
            email : "joe@gmail.com",
            content : "nice post"
        }
    ]
}

當(dāng)我們想向comments這個數(shù)組中添加一個元素庆揪,就可以使用 $push

查詢文檔

使用 find 或者 findOne 函數(shù)和查詢文檔對數(shù)據(jù)庫執(zhí)行查詢妨托。

查詢簡單的類型缸榛,只要指定想要查找的值就好了。示例兰伤,查找所有"age"的值為27的文檔:

db.users.find({"age":27})

查詢條件:

相關(guān)操作符 描述
$lt <
$lte <=
$gt >
$gte >=
$ne 不等于
$in 用來查詢一個鍵的多個值
$nin 返回與數(shù)組中所有條件都不匹配的文檔
$or 用來完成多個鍵值的任意給定值
$not 是元語句内颗,可以用在任何其他條件之上

查詢在 18 ~ 30歲的用戶:

db.users.find({"age": {"$gte": 18, "$lte": 30} })

使用$in對單個鍵做OR查詢

db.raffle.find({"ticket_no" : {"$in" : [725,542,390]}})

使用$or可以對多個鍵做OR查詢。示例敦腔,找到 ticket_no 為 725或者winner為true的文檔:

db.raffle.find({"$or" : [{"ticket_no" : 725}, {"winner", true}]})

查詢數(shù)組

例如:數(shù)組是一個水果清單

db.food.insert({"fruit" : ["apple","banana","peach"]})

下面的查詢會匹配該文檔:

db.food.find({"fruit","banana"})

$all:通過多個元素來匹配數(shù)組均澳。
找到既有 apple 又有 banana 的文檔:

db.food.find({fruit: {$all : ["apple","banana"]}})

$size用于查詢指定長度的數(shù)組。

db.food.find({fruit: {$size : 3}})

查詢內(nèi)嵌文檔

如果允許通常只針對內(nèi)嵌文檔的特定鍵值進(jìn)行查詢才是比較好的做法,這樣即便數(shù)據(jù)模式改變找前,也不會有太大問題糟袁。

我們可以使用"點(diǎn)表示法"查詢內(nèi)嵌的鍵:

db.people.find({"name.first" : "Joe", "name.last" : "Schome"})

"$where"查詢

"$where"子句可以執(zhí)行任意JavaScipt作為查詢的一部分。由了它的補(bǔ)充躺盛,使得查詢能做任何事情项戴。

最典型的應(yīng)用就算比較文檔中的兩個鍵的值是否相等。

db.foo.find({"$where" : "function(){return this.x + this.y == 10; }" })

注意:"$where"查詢在速度上要比其他常規(guī)查詢慢很多槽惫。

游標(biāo)

數(shù)據(jù)庫使用 游標(biāo) 來返回find的執(zhí)行結(jié)果周叮。find返回的對象就是一個游標(biāo)。

游標(biāo)的方法:

  • next():獲取下一個結(jié)果
  • hasNext():檢查是否有后續(xù)結(jié)果存在
  • limit():限制結(jié)果數(shù)量
  • skip():忽略一定數(shù)量的結(jié)果
  • sort():對結(jié)果排序

幾乎所有的游標(biāo)的方法返回值也是游標(biāo)界斜,這樣就可以組成方法鏈仿耽。

管理MongoDB

從命令行啟動MongoDB

直接執(zhí)行 mongod,即可簡單的啟動服務(wù)器各薇。該命令還有很多可配置的啟動選項:

選項 描述
--help 查看所有選項
--dbpath 指定數(shù)據(jù)目錄项贺。默認(rèn)值是/data/db
--port 指定服務(wù)器監(jiān)聽的端口號
--fork 以守護(hù)進(jìn)程的方式運(yùn)行MongoDB,創(chuàng)建服務(wù)器進(jìn)程
--logpath 指定日志輸出路徑得糜,而不是輸出到命令行
--config 指定配置文件敬扛。配置文件中 #是注釋符號;語法形式是"選項-值"的形似朝抖。

每個mongod進(jìn)程都需要獨(dú)立的數(shù)據(jù)目錄啥箭。當(dāng)mongod啟動時,會在數(shù)據(jù)目錄中創(chuàng)建mongod.lock文件治宣,該文件用于防止其他mongod進(jìn)程使用該數(shù)據(jù)目錄急侥。并且要給它們指定不同的端口號。

停止MongoDB

這里只介紹一個穩(wěn)妥的停止數(shù)據(jù)庫的方法:使用shutdown命令侮邀,{"shutdown" : 1}坏怪,這是管理命令,要在 admin 數(shù)據(jù)庫下使用绊茧。 MongoDB shell 提供了輔助函數(shù)铝宵,來簡化這一過程:

> use admin
switched to db admin
> db.shutdownServer();
server should be down...

學(xué)習(xí)資料

《MongoDB權(quán)威指南》
MongoDB 教程 - 菜鳥教程
官方手冊:The MongoDB Manual
MongoDB中文社區(qū)
MongoDB中文網(wǎng)
Mongodb最佳實(shí)踐-麥子學(xué)院
MongoDB基礎(chǔ)教程-慕課網(wǎng)課程
圖形工具: Robo 3T - formerly Robomongo — native MongoDB management tool (Admin UI)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市华畏,隨后出現(xiàn)的幾起案子鹏秋,更是在濱河造成了極大的恐慌,老刑警劉巖亡笑,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件侣夷,死亡現(xiàn)場離奇詭異,居然都是意外死亡仑乌,警方通過查閱死者的電腦和手機(jī)百拓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門琴锭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人衙传,你說我怎么就攤上這事决帖。” “怎么了蓖捶?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵古瓤,是天一觀的道長。 經(jīng)常有香客問我腺阳,道長,這世上最難降的妖魔是什么穿香? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任亭引,我火速辦了婚禮,結(jié)果婚禮上皮获,老公的妹妹穿的比我還像新娘焙蚓。我一直安慰自己,他們只是感情好洒宝,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布购公。 她就那樣靜靜地躺著,像睡著了一般雁歌。 火紅的嫁衣襯著肌膚如雪宏浩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天靠瞎,我揣著相機(jī)與錄音比庄,去河邊找鬼。 笑死乏盐,一個胖子當(dāng)著我的面吹牛佳窑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播父能,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼神凑,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了何吝?” 一聲冷哼從身側(cè)響起溉委,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎岔霸,沒想到半個月后薛躬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡呆细,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年型宝,在試婚紗的時候發(fā)現(xiàn)自己被綠了八匠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡趴酣,死狀恐怖梨树,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情岖寞,我是刑警寧澤抡四,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站仗谆,受9級特大地震影響指巡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜隶垮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一藻雪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧狸吞,春花似錦勉耀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至威始,卻和暖如春枢纠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背黎棠。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工京郑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人葫掉。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓些举,卻偏偏與公主長得像,于是被迫代替她去往敵國和親俭厚。 傳聞我的和親對象是個殘疾皇子户魏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容