碼農(nóng)寶典:您對MongoDB知多少?
譯文【51CTO.com快譯】NoSQL數(shù)據(jù)存儲讓數(shù)據(jù)管理方式更加靈活,徹底改變了軟件開發(fā)的狀況。MongoDB是知名的NoSQL解決方案之一,這是一種面向文檔的數(shù)據(jù)存儲系統(tǒng)。本文探討MongoDB是什么以及它如何滿足您的應(yīng)用需求。
MongoDB:文檔數(shù)據(jù)存儲系統(tǒng)
關(guān)系數(shù)據(jù)庫將信息存儲在嚴(yán)格監(jiān)管的表和列中。MongoDB是一種文檔存儲系統(tǒng),將信息存儲在集合和文檔中。這里的主要區(qū)別在于集合和文檔是非結(jié)構(gòu)化的,有時稱為無模式。這意味著MongoDB實(shí)例(集合和文檔)的結(jié)構(gòu)不是預(yù)定義的,可靈活適應(yīng)放入其中的任何數(shù)據(jù)。
文檔是一個鍵值集,其行為與JavaScript等代碼中的對象非常相似:它的結(jié)構(gòu)根據(jù)放入其中的數(shù)據(jù)而變化。這使得針對MongoDB等數(shù)據(jù)存儲系統(tǒng)進(jìn)行編程比針對關(guān)系數(shù)據(jù)存儲系統(tǒng)進(jìn)行編程來得更容易、更靈活。簡而言之,應(yīng)用程序代碼和文檔數(shù)據(jù)存儲系統(tǒng)之間的交互感覺更自然。
圖1直觀地顯示了MongoDB數(shù)據(jù)庫、集合和文檔的結(jié)構(gòu)。
圖1. MongoDB文檔存儲系統(tǒng)
這種類型的數(shù)據(jù)建模繼承的靈活性意味著可以在更加按需使用的基礎(chǔ)上處理數(shù)據(jù),從而實(shí)現(xiàn)此處所述的性能優(yōu)勢。
想具體了解這種差異,不妨比較以下兩種實(shí)現(xiàn)相同任務(wù)(創(chuàng)建記錄,然后從應(yīng)用程序添加字段)的方法,先用關(guān)系數(shù)據(jù)庫,之后用MongoDB。
關(guān)系數(shù)據(jù)庫中的步驟:
- # create a database:
- CREATE DATABASE menagerie;
- # create a table in the database:
- USE menagerie; CREATE TABLE pet (name VARCHAR(20));
- # connect to the database in app and issue insert:
- INSERT INTO pet (name) VALUES ('Friar Tuck');
- # add a column:
- ALTER TABLE pet ADD type VARCHAR(20));
- # update existing record:
- UPDATE pet SET type = 'cat' WHERE name = 'Friar Tuck'
現(xiàn)在用MongoDB執(zhí)行同樣的過程:
- # connect to the database in app and issue insert:
- use menagerie; db.pet.insertOne({name:"friar tuck"});
- # issue update:
- db.pet.updateOne({ name:'friar tuck' }, { $set:{ type: 'cat' } } );
從前面您可以了解使用MongoDB的開發(fā)體驗(yàn)有多流暢。
這種靈活性當(dāng)然將避免模式臃腫的負(fù)擔(dān)加在了開發(fā)人員的身上。駕馭大型應(yīng)用程序的文檔結(jié)構(gòu)至關(guān)重要。
MongoDB中的ID字段
關(guān)系型數(shù)據(jù)庫中有主鍵這個概念,這通常是一個合成ID列(也就是說,與業(yè)務(wù)數(shù)據(jù)無關(guān)的生成值)。在MongoDB中,每個文檔都有一個用途相似的_id字段。如果開發(fā)人員在創(chuàng)建文檔時沒有提供 ID,MongoDB引擎將自動生成一個ID(作為 UUID)。
與主鍵一樣,_id 字段自動索引,而且必須是唯一的。
MongoDB中的索引
MongoDB中的索引其行為類似關(guān)系數(shù)據(jù)庫中的索引:它創(chuàng)建有關(guān)文檔字段的額外數(shù)據(jù),以加快依賴該字段的查詢。MongoDB使用 B 樹索引。
可以使用如下語法創(chuàng)建索引:
- db.pet.createIndex( { name: 1 } )
參數(shù)中的整數(shù)表示索引是升序(1) 還是降序(-1)。
MongoDB中嵌套文檔
MongoDB面向文檔結(jié)構(gòu)的一個強(qiáng)大方面是文檔可以嵌套。比如說,您可以創(chuàng)建嵌套文檔,而不是創(chuàng)建另一個表來存儲寵物文檔的地址信息,結(jié)構(gòu)如代碼片段1所示。
代碼片段1. 嵌套文檔示例
- {
- "_id": "5cf0029caff5056591b0ce7d",
- "name": "Friar Tuck",
- "address": {
- "street": "Feline Lane",
- "city": "Big Sur",
- "state": "CA",
- "zip": "93920"
- },
- "type": "cat"
- }
MongoDB中的非規(guī)范化
MongoDB等文檔存儲系統(tǒng)對連接的支持有限,也沒有外來鍵的概念。兩者都是數(shù)據(jù)結(jié)構(gòu)動態(tài)特性的結(jié)果。MongoDB中的數(shù)據(jù)建模傾向于非規(guī)范化,即復(fù)制文檔中的數(shù)據(jù),而不是將數(shù)據(jù)嚴(yán)格保存在表孤島中。這提高了查找速度,不過以增加數(shù)據(jù)一致性維護(hù)為代價。
非規(guī)范化不是必需的,在使用面向文檔的數(shù)據(jù)庫時更多地是一種傾向。這是由于處理復(fù)雜嵌套記錄的能力得到了提高,而不是SQL傾向于將數(shù)據(jù)規(guī)范化到特定的單值列中。
MongoDB查詢語言
MongoDB中的查詢語言面向JSON,就像文檔結(jié)構(gòu)一樣。這有助于一種非常強(qiáng)大的表達(dá)式語法,甚至可以處理復(fù)雜的嵌套文檔。
比如說,您可以通過執(zhí)行db.pet.find({ "type" : "cat" })來查詢收錄所有貓咪的理論數(shù)據(jù)庫,或使用db.pet.find({ "type" : "cat" , "address.state": "CA" })來查詢加利福尼亞州的所有貓咪。請注意,查詢語言遍歷嵌套的地址文檔。
MongoDB更新語法
MongoDB的alter語法也使用類似JSON的格式,其中$set關(guān)鍵字表明將更改哪個字段、更改為什么值。set對象通過點(diǎn)表示法支持嵌套文檔,如代表片段2所示,可以在其中更改名為“Friar Tuck”的那只貓的郵政編碼。
代碼片段2. 更新嵌套文檔
- db.people.update(
- {
- "type": "cat",
- "name": "Friar Tuck"
- },
- {
- $set: {
- "address.zip": "86004"
- }
- }
- )
可以從代碼片段2中看到,更新語法與SQL對應(yīng)語法一樣強(qiáng)大,實(shí)際上更強(qiáng)大。
MongoDB云和部署選項
MongoDB為可擴(kuò)展性和分布式部署而設(shè)計。它完全能夠處理大規(guī)模工作負(fù)載。
MongoDB公司在MongoDB Atlas中提供了多云數(shù)據(jù)庫集群解決方案。MongoDB Atlas就像一個托管數(shù)據(jù)庫,可以橫跨不同的云平臺,包括監(jiān)控和容錯等企業(yè)功能。
不難看出MongoDB的重要性,因此AWS的Amazon DocumentDB產(chǎn)品將MongoDB兼容性作為主要賣點(diǎn)。微軟的Azure Cosmos DB遵循類似的模式,支持MongoDB API。
MongoDB中的高可用性
MongoDB支持副本集以實(shí)現(xiàn)高可用性。核心思想是將數(shù)據(jù)一次寫入主實(shí)例,然后復(fù)制到二級存儲以便讀取。在此處(https://docs.mongodb.com/manual/replication/)可了解有關(guān)MongoDB中復(fù)制的更多信息。
結(jié)論是,MongoDB是一種領(lǐng)先的 NoSQL 解決方案,兌現(xiàn)了靈活模式數(shù)據(jù)存儲系統(tǒng)的承諾??墒褂妹嫦驇缀醺鞣N編程語言的高級驅(qū)動程序,您也可以利用眾多部署選項。
原文標(biāo)題:What is MongoDB? A quick guide for developers,作者:Matthew Tyson
【51CTO譯稿,合作站點(diǎn)轉(zhuǎn)載請注明原文譯者和出處為51CTO.com】