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ù)的分類
-
關(guān)系型數(shù)據(jù)庫(kù)
MySQL, Oracle,DB2, SQL Server....
-
非關(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,
- 第一層意思: 不是SQL(關(guān)系型數(shù)據(jù)庫(kù)),
- 第二層意思, 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è)概念
-
數(shù)據(jù)庫(kù)(database)
數(shù)據(jù)庫(kù)就是一個(gè)倉(cāng)庫(kù),在倉(cāng)庫(kù)里可以存放集合
-
集合( collection)
集合類似于數(shù)組,在集合中可以存放文檔
-
文檔( document)
文檔數(shù)據(jù)庫(kù)中最小的單位,我們存儲(chǔ)和操作的內(nèi)容都是文檔
三個(gè)關(guān)系之間的關(guān)系

一個(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)安裝了


也可以通過(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)境變化

3.3. 創(chuàng)建數(shù)據(jù)庫(kù)存放位置(盡量在非系統(tǒng)盤創(chuàng)建)
- 創(chuàng)建一個(gè)
mongdb文件夾,用來(lái)存儲(chǔ)數(shù)據(jù)和日志 - 在
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ù)
- name:集合的名字
- capped:是否啟用集合限制,如果開(kāi)啟需要制定一個(gè)限制條件,默認(rèn)為不啟用,這個(gè)參數(shù)沒(méi)有實(shí)際意義
- size:限制集合使用空間的大小,默認(rèn)為沒(méi)有限制
- max:集合中最大條數(shù)限制,默認(rèn)為沒(méi)有限制
- autoIndexId:是否使用_id作為索引,默認(rèn)為使用(true或false)
- 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)存在了_id為aa的文檔
此時(shí)在用save方法 傳入一樣的_id這就是在更新數(shù)據(jù)
db.student.save({_id:"aa",name:'李四',age:33})
6.1.3 insert 方法和save 方法不同之處
insert() 方法向集合中插入數(shù)據(jù).若新增數(shù)據(jù)的主鍵已經(jīng)存在,則會(huì)拋 org.springframework.dao.DuplicateKeyException 異常提示主鍵重復(fù),不保存當(dāng)前數(shù)據(jù)。
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ù))
注意
-
find 方法返回的是集合,也就是數(shù)組,所以可以加所以獲取第幾條數(shù)據(jù)
db.student.find({name:"張三",age:18})[1]獲取符合條件索引為1的數(shù)據(jù)
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ù)
有兩種方法,
- 還是只用update方法,但是指定多文件修改的配置
- 使用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