本學習筆記是來源於學習B站上的尚硅谷和黑馬的MongoDB教學視頻而做的知識總結。
一、數據庫(Database)
數據庫是按照數據結構來組織、存在和管理數據的倉庫。說白了,數據庫就是存在數據的倉庫。
二、數據庫分類
主要分爲兩種:
(1)關係型數據庫
MySQL、Oracle、DB2、SQL Server。。。
關係型數據庫中全都是表
(2)非關係型數據庫(No SQL=Not Only SQL)
MongoDB、Redis。。。
鍵值對數據庫
文檔數據庫MongoDB
三、MongoDB簡單介紹
1、MongoDB是什麼
MongoDB的數據模型是面向文檔的,所謂文檔是一種類似於JSON的結構,簡單理解MongoDB這個數據庫中存的是各種各樣的JSON(BSON,Binary JSON,也就是二進制JSON)。
2、MongoDB中的三個概念
(1)數據庫(database)
數據庫是一個倉庫,在倉庫中可以存放集合。
(2)集合(collection)
集合類似於數組,在集合中可以存放文檔。集合就是一組文檔,可以是各種各樣的,沒有格式要求。
(3)文檔(document)
文檔是數據庫中的最小單位,我們可以存儲和操作都內容都是文檔。類似於JS中的對象,在MongoDB中每一條記錄都是一個文檔。
總結起來就是,多個文檔組成集合,多個集合組成數據庫。
注意,在MongoDB中,數據庫和集合都不需要手動創建,當我們創建文檔時,如果文檔所在的集合或數據庫不存在會自動創建數據庫和集合。
四、MongoDB的安裝
1、MongoDB的安裝
我們在Linux上安裝MongoDB,在官網上下載相關安裝包即可。
執行命令啓動服務:/usr/bin/mongod --config /etc/mongodb.conf
在mongodb.conf配置文件中指定數據的存儲路徑:dbpath=/var/lib/mongodb
日誌目錄:logpath=/var/log/mongodb/mongodb.log
注意,版本的選擇:
MongoDB的版本命名規範如:x.y.z;
y爲奇數時表示當前版本爲開發版,如:1.5.2、4.1.13;
y爲偶數時表示當前版本爲穩定版,如:1.6.3、4.0.10;
z是修正版本號,數字越大越好。
注意,MongoDB的配置文件參考:
https://docs.mongodb.com/manual/reference/configuration-options/
https://docs.mongodb.com/manual/reference/parameters/
2、MongoDB客戶端工具
推薦使用幾個MongoDB客戶端工具,圖像化界面,容易使用
(1)MongoDB Compass
地址:https://www.mongodb.com/download-center/v2/compass?initial=true
(2)NoSQL Manager for MongoDB
(3)RoboMongo
3、停止關閉服務
有兩種方式,分別爲快速關閉和標準關閉
(1)快速關閉,即通過kill命令直接殺死mongod 進程,但是數據可能會出錯。
如果數據損壞了,可以通過如下操作來恢復數據:
第一、刪除lock文件:rm -f /數據存儲目錄/*.lock
第二、修復數據:/usr/bin/mongod --repair --dbpath=/數據存儲目錄/
(2)標準關閉方法(數據不容易出錯,但麻煩),也就是通過MongoDB客戶端中的shutdownServer命令來關閉服務,如下:
//#切換到admin庫
use admin
//關閉服務
db.shutdownServer()
五、MongoDB的基本操作
1、基本指令
顯示當前的所有數據庫: show dbs / show databases
進入到指定的數據庫中:use 數據庫名
顯示當前所處的數據庫名稱:db
顯示數據庫中所有的集合:show collections
創建一個新的集合:db.createCollection()
刪除集合:db.collection.drop()
2、基本CRUD增刪改查指令
(0)查詢文檔
db.collection.find()
- 可以根據指定條件從集合中查詢所有符合條件的文檔
- 返回的是一個數組
db.collection.findOne()
- 查詢第一個符合條件的文檔
- 返回的是一個對象
db.collection.find().count()
- 查詢符合條件的文檔的數量
(1)插入文檔
db.<collection>.insert(doc)
- 向集合中插入一個文檔
- 例子:向test數據庫中的,stus集合中插入一個新的學生對象
{name:"孫悟空",age:18,gender:"男"}
db.stus.insert({name:"孫悟空",age:18,gender:"男"})
db.collection.insertOne()
- 向集合中插入一個文檔
db.collection.insertMany()
- 向集合中插入多個文檔
(2)修改數據庫中的文檔
db.collection.update()
- 可以修改、替換集合中的一個或多個文檔
db.collection.updateOne()
- 修改集合中的一個文檔
db.collection.updateMany()
- 修改集合中的多個文檔
db.collection.replaceOne()
- 替換集合中的一個文檔
(3)刪除集合中的文檔
db.collection.remove()
- 刪除集合中的一個或多個文檔(默認刪除多個)
db.collection.deleteOne()
- 刪除集合中的一個文檔
db.collection.deleteMany()
- 刪除集合中的多個文檔
- 清空一個集合
db.collection.remove({})
- 刪除一個集合
db.collection.drop()
- 刪除一個集合
db.dropDatabase()
- 刪除一個數據庫
3、複雜一點的操作命令
(1)投影查詢
如果要查詢結果返回部分字段,則需要使用投影查詢(不顯示所有字段,只顯示指定的字段)。
(2)覆蓋修改、局部修改、批量修改、列值增長的修改
(3)統計查詢、分頁列表查詢、排序查詢
(4)更多查詢-正則表達式查詢、比較查詢、包含查詢、條件連接查詢。
4、常用命令總結:
選擇切換數據庫:use articledb
插入數據:db.comment.insert({bson數據})
查詢所有數據:db.comment.find();
條件查詢數據:db.comment.find({條件})
查詢符合條件的第一條記錄:db.comment.findOne({條件})
查詢符合條件的前幾條記錄:db.comment.find({條件}).limit(條數)
查詢符合條件的跳過的記錄:db.comment.find({條件}).skip(條數)
修改數據:db.comment.update({條件},{修改後的數據}) 或db.comment.update({條件},{$set:{要修改部分的字段:數據})
修改數據並自增某字段值:db.comment.update({條件},{$inc:{自增的字段:步進值}})
刪除數據:db.comment.remove({條件})
統計查詢:db.comment.count({條件})
模糊查詢:db.comment.find({字段名:/正則表達式/})
條件比較運算:db.comment.find({字段名:{$gt:值}})
包含查詢:db.comment.find({字段名:{$in:[值1,值2]}})或db.comment.find({字段名:{$nin:[值1,值2]}})
條件連接查詢:db.comment.find({$and:[{條件1},{條件2}]})或db.comment.find({$or:[{條件1},{條件2}]})
六、MongoDB的索引
1、索引的類型
(1)單字段索引
MongoDB支持在文檔的單個字段上創建用戶定義的升序/降序索引,稱爲單字段索引(Single Field Index)。
說明,主鍵_id就是單字段索引
(2)複合索引
MongoDB還支持多個字段的用戶定義索引,即複合索引(Compound Index)。
複合索引中列出的字段順序具有重要意義。例如,如果複合索引由{ userid: 1, score: -1 } 組成,則索引首先按userid正序排序,然後在每個userid的值內,再在按score倒序排序。
(3)其他索引
地理空間索引(Geospatial Index)、文本索引(Text Indexes)、哈希索引(Hashed Indexes)。
2、索引的查看、創建和移除
(1)查看索引: db.emp.getIndexes();
(2)創建索引: db.collection.createIndex(keys, options)
(3)刪除索引: db.collection.dropIndex(index)
(4)刪除所有的索引: db.collection.dropIndexes()
3、索引的使用
(1)執行計劃
分析查詢性能(Analyze Query Performance)通常使用執行計劃(解釋計劃、Explain Plan)來查看查詢的情況,如查詢耗費的時間、是否基於索引查詢等。
那麼,通常,我們想知道,建立的索引是否有效,效果如何,都需要通過執行計劃查看。
db.collection.find(query,options).explain(options)
關鍵點看: "stage" : "COLLSCAN", 表示全集合掃描,"IXSCAN" ,基於索引的掃描
(2)涵蓋的查詢
當查詢條件和查詢的投影僅包含索引字段時,MongoDB直接從索引返回結果,而不掃描任何文檔或將文檔帶入內存。 這些覆蓋的查詢可以非常有效。
七、基礎練習
//1.進入my_test數據庫
use my_test
//2.向數據庫的user集合中插入一個文檔
db.user.insert({
username:"sunwukong"
});
//3.查詢user集合中的文檔
db.user.find();
//4.向數據庫的user集合中插入一個文檔
db.user.insert({
username:"zhubajie"
});
//5.查詢數據庫user集合中的文檔
db.user.find();
//6.統計數據庫user集合中的文檔數量
db.user.find().count();
//7.查詢數據庫user集合中username爲sunwukong的文檔
db.user.find({username:"sunwukong"});
//8.向數據庫user集合中的username爲sunwukong的文檔,添加一個address屬性,屬性值爲huaguoshan
db.user.update({username:"sunwukong"}, {$set:{address:"huaguoshan"}});
//9.使用{username:"tangseng"} 替換 username 爲 zhubajie的文檔
//db.user.replaceOne({username:"zhubajie"}, {username:"tangseng"});
db.user.update({username:"zhubajie"}, {$set:{username:"tangseng"}});
//10.刪除username爲sunwukong的文檔的address屬性
db.user.update({username:"sunwukong"}, {$unset:{address:1}});
//11.向username爲sunwukong的文檔中,添加一個hobby:{cities:["beijing","shanghai","shenzhen"] , movies:["sanguo","hero"]}
//在MongoDB的文檔中的屬性值也可以是一個文檔,當一個文檔的屬性值是一個文檔時,稱這個文件爲內嵌文檔
db.user.update({username:"sunwukong"}, {$set:{hobby:{cities:["beijing","shanghai","shenzhen"] , movies:["sanguo","hero"]}}});
//12.向username爲tangseng的文檔中,添加一個hobby:{movies:["A Chinese Odyssey","King of comedy"]}
db.user.update({username:"tangseng"}, {$set:{hobby:{movies:["A Chinese Odyssey","King of comedy"]}}});
//13.查詢喜歡電影hero的文檔
//MongoDB支持直接通過內嵌文檔的屬性進行查詢,如果查詢內嵌文檔可以通過.的形式匹配
//如果要通過內嵌文檔對文檔進行查詢,此時屬性名必須使用引號(單引號、雙引號都可以)
db.user.find({"hobby.movies":"hero"});
//14.向tangseng中添加一個新的電影Interstellar
//$push,用於向數組中添加一個新的元素
//$addToSet向數組中添加有一個新的元素,如果數組中已經有了這個元素,則不會再添加了
//db.user.update({username:"tangseng"}, {$push:{"hobby.movies":"Interstellar"}});
db.user.update({username:"tangseng"}, {$addToSet:{"hobby.movies":"Interstellar"}});
//15.刪除喜歡beijing的用戶
db.user.remove({"hobby.cities":"beijing"});
//16.刪除user集合
//db.user.remove({});
db.user.drop();
show dbs;
//17.向numbers中插入20000條數據
//13.2s
for(var i=1; i<=20000; i++) {
db.numbers.insert({num:i});
}
db.numbers.find();
db.numbers.remove({});
//0.1s
var arr = [];
for(var i=1; i<=20000; i++) {
arr.push({num:i});
}
db.numbers.insert(arr);
//18.查詢numbers中num爲500的文檔
db.numbers.find({num:500});
//19.查詢numbers中num大於5000的文檔
db.numbers.find({num:{$gt:5000}});
db.numbers.find({num:{$eq:5000}});
//20.查詢numbers中num小於30的文檔
db.numbers.find({num:{$lt:30}});
//21.查詢numbers中num大於40小於50的文檔
db.numbers.find({num:{$gt:40, $lt:50}});
//22.查詢numbers中num大於19996的文檔
db.numbers.find({num:{$gt:19996}});
//23.查看numbers集合中的前10條數據
//db.numbers.find({num:{$lte:10}});
//在開發中我們絕對不會進行不帶條件的查詢
db.numbers.find().limit(10).sort({num:1});
//24.查看numbers集合中的第11條到20條數據
//skip(), limilt(), sort()三個放在一起執行的時候,執行的順序是先 sort(), 然後是 skip(),最後是顯示的 limit(),和命令編寫順序無關。
db.numbers.find().limit(10).skip(10).sort({num:1});
//25.查看numbers集合中的第21條到30條數據
db.numbers.find().limit(10).skip(20).sort({num:1});
//26.將dept和emp集合導入到數據庫中
db.dept.find();
db.emp.find();
//27.查詢工資小於2000的員工
db.emp.find({sal:{$lt:2000}});
//28.查詢工資在1000-2000之間的員工
db.emp.find({sal:{$gt:1000, $lt:2000}});
//29.查詢工資小於1000或大於2500的員工
db.emp.find({$or:[{sal:{$lt:1000}}, {sal:{$gt:2500}}]});
//30.查詢財務部的所有員工
var depno = db.dept.find({dname:"財務部"})[0].deptno;
db.emp.find({depno:depno});
//31.查詢銷售部的所有員工
var depno = db.dept.find({dname:"銷售部"})[0].deptno;
db.emp.find({depno:depno});
//32.查詢所有mgr爲7698的所有員工
db.emp.find({mgr:7698});
//33.爲所有薪資低於1000的員工增加工資400元
db.emp.update({sal:{$lte:1000}}, {$inc:{sal:400}}, {multi:true});
db.emp.find({sal:{$lte:1000}});
第一步,基礎篇結束,請看:
尚硅谷+黑馬MongoDB視頻學習筆記(二)