第十三節(jié): mongodb數(shù)據(jù)庫(kù)


1. 數(shù)據(jù)庫(kù)(Database)的概述

1.1 什么是數(shù)據(jù)庫(kù)

數(shù)據(jù)庫(kù)(Database)是按照數(shù)據(jù)結(jié)構(gòu)來(lái)組織,存儲(chǔ)和管理數(shù)據(jù)的倉(cāng)庫(kù),

他產(chǎn)生于距今六十年前,隨著信息技術(shù)和市場(chǎng)的發(fā)展,特別是二十世紀(jì)九十年代以后,數(shù)據(jù)庫(kù)技術(shù)得到了更快速的發(fā)展,應(yīng)用得更加廣泛,主要用它進(jìn)行管理各種系統(tǒng)的數(shù)據(jù),作為科學(xué)研究和決策的重要技術(shù)手段


1.1.1 為什么需要數(shù)據(jù)庫(kù)

我們的程序是在內(nèi)存中運(yùn)行的,一旦程序運(yùn)行結(jié)束,或者計(jì)算機(jī)斷電,程序運(yùn)行中的數(shù)據(jù)都會(huì)丟失,所以我們需要將一些運(yùn)行的數(shù)據(jù)持久化到硬盤中, 以確保數(shù)據(jù)的安全,數(shù)據(jù)庫(kù)就是數(shù)據(jù)持久化最佳的選擇.

簡(jiǎn)單說(shuō): 數(shù)據(jù)庫(kù)就是存儲(chǔ)數(shù)據(jù)的倉(cāng)庫(kù)


1.1.2 數(shù)據(jù)庫(kù)的分類
  1. 關(guān)系型數(shù)據(jù)庫(kù)

    MySQL, Oracle,DB2, SQL Server....

  2. 非關(guān)系型數(shù)據(jù)庫(kù)

    MongoDB, Redis....


1.2. 關(guān)系型數(shù)據(jù)庫(kù)

按照關(guān)系模型存儲(chǔ)數(shù)據(jù)的數(shù)據(jù)庫(kù),數(shù)據(jù)與數(shù)據(jù)之間的關(guān)聯(lián)非常密切,可以實(shí)現(xiàn)跨數(shù)據(jù)表查詢數(shù)據(jù),占用更少的硬盤實(shí)現(xiàn)更多的數(shù)據(jù)存儲(chǔ)

T-SQL標(biāo)準(zhǔn)的結(jié)構(gòu)化查詢語(yǔ)言是關(guān)系型數(shù)據(jù)庫(kù)的通用查詢語(yǔ)言

關(guān)系型數(shù)據(jù)庫(kù)的特點(diǎn): 全都是表

常見(jiàn)的關(guān)系型數(shù)據(jù)庫(kù),MySQL, Oracle,DB2, SQL Server


1.3. 非關(guān)系型數(shù)據(jù)庫(kù)

不按關(guān)系模型存儲(chǔ)數(shù)據(jù)的數(shù)據(jù)庫(kù),統(tǒng)稱NoSQL,

  1. 第一層意思: 不是SQL(關(guān)系型數(shù)據(jù)庫(kù)),
  2. 第二層意思, Not Only SQL 不僅僅是SQL

非關(guān)系型數(shù)據(jù)庫(kù)的特點(diǎn): 是鍵值對(duì)數(shù)據(jù)庫(kù),

常用的就是 MongoDB(非關(guān)系型數(shù)據(jù)庫(kù)中的文檔數(shù)據(jù)庫(kù))


2. MongoDB 簡(jiǎn)介

MongoDB是一個(gè)基于分布式文件存儲(chǔ)的數(shù)據(jù)庫(kù),目前是世界上用的最多的,功能最豐富非關(guān)系型數(shù)據(jù)庫(kù),也是最像關(guān)系型數(shù)據(jù)庫(kù)的

mongodb 的特點(diǎn)是高性能,易部署,易使用,存儲(chǔ)數(shù)據(jù)非常方便,


2.1 Mongodb數(shù)據(jù)庫(kù)最重要的三個(gè)概念
  1. 數(shù)據(jù)庫(kù)(database)

    數(shù)據(jù)庫(kù)就是一個(gè)倉(cāng)庫(kù),在倉(cāng)庫(kù)里可以存放集合

  2. 集合( collection)

    集合類似于數(shù)組,在集合中可以存放文檔

  3. 文檔( document)

    文檔數(shù)據(jù)庫(kù)中最小的單位,我們存儲(chǔ)和操作的內(nèi)容都是文檔

三個(gè)關(guān)系之間的關(guān)系

mongodb.png

一個(gè)mongodb數(shù)據(jù)庫(kù)服務(wù)器上可以有n多個(gè)database數(shù)據(jù)庫(kù)

一個(gè)database數(shù)據(jù)庫(kù)可以有n多個(gè) collection 數(shù)據(jù)集合

一個(gè)collection 數(shù)據(jù)集合中可以有n多個(gè) document 文檔數(shù)據(jù)


3. MongoDB 安裝

3.1. 官網(wǎng)下載MongoDB

MongoDB 對(duì)于32位系統(tǒng)支持不好,3.2版本之后就不在支持32位系統(tǒng)安裝了

官網(wǎng)下載.png
官網(wǎng)下載2.png

也可以通過(guò)如下地址下載安裝mongodb

https://www.mongodb.org/dl/win32


3.2. 配置環(huán)境變量

安裝完畢以后,你會(huì)發(fā)現(xiàn)沒(méi)法使用,Mongodb跟Node不一樣,Node安裝是直接幫我們配置好了環(huán)境變量,Mongodb不會(huì),所以我們要自己配置環(huán)境變化

配置環(huán)境變量.png


3.3. 創(chuàng)建數(shù)據(jù)庫(kù)存放位置(盡量在非系統(tǒng)盤創(chuàng)建)
  1. 創(chuàng)建一個(gè)mongdb文件夾,用來(lái)存儲(chǔ)數(shù)據(jù)和日志
  2. mongodb文件內(nèi)創(chuàng)建db文件夾和log文件


3.4 開(kāi)啟數(shù)據(jù)庫(kù)服務(wù)

使用mongod命令連接數(shù)據(jù)存放的位置,使用兩個(gè)參數(shù)鏈接數(shù)據(jù)存放的位置,和日志存放的位置

mongod --dbpath "數(shù)據(jù)存儲(chǔ)位置" --logpath "日志存儲(chǔ)位置"



--dbpath 表示數(shù)據(jù)存放的路徑

此時(shí)一但數(shù)據(jù)庫(kù)連接成功后光標(biāo)掛起,沒(méi)有返回,

此時(shí)注意,這個(gè)CMD窗口不能關(guān)閉,一但關(guān)閉數(shù)據(jù)庫(kù)連接就關(guān)閉了

所以需要重新開(kāi)一個(gè)CMD窗口操作數(shù)據(jù)庫(kù)命令

我們還可以通過(guò)--port改變數(shù)據(jù)庫(kù)默認(rèn)端口


3.5 關(guān)閉服務(wù)器
mongod --shuntdown


3.6 mongod與mongo命令

mongod是用來(lái)開(kāi)啟數(shù)據(jù)庫(kù)服務(wù)器的,服務(wù)器的作用是用來(lái)保存數(shù)據(jù)的

mongo命令是數(shù)據(jù)庫(kù)的客戶端,用來(lái)連接數(shù)據(jù)庫(kù)服務(wù)器,對(duì)數(shù)據(jù)進(jìn)行增刪改查的操作


3.7. 使用基礎(chǔ)命令
3.7.1 進(jìn)入數(shù)據(jù)庫(kù)REPL環(huán)境
$ mongo  

進(jìn)入數(shù)據(jù)庫(kù)管理模式

進(jìn)入的是mongo的REPL環(huán)境(Read-Evel-Print-Loop,讀一句,執(zhí)行一句,顯示一句)


3.7.2 退出數(shù)據(jù)庫(kù)的REPL模式
$ exit

退出數(shù)據(jù)庫(kù)管理模式


4 數(shù)據(jù)庫(kù)操作命令

4.1. 查看所有數(shù)據(jù)庫(kù),顯示所有數(shù)據(jù)庫(kù)集合
> show dbs    


4.2. 使用數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)名不存在就創(chuàng)建數(shù)據(jù)庫(kù)(存在就進(jìn)入使用數(shù)據(jù)庫(kù))
> use student

? 數(shù)據(jù)庫(kù)里沒(méi)有數(shù)據(jù)時(shí),在使用查看數(shù)據(jù)庫(kù)命令時(shí)是不顯示出來(lái)的


4.3. 查看當(dāng)前正在使用的數(shù)據(jù)庫(kù)
> db


4.4. 刪除數(shù)據(jù)庫(kù)
> db.dropDatabase()  


5. 數(shù)據(jù)集合操作命令

5.1. 顯示當(dāng)前數(shù)據(jù)庫(kù)中的所有集合
> show collections


5.2. 創(chuàng)建集合
5.2.1 使用createCollection() 方法創(chuàng)建集合
> db.createCollection(name,options)

? 參數(shù):

? name 創(chuàng)建集合的名字

? options 可選參數(shù),指定有關(guān)內(nèi)存大小及索引選項(xiàng)

options參數(shù)

  1. name:集合的名字
  2. capped:是否啟用集合限制,如果開(kāi)啟需要制定一個(gè)限制條件,默認(rèn)為不啟用,這個(gè)參數(shù)沒(méi)有實(shí)際意義
  3. size:限制集合使用空間的大小,默認(rèn)為沒(méi)有限制
  4. max:集合中最大條數(shù)限制,默認(rèn)為沒(méi)有限制
  5. autoIndexId:是否使用_id作為索引,默認(rèn)為使用(true或false)
  6. size的優(yōu)先級(jí)比max要高

完整的命令如些

db.createCollection(name, {capped: <Boolean>, autoIndexId: <Boolean>, size: <number>, max <number>} )

通常在創(chuàng)建數(shù)據(jù)時(shí)自動(dòng)創(chuàng)建集合,不需要單獨(dú)創(chuàng)建,這個(gè)不常用


5.2.2 自動(dòng)創(chuàng)建集合

如果你想創(chuàng)建一個(gè)集合,肯定是希望給這個(gè)集合里添加內(nèi)容, 那么只需要正常使用集合插入數(shù)據(jù)就和了,mongodb會(huì)自動(dòng)檢測(cè),如果集合存在就正常插入,如果集合不存在,就自動(dòng)創(chuàng)建集合

db.集合名.insert(插入的數(shù)據(jù))

示例:

db.student.insert({name:"小明",age:10})


5.3. 刪除集合
db.集合名.drop()


6. 數(shù)據(jù)庫(kù)文檔的操作命令

6.1. 插入數(shù)據(jù)(新增文檔)

語(yǔ)法:

db.集合名.insert()
db.集合名.save()


6.1.1 insert() 方法

insert()方法在插入數(shù)據(jù)是,可以插入一條數(shù)據(jù),也可以插入多條數(shù)據(jù)

插入一條數(shù)據(jù),參數(shù)為一個(gè)文檔, 插入多條數(shù)據(jù)為多個(gè)文檔的數(shù)組集合

# 插入一條數(shù)據(jù)
db.student.insert({name:"小明",age:18})

#插入多條數(shù)據(jù)
 db.student.insert([{name:"小明",age:13},{name:"小紅",age:15}])

insert方法還有兩個(gè)拆分的命令

insertOne 方法插入一條數(shù)據(jù)

insertMany() 方法插入多條數(shù)據(jù)

這兩個(gè)方法就是對(duì)于insert方法的拆分,讓使用更具有寓意化

示例

// 注意insertOne 方法只能插入一條數(shù)據(jù),所以不能插入數(shù)組集合,會(huì)報(bào)錯(cuò)
db.student.insertOne({name:"小明",age:18})

// insertMany 方法插入的是多條數(shù)據(jù)的集合,就算只插入一條數(shù)據(jù)也必須是一個(gè)數(shù)組
db.student.insertMany([{name:"小明",age:13},{name:"小紅",age:15}])


6.1.2 save 方法

save方法有更新和插入兩種功能,到底是插入還是更新文檔取決于save的參數(shù)。

具體是更新還是新增,取決于_id參數(shù)。如果能根據(jù)_id找到一個(gè)已經(jīng)存在的文檔,那么就更新。如果沒(méi)有傳入_id參數(shù)或者找不到存在的文檔,那么就插入一個(gè)新文檔。

db.student.save({name:"張三",age:10})

這個(gè)命令是新增一條文檔, 插入的數(shù)據(jù)沒(méi)有_id,沒(méi)發(fā)判斷,是否存在,所以就是新增

如果先插入一個(gè)文檔

db.student.insert({_id:"aa",name:'李四',age:22})

注意新增數(shù)據(jù)時(shí),沒(méi)有指定_id,MongoDb客戶端驅(qū)動(dòng)會(huì)自動(dòng)為你生成一個(gè)默認(rèn) _id

_id的值是根據(jù)時(shí)間戳和機(jī)器碼生成的唯一ObjectId 作為文檔的主鍵

現(xiàn)在集合中已經(jīng)存在了_idaa的文檔

此時(shí)在用save方法 傳入一樣的_id這就是在更新數(shù)據(jù)

db.student.save({_id:"aa",name:'李四',age:33})


6.1.3 insert 方法和save 方法不同之處
  1. insert() 方法向集合中插入數(shù)據(jù).若新增數(shù)據(jù)的主鍵已經(jīng)存在,則會(huì)拋 org.springframework.dao.DuplicateKeyException 異常提示主鍵重復(fù),不保存當(dāng)前數(shù)據(jù)。

  2. save() 方法向集合中添加或更新數(shù)據(jù), 若新增數(shù)據(jù)的主鍵已經(jīng)存在,則會(huì)對(duì)當(dāng)前已經(jīng)存在的數(shù)據(jù)進(jìn)行修改操作。不存在則新增數(shù)據(jù)


6.2. 查詢文檔(數(shù)據(jù))

查詢文檔使用find() 方法, 查詢所有符合條件的數(shù)據(jù),find方法可以傳入查詢的參數(shù)

語(yǔ)法:

db.集合名.find()

db.集合名.find({條件對(duì)象})

db.集合名.findOne() 只查詢一條數(shù)據(jù)

db.集合名.find().pretty() 將查詢的數(shù)據(jù)以格式化的結(jié)果顯示出來(lái)

db.collection("xuesheng").find({
  // 要查詢的數(shù)據(jù)
}).toArray(function(err,result){
  // 回調(diào)函數(shù)
})


6.2.1 查詢所有的數(shù)據(jù)

注意find() 方法不傳參數(shù)或者傳入一個(gè)空對(duì)象都表示查詢集合中所有的文檔數(shù)據(jù)

db.student.find()

# OR

db.student.find({})


6.2.2 查詢指定的數(shù)據(jù)

find() 方法中傳入?yún)?shù)為查詢條件對(duì)象, 凡是符合條件的都會(huì)被查詢出來(lái)

示例:

db.student.find({age:18})

student集合中,所有age字段值為18的都會(huì)被查詢出來(lái)

查詢對(duì)象里可以指定多個(gè)字段

db.student.find({name:"張三",age:18})

student集合中,所有name字段值為"張三"并且 age字段值為18的都會(huì)被查詢出來(lái)


6.2.3 查詢符合條件的第一個(gè)數(shù)據(jù)

前面所學(xué)的方法查詢的都是集合,所有符合條件的數(shù)據(jù)都會(huì)被查詢到,如果值只想查詢符合條件的眾多數(shù)據(jù)中的第一個(gè)怎么辦

當(dāng)然是用findOne () 方法啦

db.student.findOne({name:"張三",age:18})

student集合中,只查詢第一個(gè)符合name字段值為"張三"并且 age字段值為18的文檔(數(shù)據(jù))

注意

  1. find 方法返回的是集合,也就是數(shù)組,所以可以加所以獲取第幾條數(shù)據(jù)

    db.student.find({name:"張三",age:18})[1]
    

    獲取符合條件索引為1的數(shù)據(jù)

  2. findOne 方法返回的就是符合條件的單個(gè)的文檔數(shù)據(jù),就是一個(gè)對(duì)象


6.2.4 獲取find 方法查詢數(shù)據(jù)的數(shù)量

既然find 方法查詢到的是一個(gè)集合(數(shù)據(jù)),那么如何獲取查詢內(nèi)容的數(shù)量呢,

使用count方法獲取find查詢數(shù)據(jù)的數(shù)量

 db.student.find({name:"小明",age:13}).count()

返回查詢數(shù)據(jù)的長(zhǎng)度

也可以使用length 方法獲取數(shù)量

 db.student.find({name:"小明",age:13}).length()

返回的結(jié)果和length一樣


6.2.5 在控制臺(tái)優(yōu)雅的輸出數(shù)據(jù)

我們?cè)诳刂婆_(tái)查詢返回的結(jié)果是每一個(gè)文檔一行顯示,如果超出了控制臺(tái)的寬度看起來(lái)就不是很方便

我們可以使用pretty方法,讓每一個(gè)文檔在超出控制臺(tái)后一個(gè)字段一行顯示,這樣查詢出來(lái)的數(shù)據(jù)看起來(lái)非常舒服

db.student.find({name:"小明",age:13}).pretty()


6.3. 修改數(shù)據(jù)

修改數(shù)據(jù)的前提是你要知道修改書(shū),所以修改的方法傳入兩個(gè)參數(shù),第一個(gè)參數(shù)是查詢條件,第二個(gè)參數(shù)為修改內(nèi)容

語(yǔ)法

db.集合名.update({查詢對(duì)象},{修改內(nèi)容},{配置選項(xiàng)}),

db.集合名.updateMany({查詢對(duì)象},{修改內(nèi)容}))

db.集合名.updateOne({查詢對(duì)象},{修改內(nèi)容}))

主鍵不能修改(除了id整體替換)


6.3.1 整體替換

在使用update 方法更新數(shù)據(jù)是,注意,在第一個(gè)參數(shù)查詢成功后,會(huì)有第二個(gè)參數(shù)對(duì)象,直接替換原來(lái)字段中除了_id主鍵外的其他所有字段

db.student.update({name:"小明"},{age:20})

此時(shí)查詢成功的數(shù)據(jù)將會(huì)被第二個(gè)對(duì)象所替代, 在通過(guò)find查詢是, 文檔里面只剩下了age一個(gè)字段

那么如果只想修改制定字段的內(nèi)容,其他字段不動(dòng),可以將其他字段都羅列到第二個(gè)參數(shù)對(duì)象, 很顯然這種操作很不方便

我們也可以使用修改操作符來(lái)完成制定字段的 修改


6.3.2 修改制定字段的內(nèi)容

修改制定字段內(nèi)容的修飾操作符為$set屬性.

db.student.update({name:"小明"},{$set:{age:20}})

這是,字段name值為小明成功的數(shù)據(jù)只會(huì)更新age字段值為20,其他的字段都不變


6.3.3 刪除指定字段的修飾屬性

$set 是修改制定字段的修飾屬性

$unset是刪除指定字段的修飾屬性

 db.student.update({name:"小明"},{$unset:{age:20}})

這個(gè)使用查詢到的文檔中age字段就會(huì)被刪除

通過(guò)測(cè)試我們知道,update方法只能修改符合條件的第一個(gè)數(shù)據(jù),其他的不會(huì)被修改


6.3.4 修改所有符合條件的數(shù)據(jù)

有兩種方法,

  1. 還是只用update方法,但是指定多文件修改的配置
  2. 使用updateMany 方法修改所有符合條件的數(shù)據(jù)

使用update方法

更新所有查詢到的數(shù)據(jù)

 db.student.update({name:"小紅"},{$set:{age:20}},{multi:true})

這樣所有數(shù)據(jù)符合字段name值為小紅的數(shù)據(jù),age字段都會(huì)被修改

使用updateMany 方法

db.student.updateMany({name:"小紅"},{$set:{age:20}})


6.3.5 單獨(dú)修改一個(gè)數(shù)據(jù)的方法

單獨(dú)修改一個(gè)數(shù)據(jù)的方法為 updateOne

db.student.updateOne({name:"小紅"},{$set:{age:24}})

只有第一個(gè)符合條件數(shù)據(jù)的age字段會(huì)被修改

總結(jié),

所以我們會(huì)發(fā)現(xiàn)

updateMany 方法和 updateOne 方法是 update方法拆分


6.4. 刪除文檔(數(shù)據(jù))

語(yǔ)法

db.集合名.remove({}) 刪除當(dāng)前集合中的所有數(shù)據(jù)

db.集合名.remove({條件對(duì)象}) 刪除符合條件的所有數(shù)據(jù)

db.集合名.deleteOne() 刪除符合條件的第一個(gè)數(shù)據(jù)

db.集合名.deleteMany() 刪除符合條件的所有數(shù)據(jù)


6.4.1 remove() 方法 刪除符合條件的所有數(shù)據(jù)

remove 方法傳參和find 方放傳參一樣, 但是remove方法不允許不傳參,會(huì)報(bào)錯(cuò)

 db.student.remove({name:"小明"})

所有數(shù)據(jù)中name字段為小明的數(shù)據(jù)都會(huì)被刪除


6.4.2 remove() 方法 刪除符合條件的第一條數(shù)據(jù)

remove 方法可以接受第二個(gè)參數(shù), 參數(shù)為布爾值, 為true就是刪除一條數(shù)據(jù)

db.student.remove({name:"小紅"},true)

只會(huì)刪除數(shù)據(jù)中字段name值為小紅的第一條數(shù)據(jù)

同時(shí)刪除也有拆分的兩個(gè)方法


6.4.3 deleteOne 方法 刪除一條數(shù)據(jù)
db.student.deleteOne({"age":20})


6.4.4 deleteMany() 方法 刪除所有符合條件的數(shù)據(jù)
db.student.deleteMany({"name":"小紅"})


6.4.5 remove () 方法清空集合

remove 方法傳入一個(gè)空對(duì)象,就是清空這個(gè)集合, 刪除所有數(shù)據(jù)

db.student.remove({})

但是這種刪除新能非常不好, 因?yàn)檫@種刪除方式是一條一條數(shù)據(jù)刪除的,

如果你有需求需要?jiǎng)h除字段中所有的數(shù)據(jù), 可以直接通過(guò)drap方法,刪除整個(gè)集合

db.student.drop()

一般數(shù)據(jù)庫(kù)中的數(shù)據(jù)都不會(huì)真正被刪除, 所以刪除的方法基本沒(méi)用

通常會(huì)在數(shù)據(jù)中添加一個(gè)字段來(lái)表示數(shù)據(jù)是否被刪除

注意: 由于刪除和更新操作會(huì)對(duì)數(shù)據(jù)造成極大的影響,所以一定要謹(jǐn)慎.


7. 其他數(shù)據(jù)庫(kù)操作

7.1 導(dǎo)入數(shù)據(jù)
$ mongoimport -d students -c student "C:\Windows 7 Documents\Desktop\1.txt"

將1.txt中的 數(shù)據(jù)導(dǎo)入到數(shù)據(jù)庫(kù)students的student

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容