作者:劉賓, thomas_liub@hotmail.com
請尊重作者著作權(quán),轉(zhuǎn)載請注明出處,謝謝!
事務(wù)處理的ACID原則
A (Atomicity) 原子性
原子性很容易理解,也就是說事務(wù)里的所有操作要么全部做完,要么都不做,事務(wù)成功的條件是事務(wù)里的所有操作都成功,只要有一個(gè)操作失敗,整個(gè)事務(wù)就失敗,需要回滾。C (Consistency) 一致性
一致性也比較容易理解,也就是說數(shù)據(jù)庫要一直處于一致的狀態(tài),事務(wù)的運(yùn)行不會改變數(shù)據(jù)庫原本的一致性約束。
例如現(xiàn)有完整性約束a+b=10,如果一個(gè)事務(wù)改變了a,那么必須得改變b,使得事務(wù)結(jié)束后依然滿足a+b=10,否則事務(wù)失敗。I (Isolation) 獨(dú)立性
所謂的獨(dú)立性是指并發(fā)的事務(wù)之間不會互相影響,如果一個(gè)事務(wù)要訪問的數(shù)據(jù)正在被另外一個(gè)事務(wù)修改,只要另外一個(gè)事務(wù)未提交,它所訪問的數(shù)據(jù)就不受未提交事務(wù)的影響。D (Durability) 持久性
持久性是指一旦事務(wù)提交后,它所做的修改將會永久的保存在數(shù)據(jù)庫上,即使出現(xiàn)宕機(jī)也不會丟失。
RDBMS遵循事務(wù)處理的ACID原則
分布式系統(tǒng)的CAP定理,又稱作布魯爾定理
- 一致性(Consistency) (所有節(jié)點(diǎn)在同一時(shí)間具有相同的數(shù)據(jù))
- 可用性(Availability) (保證每個(gè)請求不管成功或者失敗都有響應(yīng))
- 分隔容忍(Partition tolerance) (系統(tǒng)中任意信息的丟失或失敗不會影響系統(tǒng)的繼續(xù)運(yùn)作)
CAP理論的核心是:一個(gè)分布式系統(tǒng)不可能同時(shí)很好的滿足一致性,可用性和分區(qū)容錯(cuò)性這三個(gè)需求,最多只能同時(shí)較好的滿足兩個(gè)。因此,根據(jù) CAP 原理將 NoSQL 數(shù)據(jù)庫分成了滿足 CA 原則、滿足 CP 原則和滿足 AP 原則三 大類:
- CA - 單點(diǎn)集群,滿足一致性,可用性的系統(tǒng),通常在可擴(kuò)展性上不太強(qiáng)大。
- CP - 滿足一致性,分區(qū)容忍性的系統(tǒng),通常性能不是特別高。
- AP - 滿足可用性,分區(qū)容忍性的系統(tǒng),通??赡軐σ恢滦砸蟮鸵恍?/li>

NoSQL數(shù)據(jù)庫分類
| 類型 | 部分代表 | 特點(diǎn) |
|---|---|---|
| 列存儲 | Hbase,Cassandra,Hypertable | 顧名思義,是按列存儲數(shù)據(jù)的。最大的特點(diǎn)是方便存儲結(jié)構(gòu)化和半結(jié)構(gòu)化數(shù)據(jù),方便做數(shù)據(jù)壓縮,對針對某一列或者某幾列的查詢有非常大的IO優(yōu)勢。 |
| 文檔存儲 | MongoDB, CouchDB | 文檔存儲一般用類似json的格式存儲,存儲的內(nèi)容是文檔型的。這樣也就有有機(jī)會對某些字段建立索引,實(shí)現(xiàn)關(guān)系數(shù)據(jù)庫的某些功能。 |
| key-value存儲 | Tokyo Cabinet / Tyrant,Berkeley DB,MemcacheDB,Redis | 可以通過key快速查詢到其value。一般來說,存儲不管value的格式,照單全收。(Redis包含了其他功能) |
| 圖存儲 | Neo4J,FlockDB | 圖形關(guān)系的最佳存儲。使用傳統(tǒng)關(guān)系數(shù)據(jù)庫來解決的話性能低下,而且設(shè)計(jì)使用不方便。 |
| 對象存儲 | db4o,Versant | 通過類似面向?qū)ο笳Z言的語法操作數(shù)據(jù)庫,通過對象的方式存取數(shù)據(jù)。 |
| xml數(shù)據(jù)庫 | Berkeley DB XML BaseX | 高效的存儲XML數(shù)據(jù),并支持XML的內(nèi)部查詢語法,比如XQuery,Xpath。 |
概念對比
| SQL術(shù)語/概念 | MongoDB術(shù)語/概念 | 解釋/說明 |
|---|---|---|
| database | database | 數(shù)據(jù)庫 |
| table | collection | 數(shù)據(jù)庫表/集合 |
| row | document | 數(shù)據(jù)記錄行/文檔 |
| column | field | 數(shù)據(jù)字段/域 |
| index | index | 索引 |
| table joins | - | 表連接,MongoDB不支持 |
| primary key | primary key | 主鍵,MongoDB自動(dòng)將_id字段設(shè)置為主鍵 |
Mongo DB數(shù)據(jù)類型
| 數(shù)據(jù)類型 | 描述 |
|---|---|
| String | 字符串。存儲數(shù)據(jù)常用的數(shù)據(jù)類型。在 MongoDB 中,UTF-8 編碼的字符串才是合法的。 |
| Integer | 整型數(shù)值。用于存儲數(shù)值。根據(jù)你所采用的服務(wù)器,可分為 32 位或 64 位。 |
| Boolean | 布爾值。用于存儲布爾值(真/假)。 |
| Double | 雙精度浮點(diǎn)值。用于存儲浮點(diǎn)值。 |
| Min/Max keys | 將一個(gè)值與 BSON(二進(jìn)制的 JSON)元素的最低值和最高值相對比。 |
| Arrays | 用于將數(shù)組或列表或多個(gè)值存儲為一個(gè)鍵。 |
| Timestamp | 時(shí)間戳。記錄文檔修改或添加的具體時(shí)間。 |
| Object | 用于內(nèi)嵌文檔。 |
| Null | 用于創(chuàng)建空值。 |
| Symbo | 符號。該數(shù)據(jù)類型基本上等同于字符串類型,但不同的是,它一般用于采用特殊符號類型的語言。 |
| Date | 日期時(shí)間。用 UNIX 時(shí)間格式來存儲當(dāng)前日期或時(shí)間。你可以指定自己的日期時(shí)間:創(chuàng)建 Date 對象,傳入年月日信息。 |
| Object ID | 對象 ID。用于創(chuàng)建文檔的 ID。 |
| Binary Data | 二進(jìn)制數(shù)據(jù)。用于存儲二進(jìn)制數(shù)據(jù)。 |
| Code | 代碼類型。用于在文檔中存儲 JavaScript 代碼。 |
| Regular expression | 正則表達(dá)式類型。用于存儲正則表達(dá)式。 |
數(shù)據(jù)庫命令
數(shù)據(jù)庫相關(guān)
- 列出所有數(shù)據(jù)庫
show dbs
- 列出當(dāng)前數(shù)據(jù)庫
db
- 創(chuàng)建/切換當(dāng)前數(shù)據(jù)庫
user db_name
- 刪除數(shù)據(jù)庫
use runoob
db.dropDatabase()
- 數(shù)據(jù)庫連接URI寫法
mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
* mongodb:// 這是固定的格式,必須要指定。
* username:password@ 可選項(xiàng),如果設(shè)置,在連接數(shù)據(jù)庫服務(wù)器之后,驅(qū)動(dòng)都會嘗試登陸這個(gè)數(shù)據(jù)庫
* host1 必須的指定至少一個(gè)host, host1 是這個(gè)URI唯一要填寫的。它指定了要連接服務(wù)器的地址。如果要連接復(fù)制集,請指定多個(gè)主機(jī)地址。
* portX 可選的指定端口,如果不填,默認(rèn)為27017
* /database 如果指定username:password@,連接并驗(yàn)證登陸指定數(shù)據(jù)庫。若不指定,默認(rèn)打開admin數(shù)據(jù)庫。
* ?options 是連接選項(xiàng)。如果不使用/database,則前面需要加上/。所有連接選項(xiàng)都是鍵值對name=value,鍵值對之間通過&或;(分號)隔開
集合相關(guān)
- 刪除集合
use runoob
show tables()
>site
db.site.drop()
文檔相關(guān)
- 插入文檔
db.COLLECTION_NAME.insert(document)
例如:
db.col.insert({title: 'MongoDB 教程',
description: 'MongoDB 是一個(gè) Nosql 數(shù)據(jù)庫',
by: '菜鳥教程',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
})
查詢文檔
db.collection.find(query, projection)
db.col.find().pretty()
query :可選,使用查詢操作符指定查詢條件
projection :可選,使用投影操作符指定返回的鍵。查詢時(shí)返回文檔中所有鍵值, 只需省略該參數(shù)即可(默認(rèn)省略)
查詢算數(shù)條件
| 操作 | 格式 | 范例 | RDBMS中的類似語句 |
|---|---|---|---|
| 等于 | {<key>:<value>} | db.col.find({"by":"菜鳥教程"}).pretty() | where by = '菜鳥教程' |
| 小于 | {<key>:{$lt:<value>}} | db.col.find({"likes":{$lt:50}}).pretty() | where likes < 50 |
| 小于或等于 | {<key>:{$lte:<value>}} | db.col.find({"likes":{$lte:50}}).pretty() | where likes <= 50 |
| 大于 | {<key>:{$gt:<value>}} | db.col.find({"likes":{$gt:50}}).pretty() | where likes > 50 |
| 大于或等于 | {<key>:{$gte:<value>}} | db.col.find({"likes":{$gte:50}}).pretty() | where likes >= 50 |
| 不等于 | {<key>:{$ne:<value>}} | db.col.find({"likes":{$ne:50}}).pretty() | where likes != 50 |
邏輯條件
- AND條件
方法可以傳入多個(gè)鍵(key),每個(gè)鍵(key)以逗號隔開,及常規(guī) SQL 的 AND 條件.
db.col.find({key1:value1, key2:value2}).pretty()
db.col.find({"by":"菜鳥教程", "title":"MongoDB 教程"}).pretty()
{
"_id" : ObjectId("56063f17ade2f21f36b03133"),
"title" : "MongoDB 教程",
"description" : "MongoDB 是一個(gè) Nosql 數(shù)據(jù)庫",
"by" : "菜鳥教程",
"url" : "http://www.runoob.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100
}
- OR條件
>db.col.find(
{
$or: [
{key1: value1}, {key2:value2}
]
}
).pretty()
db.col.find({$or:[{"by":"菜鳥教程"},{"title": "MongoDB 教程"}]}).pretty()
- 組合
db.col.find({"likes": {$gt:50}, $or: [{"by": "菜鳥教程"},{"title": "MongoDB 教程"}]}).pretty()
類型查詢,$type
| 類型 | 數(shù)字 |
|---|---|
| Double | 1 |
| String | 2 |
| Object | 3 |
| Array | 4 |
| Binary data | 5 |
| Undefined | 6 已廢棄。 |
| Object id | 7 |
| Boolean | 8 |
| Date | 9 |
| Null | 10 |
| Regular Expression | 11 |
| JavaScript | 13 |
| Symbol | 14 |
| JavaScript (with scope) | 15 |
| 32-bit integer | 16 |
| Timestamp | 17 |
| 64-bit integer | 18 |
| Min key | 255 Query with -1. |
| Max key | 127 |
查找title是字符串的文檔
db.col.find({"title" : {$type : 2}})
查詢offset
跳過10個(gè)返回100條文檔
db.COLLECTION_NAME.find().skip(10).limit(100)
查詢排序
升序排列
db.COLLECTION_NAME.find().sort({KEY:1})
降序排列
db.COLLECTION_NAME.find().sort({KEY:-1})
更新文檔
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})
db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}},{multi:true})
query : update的查詢條件,類似sql update查詢內(nèi)where后面的。
update : update的對象和一些更新的操作符(如$,$inc...)等,也可以理解為sql update查詢內(nèi)set后面的
upsert : 可選,這個(gè)參數(shù)的意思是,如果不存在update的記錄,是否插入objNew,true為插入,默認(rèn)是false,不插入。
multi : 可選,mongodb 默認(rèn)是false,只更新找到的第一條記錄,如果這個(gè)參數(shù)為true,就把按條件查出來多條記錄全部更新。
writeConcern :可選,拋出異常的級別。
db.collection.save(
<document>,
{
writeConcern: <document>
}
)
db.col.save({
"_id" : ObjectId("56064f89ade2f21f36b03136"),
"title" : "MongoDB",
"description" : "MongoDB 是一個(gè) Nosql 數(shù)據(jù)庫",
"by" : "Runoob",
"url" : "http://www.runoob.com",
"tags" : [
"mongodb",
"NoSQL"
],
"likes" : 110
})
document : 文檔數(shù)據(jù)。
writeConcern :可選,拋出異常的級別。
刪除文檔
db.collection.remove(
<query>,
<justOne>
)
刪除所有匹配成功的文檔
db.col.remove({'title':'MongoDB 教程'})
刪除找到的第一個(gè)文檔
db.col.remove({'title':'MongoDB 教程'},1)
刪除所有文檔:
db.col.remove({})
query :(可選)刪除的文檔的條件。
justOne : (可選)如果設(shè)為 true 或 1,則只刪除一個(gè)文檔。
writeConcern :(可選)拋出異常的級別。
創(chuàng)建索引
db.COLLECTION_NAME.ensureIndex({KEY:1})
語法中 Key 值為你要?jiǎng)?chuàng)建的索引字段,1為指定按升序創(chuàng)建索引,如果你想按降序來創(chuàng)建索引指定為-1即可
聚合操作
MongoDB中聚合(aggregate)主要用于處理數(shù)據(jù)(諸如統(tǒng)計(jì)平均值,求和等),并返回計(jì)算后的數(shù)據(jù)結(jié)果。有點(diǎn)類似sql語句中的 count(*)
db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])