以前學過的有mysql數據庫,如今咱們學習一種非關係型數據庫html
MongoDB是一款強大、靈活、且易於擴展的通用型數據庫python
MongoDB 是由C++語言編寫的,是一個基於分佈式文件存儲的開源數據庫系統。mysql
在高負載的狀況下,添加更多的節點,能夠保證服務器性能。正則表達式
MongoDB 旨在爲WEB應用提供可擴展的高性能數據存儲解決方案。redis
MongoDB 將數據存儲爲一個文檔,數據結構由鍵值(key=>value)對組成。MongoDB 文檔相似於 JSON 對象。字段值能夠包含其餘文檔,數組及文檔數組。sql
一、易用性mongodb
MongoDB是由C++編寫的,是一個基於分佈式文件存儲的開源數據庫系統,它不是關係型數據庫。在高負載的狀況下,添加更多的節點,能夠保證服務器的性能。數據庫
MongoDB是一個面向文檔(document-oriented)的數據庫,而不是關係型數據庫。 不採用關係型主要是爲了得到更好得擴展性。固然還有一些其餘好處,與關係數據庫相比,面向文檔的數據庫再也不有「行「(row)
的概念取而代之的是更爲靈活的「文檔」(document)模型。經過在文檔中嵌入文檔和數組,面向文檔的方法可以僅使用一條記錄
來表現複雜的層級關係,這與現代的面嚮對象語言的開發者對數據的見解一致。
另外,再也不有預約義模式(predefined schema):文檔的鍵(key)和值(value)再也不是固定的類型和大小
。因爲沒有固定的模式,根據須要添加或刪除字段變得更容易了。一般因爲開發者可以進行快速迭代,因此開發進程得以加快。
並且,實驗更容易進行。開發者能嘗試大量的數據模型,從中選一個最好的。
卓越的性能編程
MongoDB的一個主要目標是提供卓越的性能,這很大程度上決定了MongoDB的設計。MongoDB把儘量多的內存用做緩存cache,
視圖爲每次查詢自動選擇正確的索引。 總之各方面的設計都旨在保持它的高性能 雖然MongoDB很是強大並試圖保留關係型數據庫的不少特性,但它並不追求具有關係型數據庫的全部功能。
只要有可能,數據庫服務器就會將處理邏輯交給客戶端
。這種精簡方式的設計是MongoDB可以實現如此高性能的緣由之一
2、MongoDB基礎知識json
一、文檔是MongoDB的核心概念。文檔就是鍵值對的一個有序集{'msg':'hello','foo':3}。相似於python中的有序字典
須要注意的是: #一、文檔中的鍵/值對是有序的。 #二、文檔中的值不只能夠是在雙引號裏面的字符串,還能夠是其餘幾種數據類型(甚至能夠是整個嵌入的文檔)。 #三、MongoDB區分類型和大小寫。 #四、MongoDB的文檔不能有重複的鍵。 #五、文檔中的值能夠是多種不一樣的數據類型,也能夠是一個完整的內嵌文檔。文檔的鍵是字符串。除了少數例外狀況,鍵可使用任意UTF-8字符。 文檔鍵命名規範: #一、鍵不能含有\0 (空字符)。這個字符用來表示鍵的結尾。 #二、.和$有特別的意義,只有在特定環境下才能使用。 #三、如下劃線"_"開頭的鍵是保留的(不是嚴格要求的)。
二、集合就是一組文檔。若是將MongoDB中的一個文檔比喻爲關係型數據的一行,那麼一個集合就是至關於一張表
#一、集合存在於數據庫中,一般狀況下爲了方便管理,不一樣格式和類型的數據應該插入到不一樣的集合,但其實集合沒有固定的結構,
這意味着咱們徹底能夠把不一樣格式和類型的數據通通插入一個集合中。 #二、組織子集合的方式就是使用「.」,分隔不一樣命名空間的子集合。 好比一個具備博客功能的應用可能包含兩個集合,分別是blog.posts和blog.authors,這是爲了使組織結構更清晰,
這裏的blog集合(這個集合甚至不須要存在)跟它的兩個子集合沒有任何關係。 在MongoDB中,使用子集合來組織數據很是高效,值得推薦 #三、當第一個文檔插入時,集合就會被建立。合法的集合名: 集合名不能是空字符串""。 集合名不能含有\0字符(空字符),這個字符表示集合名的結尾。 集合名不能以"system."開頭,這是爲系統集合保留的前綴。 用戶建立的集合名字不能含有保留字符。有些驅動程序的確支持在集合名裏面包含,這是由於某些系統生成的集合中包含該字符。
除非你要訪問這種系統建立的集合,不然千萬不要在名字裏出現$。
三、數據庫:在MongoDB中,多個文檔組成集合,多個集合能夠組成數據庫
數據庫也經過名字來標識。數據庫名能夠是知足如下條件的任意UTF-8字符串: #一、不能是空字符串("")。 #二、不得含有' '(空格)、.、$、/、\和\0 (空字符)。 #三、應所有小寫。 #四、最多64字節。 有一些數據庫名是保留的,能夠直接訪問這些有特殊做用的數據庫。 #一、admin: 從身份認證的角度講,這是「root」數據庫,若是將一個用戶添加到admin數據庫,這個用戶將自動得到全部數據庫的權限。再者,一些特定的服務器端命令也只能從admin數據庫運行,如列出全部數據庫或關閉服務器 #二、local: 這個數據庫永遠都不能夠複製,且一臺服務器上的全部本地集合均可以存儲在這個數據庫中 #三、config: MongoDB用於分片設置時,分片信息會存儲在config數據庫
四、強調:把數據庫名添加到集合名前,獲得集合的徹底限定名,即命名空間
例如: 若是要使用cms數據庫中的blog.posts集合,這個集合的命名空間就是 cms.blog.posts。命名空間的長度不得超過121個字節,且在實際使用中應該小於100個字節
基於BSON結構 string 字符串,Utf8 integer 整型 double 雙精度,包含float,MongoDB中不存在Float Null 空數據類型 Date 時間類型 ISODate(2018-9-12 10:45:58) Timestamp 時間戳類型 ISODate("123123") ObjectId 對象ID Documents 自生成的 _id ObjectId("5b98794ec34b9812bcabdde7") #"5b151f85" 代指的是時間戳,這條數據的產生時間 #"364098" 代指某臺機器的機器碼,存儲這條數據時的機器編號 #"09ab" 代指進程ID,多進程存儲數據的時候,很是有用的 #"2e6b26" 代指計數器,這裏要注意的是,計數器的數字可能會出現重複,不是惟一的 #以上四種標識符拼湊成世界上惟一的ObjectID #只要是支持MongoDB的語言,都會有一個或多個方法,對ObjectID進行轉換 #能夠獲得以上四種信息
(此處說的是windows的)
下載好mongoDB以後,選擇文件夾安裝 ,而後配置環境變量,就是把你的環境變量配置到電腦上,而後你須要再創建一個文件夾用來存放mpongodb的數據庫
安裝目錄: D:\MongoDB 而後找到bin目錄加入到電腦的環境變量種 而後再建立一個目錄用來存放你的數據庫 D:\MongoDB\data\db 目錄一半都是建立data\db 而後這個時候用你的管理員的身份來運行cmd而後切換到你的 新創建的存放數據庫的文件夾下: D:\MongoDB\data\db 而後執行 mongod --dbpath +你的文件夾路徑 mongod --dbpath D:\MongoDB\data\db 就把你的數據庫鏈接打開了 而後你就能夠經過其餘鏈接 進行與你的mongodb數據庫鏈接了(切忌:上一次的和數據庫的連接不能夠斷開 就是選定的連接文件夾和數據庫相鏈接)
選好安裝目錄 | D:\MongoDB |
選擇數據庫存放目錄 | D:\MongoDB\data\db |
以管理員身份運行 | mongod --dbpath D:\MongoDB\data\db
|
而後再次打開新的鏈接 | 上次的連接不能夠斷開 須要再次打開新的連接進行數據庫訪問 |
二、帳號管理
#帳號管理:https://docs.mongodb.com/master/tutorial/enable-authentication/ #一、建立有權限的用戶
use admin
db.createUser(
{
user: "root", #這個root能夠隨便寫
pwd: "123",
roles: [ { role: "root", db: "admin" } ] #權限,role是root說明是管理員,
}
)
use test
db.createUser(
{
user: "egon",
pwd: "123",
roles: [ { role: "readWrite", db: "test" }, #針對test庫有讀寫權限,操做本身的庫有讀寫權限
{ role: "read", db: "db1" } ] #針對db1庫讀權限,操做其餘庫有讀權限
}
)
#二、重啓數據庫 mongod --remove mongod --config "C:\mongodb\mongod.cfg" --bind_ip 0.0.0.0 --install --auth
或者
mongod --bind_ip 0.0.0.0 --port 27017 --logpath D:\MongoDB\log\mongod.log --logappend --dbpath
D:\MongoDB\data\db --serviceName "MongoDB" --serviceDisplayName "MongoDB" --install --auth
#三、登陸:注意使用雙引號而非單引號 mongo --port 27017 -u "root" -p "123" --authenticationDatabase "admin" 也能夠在登陸以後用db.auth("帳號","密碼")登陸 mongo use admin db.auth("root","123") #推薦博客:https://www.cnblogs.com/zhoujinyi/p/4610050.html 建立帳號密碼+開啓認證機制
數據庫的鏈接工具:
簡單操做:
以上是一個簡單的鏈接工具,就是先鏈接本機的數據庫 也能夠選擇鏈接其餘ip地址的數據庫(僅僅限於mongoDB數據庫)
在mongodb種數據庫仍是數據庫的含義,可是表的定義沒有了,叫集合(其實仍是表)
基本數據類型
一、在概念上,MongoDB的文檔與Javascript的對象相近,於是能夠認爲它相似於JSON。JSON(http://www.json.org)是一種簡單的數據表示方式:其規範僅用一段文字就能描述清楚(其官網證實了這點),且僅包含六種數據類型。
二、這樣有不少好處:易於理解、易於解析、易於記憶。然而從另外一方面說,由於只有null、布爾、數字、字符串、數字和對象這幾種數據類型,因此JSON的表達能力有必定的侷限。
三、雖然JSON具有的這些類型已經具備很強的表現力,但絕大數應用(尤爲是在於數據庫打交道時)都還須要其餘一些重要的類型。例如,JSON沒有日期類型,這使得本來容易日期處理變得煩人。另外,JSON只有一種數字類型,沒法區分浮點數和整數,更別區分32位和64位了。再者JSON沒法表示其餘一些通用類型,如正則表達式或函數。
四、MongoDB在保留了JSON基本鍵/值對特性的基礎上,添加了其餘一些數據類型。在不一樣的編程語言下,這些類型的確切表示有些許差別。下面說明了MongoDB支持的其餘通用類型,以及如何正在文檔中使用它們
五、數據類型
1 #一、null:用於表示空或不存在的字段 2 d={'x':null} 3 #二、布爾型:true和false 4 d={'x':true,'y':false} 5 #三、數值 6 d={'x':3,'y':3.1415926} 7 #四、字符串 8 d={'x':'egon'} 9 #五、日期 10 d={'x':new Date()} 11 d.x.getHours() 12 #六、正則表達式 13 d={'pattern':/^egon.*?nb$/i} 14 15 正則寫在//內,後面的i表明: 16 i 忽略大小寫 17 m 多行匹配模式 18 x 忽略非轉義的空白字符 19 s 單行匹配模式 20 21 #七、數組 22 d={'x':[1,'a','v']} 23 24 #八、內嵌文檔 25 user={'name':'egon','addr':{'country':'China','city':'YT'}} 26 user.addr.country 27 28 #九、對象id:是一個12字節的ID,是文檔的惟一標識,不可變 29 d={'x':ObjectId()}
六、_id和ObjectId
1 MongoDB中存儲的文檔必須有一個"_id"鍵。這個鍵的值能夠是任意類型,默認是個ObjectId對象。 2 在一個集合裏,每一個文檔都有惟一的「_id」,確保集合裏每一個文檔都能被惟一標識。 3 不一樣集合"_id"的值能夠重複,但同一集合內"_id"的值必須惟一 4 5 #一、ObjectId 6 ObjectId是"_id"的默認類型。由於設計MongoDb的初衷就是用做分佈式數據庫,因此可以在分片環境中生成 7 惟一的標識符很是重要,而常規的作法:在多個服務器上同步自動增長主鍵既費時又費力,這就是MongoDB採用 8 ObjectId的緣由。 9 ObjectId採用12字節的存儲空間,是一個由24個十六進制數字組成的字符串 10 0|1|2|3| 4|5|6| 7|8 9|10|11 11 時間戳 機器 PID 計數器 12 若是快速建立多個ObjectId,會發現每次只有最後幾位有變化。另外,中間的幾位數字也會變化(要是在建立過程當中停頓幾秒)。 13 這是ObjectId的建立方式致使的,如上圖 14 15 時間戳單位爲秒,與隨後5個字節組合起來,提供了秒級的惟一性。這個4個字節隱藏了文檔的建立時間,絕大多數驅動程序都會提供 16 一個方法,用於從ObjectId中獲取這些信息。 17 18 由於使用的是當前時間,不少用戶擔憂要對服務器進行時鐘同步。其實不必,由於時間戳的實際值並不重要,只要它老是不停增長就好。 19 接下來3個字節是所在主機的惟一標識符。一般是機器主機名的散列值。這樣就能夠保證不一樣主機生成不一樣的ObjectId,不產生衝突 20 21 接下來連個字節確保了在同一臺機器上併發的多個進程產生的ObjectId是惟一的 22 23 前9個字節確保了同一秒鐘不一樣機器不一樣進程產生的ObjectId是惟一的。最後3個字節是一個自動增長的 計數器。確保相同進程的同一秒產生的 24 ObjectId也是不同的。 25 26 #二、自動生成_id 27 若是插入文檔時沒有"_id"鍵,系統會自幫你建立 一個。能夠由MongoDb服務器來作這件事。 28 但一般會在客戶端由驅動程序完成。這一作法很是好地體現了MongoDb的哲學:能交給客戶端驅動程序來作的事情就不要交給服務器來作。 29 這種理念背後的緣由是:即使是像MongoDB這樣擴展性很是好的數據庫,擴展應用層也要比擴展數據庫層容易的多。將工做交給客戶端作就 30 減輕了數據庫擴展的負擔。
增刪改查:
增: - db.user.info #user.info表 - db.user #user表 - db.user.auth ##user.auth表 當第一個文檔插入時,集合就會被建立 > use database1 switched to db database1 > db.table1.insert({'a':1}) WriteResult({ "nInserted" : 1 }) > db.table2.insert({'b':2}) WriteResult({ "nInserted" : 1 }) 查: - show collections - show tables #這兩個是同樣的 #只要是空不顯示 刪: - db.user.info.help() #查看幫助 - db.user.info.drop()
一、數據庫的增:
增長數據庫: use +數據庫名 # 有則切換無則新增 當你用use 建立完以後,你須要在insert以後才能顯示出這個數據庫 db.建立的數據庫名.insertOne() eg: db.db.insertOne() 而後就會顯示出你所建立的數據庫 或者你直接使用db.建立的數據庫名.insertOne()而後也能夠直接建立出數據庫
mongodb數據庫的操做不論事增、刪、改、查 都是須要用到db.你的數據的名而後再加上要操做的內容
你使用use建立的只是數據庫 而當你插入第一條數據的時候你的集合就會被建立
建立數據庫 | use+數據庫名 | 有則切換 無則建立 |
查看服務器中的全部的數據庫 | show dbs | |
db | 查看當前所在的數據庫 | |
show tables | 查看當前數據庫的中的集合 |
增長 | db.test.insert({"name":"老王"}) | 這個是對你的數據中插入一個集合爲test的數據 |
多行增長 | db.test.insert([{"name":"隔壁老王"},{"hobby":"找人"}]) | 對你的數據庫中的test集合插入兩條數據 |
單行增長 | db.db.inertOne({"name":"隔壁老王"}) | 爲你的數據中插入一個集合爲db的數據 |
多行插入 | d.db.insertMany([{"name":"隔壁老王"},{"name":"你媳婦"}]) | 爲你的數據庫中插入一個集合 db,db集合中有兩條數據 |
增:
#一、沒有指定_id則默認ObjectId,_id不能重複,且在插入後不可變 2 3 #二、插入單條 4 user0={ 5 "name":"egon", 6 "age":10, 7 'hobbies':['music','read','dancing'], 8 'addr':{ 9 'country':'China', 10 'city':'BJ' 11 } 12 } 13 14 db.test.insert(user0) 15 db.test.find() 16 17 #三、插入多條 18 user1={ 19 "_id":1, 20 "name":"alex", 21 "age":10, 22 'hobbies':['music','read','dancing'], 23 'addr':{ 24 'country':'China', 25 'city':'weifang' 26 } 27 } 28 29 user2={ 30 "_id":2, 31 "name":"wupeiqi", 32 "age":20, 33 'hobbies':['music','read','run'], 34 'addr':{ 35 'country':'China', 36 'city':'hebei' 37 } 38 } 39 40 41 user3={ 42 "_id":3, 43 "name":"yuanhao", 44 "age":30, 45 'hobbies':['music','drink'], 46 'addr':{ 47 'country':'China', 48 'city':'heibei' 49 } 50 } 51 52 user4={ 53 "_id":4, 54 "name":"jingliyang", 55 "age":40, 56 'hobbies':['music','read','dancing','tea'], 57 'addr':{ 58 'country':'China', 59 'city':'BJ' 60 } 61 } 62 63 user5={ 64 "_id":5, 65 "name":"jinxin", 66 "age":50, 67 'hobbies':['music','read',], 68 'addr':{ 69 'country':'China', 70 'city':'henan' 71 } 72 } 73 db.user.insertMany([user1,user2,user3,user4,user5])
刪:db.dropDatabase() #
db.user.drop() #刪除user集合
db.user.remove({})
// remove 方式 被官方不推薦了
db.user.deleteOne({"name":"白虎"})
db.user.deleteMany({"name":"翠花兒"})
1 #一、刪除多箇中的第一個 2 db.user.deleteOne({ 'age': 8 }) 3 4 #二、刪除國家爲China的所有 這個是刪除你的全部的知足條件的 5 db.user.deleteMany( {'addr.country': 'China'} ) 6 7 #三、刪除所有 8 db.user.deleteMany({})
可視化工具
db.+集合名.find() #查看這個集合內部的全部內容 db.test.find() #查看test集合中的全部內容 根據條件查找 db.test.find(條件) db.test.find("name":"老王") #查找test集合中的name是老王的信息 findOne() 查找單行 db.one.findOne({"name":"老王",age:1}) 逗號表明and
數字比較符:
$lt |
小於 |
$gt |
大於 |
$lte |
小於等於 |
$gte |
大於等於 |
$and | 和 |
$or | 或者 |
$not | 不是 |
$mod | 取模運算 |
$gt 大於 db.test.findOne({"id":{$gt:1}}) 求集合test中id大於1的信息
$lt 小於
db.test.findOne({"id":{$lt:5}}) 集合test中id小於5的信息
$lte小於等於
db.test.findOne({"id":{$lte:3}}) 集合test中id小於等於5的信息
$gte 大於等於
db.user.find({ "_id":{"$gte":3,"$lte":4}, "age":{"$gte":40} #結束就不要加逗號了 })
$and # 並列查詢 以逗號分隔
db.user.find({"$and":[ {"_id":{"$gte":3,"$lte":4}}, #一個字典就是一個條件 {"age":{"$gte":40}} ]}
select * from db1.user where id >=0 and id <=1 or id >=4 or name = "yuanhao"; db.user.find({"$or":[ {"_id":{"$lte":1,"$gte":0}}, {"_id":{"$gte":4}}, {"name":"yuanhao"} ]})
select * from db1.user where id % 2 = 1; #奇數 db.user.find({"_id":{"$mod":[2,1]}}) #取模運算,id對2取模 #取反,偶數 db.user.find({ "_id":{"$not":{"$mod":[2,1]}} })
$in | 在裏面 |
$nin | 不在 |
# SQL:in,not in 2 # MongoDB:"$in","$nin" 3 4 #一、select * from db1.user where age in (20,30,31); 5 db.user.find({"age":{"$in":[20,30,31]}}) 6 7 #二、select * from db1.user where name not in ('huahua','xxx'); 8 db.user.find({"name":{"$nin":['hauhua','xxx']}})
$in | 在什麼裏面 |
$or | 或者 |
$all | 必需要包含全部的 |
$in: db.user.find({age:{$in:[1,2,3]}}) 字段符合in,array中的數值 $or: db.user.find({$or:[{age:{$in:[1,2,3,4]}},{name:666}]}) $all: db.user.find({test:{$all:[1,2]}}) array元素相同便可 或 包含全部$all中的元素
改:update
1 update() 方法用於更新已存在的文檔。語法格式以下: 2 db.collection.update( 3 <query>, 4 <update>, 5 { 6 upsert: <boolean>, 7 multi: <boolean>, 8 writeConcern: <document> 9 } 10 ) 11 參數說明:對比update db1.t1 set name='EGON',sex='Male' where name='egon' and age=18; 12 13 query : 至關於where條件。 14 update : update的對象和一些更新的操做符(如$,$inc...等,至關於set後面的 15 upsert : 可選,默認爲false,表明若是不存在update的記錄不更新也不插入,設置爲true表明插入。 16 multi : 可選,默認爲false,表明只更新找到的第一條記錄,設爲true,表明更新找到的所有記錄。 17 writeConcern :可選,拋出異常的級別。 18 19 更新操做是不可分割的:若兩個更新同時發送,先到達服務器的先執行,而後執行另一個,不會破壞文檔。
$set : 將某個key的value 修改成 某值 $unset: 刪除字段 {$unset: {test: "" }} $inc:{$inc:{"age":100}} 原有值基礎上增長 xxx array: $push : 向數組Array最後位置插入一條元素 {$push:{"hobby":1234}} [].append(1234) $pull : 刪除數組中的某一個元素 {$pull:{"hobby":123}} #刪除字典 db.user.updateOne({"_id":ObjectId("5b98794ec34b9812bcabdde7"),"hobby.age":18},{$unset:{"hobby.$":1}}) $pop : 刪除數組的第一個或最後一個 最後一個:{$pop:{"hobby":1}} 第一個:{$pop:{"hobby":-1}} $ :代指符合條件的某數據 array.$ : db.user.updateOne({"_id":ObjectId("5b98794ec34b9812bcabdde7"),"hobby.name":"翠花兒"},{$set:{"hobby.$.name":"農婦山泉"}})
後面條件的$帶表指的是前面的條件 就是告訴你要修改的是前面的條件
update修改:
updateOne 修改單條
db.test.updateOne({"name":"隔壁小姑娘"},{"name":"操場小妹妹"})
updateMany #修改多條數據
$set | 講某個key的value修改成某值 |
$unset | 刪除字段 {$unset: {test: "" }} |
$inc | 在原值上增長 |
$push | 向數組Array最後位置插入一條元素 |
$pull | 刪除數組中的某一個元素 |
$pop | 刪除數組的第一個或最後一個 |
$ | 單獨使用代指的是你的條件 |
db.test.update({"name":"操場小妹妹"},{"$set":{"name":"屬於你的妹子"}}) 修改
修改單挑數據
db.user.updateOne({"name":"子龍"},{$set:{"name":"趙子龍"}})
修改多條數據
db.user.updateMany({"name":"小青龍"},{$set:{"name":"白虎"}})
排序 跳過 顯示條目 sort 排序 find().sort(id:-1/1) 1 升序 2 降序 desc skip 跳過 find().skip(2) 從三條開始返回 limit 顯示條目 find().limit(2)只顯示前兩條 混搭: db.user.find({}).sort({age:-1 }).skip(1).limit(2) 根據age字段進行降序排列,而且跳過第一條,從第二條開始返回,兩條數據
res = mongo_db.user.find_one({"_id":ObjectId("5b98794ec34b9812bcabdde7")}) 查找單條的數據 res = mongo_db.content.insert_one({"name":"123"}) 插入單條 res = mongo_db.content.update_one({"name":"123"},{"$set":{"name":"666"}}) 修改單條 修改多條 res = mongo_db.content.update_many({"name":"666"},{"$set":{"name":"123"}})
首先要先安裝pymongo 模塊
pip3 install pymongo
python和mongodb數據庫鏈接
.MongoDB的默認端口號:27017 (redis:6379 MySql:3306)
mclient = pymongo.MongoClient(host="127.0.0.1", port=27017) #端口號和地址 mongo_db = mclient[數據庫]
========
client=MongoClient('mongodb://root:123@localhost:27017') table=client['db1']['emp']