像MongoDB, Cassandra, HBase, DynamoDB, 和
目前創(chuàng)新互聯(lián)公司已為1000多家的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬空間、成都網(wǎng)站托管、企業(yè)網(wǎng)站設(shè)計(jì)、溫江網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。
Riak這些NoSQL缺乏傳統(tǒng)的原子事務(wù)機(jī)制,所謂原子事務(wù)機(jī)制是可以保證一系列寫(xiě)操作要么全部完成,要么全部不會(huì)完成,不會(huì)發(fā)生只完成一系列中一兩個(gè)
寫(xiě)操作;因?yàn)閿?shù)據(jù)庫(kù)不提供這種事務(wù)機(jī)制支持,開(kāi)發(fā)者需要自己編寫(xiě)代碼來(lái)確保一系列寫(xiě)操作的事務(wù)機(jī)制,比較復(fù)雜和測(cè)試。
這些NoSQL數(shù)據(jù)庫(kù)不提供事務(wù)機(jī)制原因在于其分布式特點(diǎn),一系列寫(xiě)操作中訪問(wèn)的數(shù)據(jù)可能位于不同的分區(qū)服務(wù)器,這樣的事務(wù)就變成分布式事務(wù),在分
布式事務(wù)中實(shí)現(xiàn)原子性需要彼此協(xié)調(diào),而協(xié)調(diào)是耗費(fèi)時(shí)間的,每臺(tái)機(jī)器在一個(gè)大事務(wù)過(guò)程中必須依次確認(rèn),這就需要一種協(xié)議確保一個(gè)事務(wù)中沒(méi)有任何一臺(tái)機(jī)器寫(xiě)操
作失敗。
這種協(xié)調(diào)是昂貴的,會(huì)增加延遲時(shí)間,關(guān)鍵問(wèn)題是,當(dāng)協(xié)調(diào)沒(méi)有完成時(shí),其他操作是不能讀取事務(wù)中寫(xiě)操作結(jié)果的,這是因?yàn)槭聞?wù)的all-or-
nothing原理導(dǎo)致,萬(wàn)一協(xié)調(diào)過(guò)程發(fā)現(xiàn)某個(gè)寫(xiě)操作不能完成,那么需要將其他寫(xiě)操作成功的進(jìn)行回滾。針對(duì)分布式事務(wù)的分布式協(xié)調(diào)對(duì)整體數(shù)據(jù)庫(kù)性能有嚴(yán)重
影響,不只是吞吐量還包括延遲時(shí)間,這樣大部分NoSQL數(shù)據(jù)庫(kù)因?yàn)樾阅軉?wèn)題就選擇不提供分布式事務(wù)。
MongoDB, Riak, HBase, 和 Cassandra提供基于單一鍵的事務(wù),這是因?yàn)樗行畔⒍己鸵粋€(gè)鍵key有關(guān),這個(gè)鍵是存儲(chǔ)在單個(gè)服務(wù)器上,這樣基于單鍵的事務(wù)不會(huì)帶來(lái)復(fù)雜的分布式協(xié)調(diào)。
那么看來(lái)擴(kuò)展性性能和分布式事務(wù)是一對(duì)矛盾,總要有取舍?實(shí)際上是不完全是,現(xiàn)在完全有可能提供高擴(kuò)展的性能同時(shí)提供分布式原子事務(wù)。
FIT是這樣一個(gè)在分布式系統(tǒng)提供原子事務(wù)的策略,在fairness公平性, isolation隔離性, 和throughput吞吐量(簡(jiǎn)稱FIT)可以權(quán)衡。
一個(gè)支持分布式事務(wù)的可伸縮分布式系統(tǒng)能夠完成這三個(gè)屬性中兩個(gè),公平是事務(wù)之間不會(huì)相互影響造成延遲;隔離性提供一種幻覺(jué)好像整個(gè)數(shù)據(jù)庫(kù)只有它自
己一個(gè)事務(wù),隔離性保證當(dāng)任何同時(shí)發(fā)生的事務(wù)發(fā)生沖突時(shí),能夠保證彼此能看到彼此的寫(xiě)操作結(jié)果,因此減輕了程序員為避免事務(wù)讀寫(xiě)沖突的強(qiáng)邏輯推理要求;吞
吐量是指每單元時(shí)間數(shù)據(jù)庫(kù)能夠并發(fā)處理多少事務(wù)。
FIT是如下進(jìn)行權(quán)衡:
保證公平性fairness 和隔離性isolation, 但是犧牲吞吐量
保證公平性fairness和吞吐量, 犧牲隔離性isolation
保證隔離性isolation和吞吐量throughput, 但是犧牲公平性fairness.
犧牲公平性:放棄公平性,數(shù)據(jù)庫(kù)能有更多機(jī)會(huì)降低分布式事務(wù)的成本,主要成本是分布式協(xié)調(diào)帶來(lái)的,也就是說(shuō),不需要在每個(gè)事務(wù)過(guò)程內(nèi)對(duì)每個(gè)機(jī)器都依
次確認(rèn)事務(wù)完成,這樣排隊(duì)式的確認(rèn)commit事務(wù)是很浪費(fèi)時(shí)間的,放棄公平性,意味著可以在事務(wù)外面進(jìn)行協(xié)調(diào),這樣就只是增加了協(xié)調(diào)時(shí)間,不會(huì)增加互相
沖突事務(wù)因?yàn)楸舜藳_突而不能運(yùn)行所耽擱的時(shí)間,當(dāng)系統(tǒng)不需要公平性時(shí),需要根據(jù)事務(wù)的優(yōu)先級(jí)或延遲等標(biāo)準(zhǔn)進(jìn)行指定先后執(zhí)行順序,這樣就能夠獲得很好的吞吐
量。
G-Store是一種放棄公平性的 Isolation-Throughput
的分布式key-value存儲(chǔ),支持多鍵事務(wù)(multi-key transactions),MongoDB 和
HBase在鍵key在同樣分區(qū)上也支持多鍵事務(wù),但是不支持跨分區(qū)的事務(wù)。
總之:傳統(tǒng)分布式事務(wù)性能不佳的原因是確保原子性(分布式協(xié)調(diào))和隔離性同時(shí)重疊,創(chuàng)建一個(gè)高吞吐量分布式事務(wù)的關(guān)鍵是分離這兩種關(guān)注,這種分離原
子性和隔離性的視角將導(dǎo)致兩種類(lèi)型的系統(tǒng),第一種選擇是弱隔離性能讓沖突事務(wù)并行執(zhí)行和確認(rèn)提交;第二個(gè)選擇重新排序原子性和隔離性機(jī)制保證它們不會(huì)某個(gè)
時(shí)間重疊,這是一種放棄公平的事務(wù)執(zhí)行,所謂放棄公平就是不再同時(shí)照顧原子性和隔離性了,有所傾斜,放棄高標(biāo)準(zhǔn)道德要求就會(huì)帶來(lái)高自由高效率。
NoSQL,泛指非關(guān)系型的數(shù)據(jù)庫(kù)。隨著互聯(lián)網(wǎng)web2.0網(wǎng)站的興起,傳統(tǒng)的關(guān)系數(shù)據(jù)庫(kù)在應(yīng)付web2.0網(wǎng)站,特別是超大規(guī)模和高并發(fā)的SNS類(lèi)型的web2.0純動(dòng)態(tài)網(wǎng)站已經(jīng)顯得力不從心,暴露了很多難以克服的問(wèn)題,而非關(guān)系型的數(shù)據(jù)庫(kù)則由于其本身的特點(diǎn)得到了非常迅速的發(fā)展。NoSQL數(shù)據(jù)庫(kù)的產(chǎn)生就是為了解決大規(guī)模數(shù)據(jù)集合多重?cái)?shù)據(jù)種類(lèi)帶來(lái)的挑戰(zhàn),尤其是大數(shù)據(jù)應(yīng)用難題。
雖然NoSQL流行語(yǔ)火起來(lái)才短短一年的時(shí)間,但是不可否認(rèn),現(xiàn)在已經(jīng)開(kāi)始了第二代運(yùn)動(dòng)。盡管早期的堆棧代碼只能算是一種實(shí)驗(yàn),然而現(xiàn)在的系統(tǒng)已經(jīng)更加的成熟、穩(wěn)定。不過(guò)現(xiàn)在也面臨著一個(gè)嚴(yán)酷的事實(shí):技術(shù)越來(lái)越成熟——以至于原來(lái)很好的NoSQL數(shù)據(jù)存儲(chǔ)不得不進(jìn)行重寫(xiě),也有少數(shù)人認(rèn)為這就是所謂的2.0版本。這里列出一些比較知名的工具,可以為大數(shù)據(jù)建立快速、可擴(kuò)展的存儲(chǔ)庫(kù)。
NoSQL(NoSQL = Not Only SQL ),意即“不僅僅是SQL”,是一項(xiàng)全新的數(shù)據(jù)庫(kù)革命性運(yùn)動(dòng),早期就有人提出,發(fā)展至2009年趨勢(shì)越發(fā)高漲。NoSQL的擁護(hù)者們提倡運(yùn)用非關(guān)系型的數(shù)據(jù)存儲(chǔ),相對(duì)于鋪天蓋地的關(guān)系型數(shù)據(jù)庫(kù)運(yùn)用,這一概念無(wú)疑是一種全新的思維的注入。
對(duì)于NoSQL并沒(méi)有一個(gè)明確的范圍和定義,但是他們都普遍存在下面一些共同特征:
不需要預(yù)定義模式:不需要事先定義數(shù)據(jù)模式,預(yù)定義表結(jié)構(gòu)。數(shù)據(jù)中的每條記錄都可能有不同的屬性和格式。當(dāng)插入數(shù)據(jù)時(shí),并不需要預(yù)先定義它們的模式。
無(wú)共享架構(gòu):相對(duì)于將所有數(shù)據(jù)存儲(chǔ)的存儲(chǔ)區(qū)域網(wǎng)絡(luò)中的全共享架構(gòu)。NoSQL往往將數(shù)據(jù)劃分后存儲(chǔ)在各個(gè)本地服務(wù)器上。因?yàn)閺谋镜卮疟P(pán)讀取數(shù)據(jù)的性能往往好于通過(guò)網(wǎng)絡(luò)傳輸讀取數(shù)據(jù)的性能,從而提高了系統(tǒng)的性能。
彈性可擴(kuò)展:可以在系統(tǒng)運(yùn)行的時(shí)候,動(dòng)態(tài)增加或者刪除結(jié)點(diǎn)。不需要停機(jī)維護(hù),數(shù)據(jù)可以自動(dòng)遷移。
分區(qū):相對(duì)于將數(shù)據(jù)存放于同一個(gè)節(jié)點(diǎn),NoSQL數(shù)據(jù)庫(kù)需要將數(shù)據(jù)進(jìn)行分區(qū),將記錄分散在多個(gè)節(jié)點(diǎn)上面。并且通常分區(qū)的同時(shí)還要做復(fù)制。這樣既提高了并行性能,又能保證沒(méi)有單點(diǎn)失效的問(wèn)題。
異步復(fù)制:和RAID存儲(chǔ)系統(tǒng)不同的是,NoSQL中的復(fù)制,往往是基于日志的異步復(fù)制。這樣,數(shù)據(jù)就可以盡快地寫(xiě)入一個(gè)節(jié)點(diǎn),而不會(huì)被網(wǎng)絡(luò)傳輸引起遲延。缺點(diǎn)是并不總是能保證一致性,這樣的方式在出現(xiàn)故障的時(shí)候,可能會(huì)丟失少量的數(shù)據(jù)。
BASE:相對(duì)于事務(wù)嚴(yán)格的ACID特性,NoSQL數(shù)據(jù)庫(kù)保證的是BASE特性。BASE是最終一致性和軟事務(wù)。
NoSQL數(shù)據(jù)庫(kù)并沒(méi)有一個(gè)統(tǒng)一的架構(gòu),兩種NoSQL數(shù)據(jù)庫(kù)之間的不同,甚至遠(yuǎn)遠(yuǎn)超過(guò)兩種關(guān)系型數(shù)據(jù)庫(kù)的不同??梢哉f(shuō),NoSQL各有所長(zhǎng),成功的NoSQL必然特別適用于某些場(chǎng)合或者某些應(yīng)用,在這些場(chǎng)合中會(huì)遠(yuǎn)遠(yuǎn)勝過(guò)關(guān)系型數(shù)據(jù)庫(kù)和其他的NoSQL。
select ID=Dept_ID,Name=Dept_Name
from (
select *,flag=0 from d_dept
union all
select *,1 from d_unit) k
order by left(Dept_ID,3) asc,flag asc,Dept_ID asc
首先通過(guò)
select *,flag=0 from d_dept
union all
select *,1 from d_unit
將所有內(nèi)容合并在一起 這樣合一起是亂序的
然后將它作為臨時(shí)表
from (
select *,flag=0 from d_dept
union all
select *,1 from d_unit) k
注意這里我加個(gè)了個(gè)FLAG字段 是為了標(biāo)志0為部門(mén) 1為單位 為之后排序做準(zhǔn)備
然后利用這個(gè)臨時(shí)表 我進(jìn)行排序 看下面
select ID=Dept_ID,Name=Dept_Name
這句的意思 理解的吧 選取臨時(shí)結(jié)果集的2個(gè)字段,注意這里的Dept_ID和Dept_Name分別語(yǔ)句包含了unit_ID 和unit_Name(這個(gè)自己執(zhí)行下臨時(shí)結(jié)果集就知道了)
我們重點(diǎn)來(lái)說(shuō)排序
order by left(Dept_ID,3) asc,flag asc,Dept_ID asc
先看第一個(gè)left(Dept_ID,3) 首先要進(jìn)行部門(mén)排序的 我們是以左邊三個(gè)符號(hào)位排序信息的 排出來(lái)就是
001
001001
..
002
..
003
003...
上面的排序不保證每個(gè)部門(mén)里面的排序時(shí)按照部門(mén)號(hào)先 然后再改部門(mén)的單位的順序 所以加上flag asc
在每組里面 要讓部門(mén)號(hào)先 通過(guò)FLAG=0 將部門(mén)號(hào)放在了前面
所以這里出來(lái):
001
001001
..
002
..
003
003...
請(qǐng)看 在001號(hào)部門(mén)里面 001 肯定在 001XXX前面了
但是這排序不能保證 001XXX 001XXY這樣的單位號(hào)排序 就是加上
Dept_ID asc 明白了吧
文檔數(shù)據(jù)庫(kù)
源起:受Lotus Notes啟發(fā)。
數(shù)據(jù)模型:包含了key-value的文檔集合
例子:CouchDB, MongoDB
優(yōu)點(diǎn):數(shù)據(jù)模型自然,編程友好,快速開(kāi)發(fā),web友好,CRUD。
圖數(shù)據(jù)庫(kù)
源起: 歐拉和圖理論。
數(shù)據(jù)模型:節(jié)點(diǎn)和關(guān)系,也可處理鍵值對(duì)。
例子:AllegroGraph, InfoGrid, Neo4j
優(yōu)點(diǎn):解決復(fù)雜的圖問(wèn)題。
關(guān)系數(shù)據(jù)庫(kù)
源起: E. F. Codd 在A Relational Model of Data for Large Shared Data Banks提出的
數(shù)據(jù)模型:各種關(guān)系
例子:VoltDB, Clustrix, MySQL
優(yōu)點(diǎn):高性能、可擴(kuò)展的OLTP,支持SQL,物化視圖,支持事務(wù),編程友好。
對(duì)象數(shù)據(jù)庫(kù)
源起:圖數(shù)據(jù)庫(kù)研究
數(shù)據(jù)模型:對(duì)象
例子:Objectivity, Gemstone
優(yōu)點(diǎn):復(fù)雜對(duì)象模型,快速鍵值訪問(wèn),鍵功能訪問(wèn),以及圖數(shù)據(jù)庫(kù)的優(yōu)點(diǎn)。
Key-Value數(shù)據(jù)庫(kù)
源起:Amazon的論文 Dynamo 和 Distributed HashTables。
數(shù)據(jù)模型:鍵值對(duì)
例子:Membase, Riak
優(yōu)點(diǎn):處理大量數(shù)據(jù),快速處理大量讀寫(xiě)請(qǐng)求。編程友好。
BigTable類(lèi)型數(shù)據(jù)庫(kù)
源起:Google的論文 BigTable。
數(shù)據(jù)模型:列簇,每一行在理論上都是不同的
例子:HBase, Hypertable, Cassandra
優(yōu)點(diǎn):處理大量數(shù)據(jù),應(yīng)對(duì)極高寫(xiě)負(fù)載,高可用,支持跨數(shù)據(jù)中心, MapReduce。
數(shù)據(jù)結(jié)構(gòu)服務(wù)
源起: ?
數(shù)據(jù)模型:字典操作,lists, sets和字符串值
例子:Redis
優(yōu)點(diǎn):不同于以前的任何數(shù)據(jù)庫(kù)
網(wǎng)格數(shù)據(jù)庫(kù)
源起:數(shù)據(jù)網(wǎng)格和元組空間研究。
數(shù)據(jù)模型:基于空間的架構(gòu)
例子:GigaSpaces, Coherence
優(yōu)點(diǎn):適于事務(wù)處理的高性能和高擴(kuò)展性
下文例子中演示了如何插入、獲取、刪除一條記錄
LevelDB 簡(jiǎn)介
一、LevelDB入門(mén)
LevelDB是Google開(kāi)源的持久化KV單機(jī)數(shù)據(jù)庫(kù),具有很高的隨機(jī)寫(xiě),順序讀/寫(xiě)性能,但是隨機(jī)讀的性能很一般,也就是說(shuō),LevelDB很適合應(yīng)用在查詢較少,而寫(xiě)很多的場(chǎng)景。LevelDB應(yīng)用了LSM (Log Structured Merge) 策略,lsm_tree對(duì)索引變更進(jìn)行延遲及批量處理,并通過(guò)一種類(lèi)似于歸并排序的方式高效地將更新遷移到磁盤(pán),降低索引插入開(kāi)銷(xiāo),關(guān)于LSM,本文在后面也會(huì)簡(jiǎn)單提及。
根據(jù)LevelDB官方網(wǎng)站的描述,LevelDB的特點(diǎn)和限制如下:
特點(diǎn):
1、key和value都是任意長(zhǎng)度的字節(jié)數(shù)組;
2、entry(即一條K-V記錄)默認(rèn)是按照key的字典順序存儲(chǔ)的,當(dāng)然開(kāi)發(fā)者也可以重載這個(gè)排序函數(shù);
3、提供的基本操作接口:Put()、Delete()、Get()、Batch();
4、支持批量操作以原子操作進(jìn)行;
5、可以創(chuàng)建數(shù)據(jù)全景的snapshot(快照),并允許在快照中查找數(shù)據(jù);
6、可以通過(guò)前向(或后向)迭代器遍歷數(shù)據(jù)(迭代器會(huì)隱含的創(chuàng)建一個(gè)snapshot);
7、自動(dòng)使用Snappy壓縮數(shù)據(jù);
8、可移植性;
限制:
1、非關(guān)系型數(shù)據(jù)模型(NoSQL),不支持sql語(yǔ)句,也不支持索引;
2、一次只允許一個(gè)進(jìn)程訪問(wèn)一個(gè)特定的數(shù)據(jù)庫(kù);
3、沒(méi)有內(nèi)置的C/S架構(gòu),但開(kāi)發(fā)者可以使用LevelDB庫(kù)自己封裝一個(gè)server;
LevelDB本身只是一個(gè)lib庫(kù),在源碼目錄make編譯即可,然后在我們的應(yīng)用程序里面可以直接include leveldb/include/db.h頭文件,該頭文件有幾個(gè)基本的數(shù)據(jù)庫(kù)操作接口,下面是一個(gè)測(cè)試?yán)樱?/p>
#include iostream
#include string
#include assert.h
#include "leveldb/db.h"
using namespace std;
int main(void)
{
leveldb::DB *db;
leveldb::Options options;
options.create_if_missing = true;
// open
leveldb::Status status = leveldb::DB::Open(options,"/tmp/testdb", db);
assert(status.ok());
string key = "name";
string value = "chenqi";
// write
status = db-Put(leveldb::WriteOptions(), key, value);
assert(status.ok());
// read
status = db-Get(leveldb::ReadOptions(), key, value);
assert(status.ok());
coutvalueendl;
// delete
status = db-Delete(leveldb::WriteOptions(), key);
assert(status.ok());
status = db-Get(leveldb::ReadOptions(),key, value);
if(!status.ok()) {
cerrkey" "status.ToString()endl;
} else {
coutkey"==="valueendl;
}
// close
delete db;
return 0;
}
上面的例子演示了如何插入、獲取、刪除一條記錄,編譯代碼:
g++ -o test test.cpp libleveldb.a -lpthread -Iinclude
執(zhí)行./test后,會(huì)在/tmp下面生成一個(gè)目錄testdb,里面包含若干文件:
------------------------------------------------------------
LevelDB是google開(kāi)源的一個(gè)key-value存儲(chǔ)引擎庫(kù),類(lèi)似于開(kāi)源的Lucene索引庫(kù)一樣。其他的軟件開(kāi)發(fā)者可以利用該庫(kù)做二次開(kāi)發(fā),來(lái)滿足定制需求。LevelDB采用日志式的寫(xiě)方式來(lái)提高寫(xiě)性能,但是犧牲了部分讀性能。為了彌補(bǔ)犧牲了的讀性能,一些人提議使用SSD作為存儲(chǔ)介質(zhì)。
對(duì)于本地化的Key-value存儲(chǔ)引擎來(lái)說(shuō),簡(jiǎn)單的使用一般都分成三個(gè)基本的步驟:(1)打開(kāi)一個(gè)數(shù)據(jù)庫(kù)實(shí)例;(2)對(duì)這個(gè)數(shù)據(jù)庫(kù)實(shí)例進(jìn)行插入,修改和查詢操作;(3)最后在使用完成之后,關(guān)閉該數(shù)據(jù)庫(kù)。下面將詳細(xì)討論該三個(gè)步驟:
一、打開(kāi)一個(gè)數(shù)據(jù)庫(kù)實(shí)例
一個(gè)leveldb數(shù)據(jù)庫(kù)有一個(gè)對(duì)應(yīng)一個(gè)文件系統(tǒng)目錄的名字。該數(shù)據(jù)庫(kù)的所有內(nèi)容都存儲(chǔ)在這個(gè)目錄下。下面的代碼描述了怎樣打開(kāi)一個(gè)數(shù)據(jù)庫(kù)或者建立一個(gè)新的數(shù)據(jù)庫(kù)。
#include assert.h
#include "leveldb/db.h"
leveldb::DB* db;
leveldb::Options options;
options.create_if_missing = true;
leveldb::Status status = leveldb::DB::Open(options,"/tmp/testdb", db);
assert(status.ok());
如果打開(kāi)已存在數(shù)據(jù)庫(kù)的時(shí)候,需要拋出錯(cuò)誤。將以下代碼插在leveldb::DB::Open方法前面:
options.error_if_exists = true;
二、對(duì)數(shù)據(jù)庫(kù)的簡(jiǎn)單讀、寫(xiě)操作
LevelDB提供了Put,Delete和Get三個(gè)方法對(duì)數(shù)據(jù)庫(kù)進(jìn)行修改和查詢。例如,下面的代碼片段描述了怎樣將key1對(duì)應(yīng)的value值,移到key2對(duì)應(yīng)的值。
std::string value;
leveldb::Status s = db-Get(leveldb::ReadOptions(), key1, value);
if(s.ok()) s = db-Put(leveldb::WriteOptions(), key2, value);
if(s.ok()) s = db-Delete(leveldb::WriteOptions(), key1);
三、關(guān)閉數(shù)據(jù)庫(kù)
在對(duì)數(shù)據(jù)庫(kù)進(jìn)行了一系列的操作之后,需要對(duì)數(shù)據(jù)庫(kù)進(jìn)行關(guān)閉。該操作比較簡(jiǎn)單:
... open the db as described above...
... do something with db ...
delete db;
上面對(duì)levelDB的簡(jiǎn)單使用做了基本的介紹,接下來(lái)就是如何自己寫(xiě)一個(gè)完成并且能運(yùn)行的例子。
1、下載源碼 git clone
2、編譯源碼 cd leveldb make all
3、編寫(xiě)test.cpp
#include assert.h
#include string.h
#include leveldb/db.h
#include iostream
int main(){
leveldb::DB* db;
leveldb::Options options;
options.create_if_missing = true;
leveldb::Status status = leveldb::DB::Open(options,"/tmp/testdb", db);
assert(status.ok());
//write key1,value1
std::string key="key";
std::string value = "value";
status = db-Put(leveldb::WriteOptions(), key,value);
assert(status.ok());
status = db-Get(leveldb::ReadOptions(), key, value);
assert(status.ok());
std::coutvaluestd::endl;
std::string key2 = "key2";
//move the value under key to key2
status = db-Put(leveldb::WriteOptions(),key2,value);
assert(status.ok());
status = db-Delete(leveldb::WriteOptions(), key);
assert(status.ok());
status = db-Get(leveldb::ReadOptions(),key2, value);
assert(status.ok());
std::coutkey2"==="valuestd::endl;
status = db-Get(leveldb::ReadOptions(),key, value);
if(!status.ok()) std::cerrkey" "status.ToString()std::endl;
else std::coutkey"==="valuestd::endl;
delete db;
return 0;
}
4、編譯鏈接 g++ -o test test.cpp ../leveldb/libleveldb.a -lpthread -I../leveldb/include
注意libleveldb.a 和leveldb include的路徑。
5、運(yùn)行結(jié)果./test:
value
key2===value
key NotFound: