下文例子中演示了如何插入、獲取、刪除一條記錄
成都創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設、高性價比日照網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式日照網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設找我們,業(yè)務覆蓋日照地區(qū)。費用合理售后完善,十載實體公司更值得信賴。
LevelDB 簡介
一、LevelDB入門
LevelDB是Google開源的持久化KV單機數(shù)據(jù)庫,具有很高的隨機寫,順序讀/寫性能,但是隨機讀的性能很一般,也就是說,LevelDB很適合應用在查詢較少,而寫很多的場景。LevelDB應用了LSM (Log Structured Merge) 策略,lsm_tree對索引變更進行延遲及批量處理,并通過一種類似于歸并排序的方式高效地將更新遷移到磁盤,降低索引插入開銷,關于LSM,本文在后面也會簡單提及。
根據(jù)LevelDB官方網(wǎng)站的描述,LevelDB的特點和限制如下:
特點:
1、key和value都是任意長度的字節(jié)數(shù)組;
2、entry(即一條K-V記錄)默認是按照key的字典順序存儲的,當然開發(fā)者也可以重載這個排序函數(shù);
3、提供的基本操作接口:Put()、Delete()、Get()、Batch();
4、支持批量操作以原子操作進行;
5、可以創(chuàng)建數(shù)據(jù)全景的snapshot(快照),并允許在快照中查找數(shù)據(jù);
6、可以通過前向(或后向)迭代器遍歷數(shù)據(jù)(迭代器會隱含的創(chuàng)建一個snapshot);
7、自動使用Snappy壓縮數(shù)據(jù);
8、可移植性;
限制:
1、非關系型數(shù)據(jù)模型(NoSQL),不支持sql語句,也不支持索引;
2、一次只允許一個進程訪問一個特定的數(shù)據(jù)庫;
3、沒有內(nèi)置的C/S架構(gòu),但開發(fā)者可以使用LevelDB庫自己封裝一個server;
LevelDB本身只是一個lib庫,在源碼目錄make編譯即可,然后在我們的應用程序里面可以直接include leveldb/include/db.h頭文件,該頭文件有幾個基本的數(shù)據(jù)庫操作接口,下面是一個測試例子:
#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后,會在/tmp下面生成一個目錄testdb,里面包含若干文件:
------------------------------------------------------------
LevelDB是google開源的一個key-value存儲引擎庫,類似于開源的Lucene索引庫一樣。其他的軟件開發(fā)者可以利用該庫做二次開發(fā),來滿足定制需求。LevelDB采用日志式的寫方式來提高寫性能,但是犧牲了部分讀性能。為了彌補犧牲了的讀性能,一些人提議使用SSD作為存儲介質(zhì)。
對于本地化的Key-value存儲引擎來說,簡單的使用一般都分成三個基本的步驟:(1)打開一個數(shù)據(jù)庫實例;(2)對這個數(shù)據(jù)庫實例進行插入,修改和查詢操作;(3)最后在使用完成之后,關閉該數(shù)據(jù)庫。下面將詳細討論該三個步驟:
一、打開一個數(shù)據(jù)庫實例
一個leveldb數(shù)據(jù)庫有一個對應一個文件系統(tǒng)目錄的名字。該數(shù)據(jù)庫的所有內(nèi)容都存儲在這個目錄下。下面的代碼描述了怎樣打開一個數(shù)據(jù)庫或者建立一個新的數(shù)據(jù)庫。
#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());
如果打開已存在數(shù)據(jù)庫的時候,需要拋出錯誤。將以下代碼插在leveldb::DB::Open方法前面:
options.error_if_exists = true;
二、對數(shù)據(jù)庫的簡單讀、寫操作
LevelDB提供了Put,Delete和Get三個方法對數(shù)據(jù)庫進行修改和查詢。例如,下面的代碼片段描述了怎樣將key1對應的value值,移到key2對應的值。
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);
三、關閉數(shù)據(jù)庫
在對數(shù)據(jù)庫進行了一系列的操作之后,需要對數(shù)據(jù)庫進行關閉。該操作比較簡單:
... open the db as described above...
... do something with db ...
delete db;
上面對levelDB的簡單使用做了基本的介紹,接下來就是如何自己寫一個完成并且能運行的例子。
1、下載源碼 git clone
2、編譯源碼 cd leveldb make all
3、編寫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、運行結(jié)果./test:
value
key2===value
key NotFound:
文檔數(shù)據(jù)庫
源起:受Lotus Notes啟發(fā)。
數(shù)據(jù)模型:包含了key-value的文檔集合
例子:CouchDB, MongoDB
優(yōu)點:數(shù)據(jù)模型自然,編程友好,快速開發(fā),web友好,CRUD。
圖數(shù)據(jù)庫
源起: 歐拉和圖理論。
數(shù)據(jù)模型:節(jié)點和關系,也可處理鍵值對。
例子:AllegroGraph, InfoGrid, Neo4j
優(yōu)點:解決復雜的圖問題。
關系數(shù)據(jù)庫
源起: E. F. Codd 在A Relational Model of Data for Large Shared Data Banks提出的
數(shù)據(jù)模型:各種關系
例子:VoltDB, Clustrix, MySQL
優(yōu)點:高性能、可擴展的OLTP,支持SQL,物化視圖,支持事務,編程友好。
對象數(shù)據(jù)庫
源起:圖數(shù)據(jù)庫研究
數(shù)據(jù)模型:對象
例子:Objectivity, Gemstone
優(yōu)點:復雜對象模型,快速鍵值訪問,鍵功能訪問,以及圖數(shù)據(jù)庫的優(yōu)點。
Key-Value數(shù)據(jù)庫
源起:Amazon的論文 Dynamo 和 Distributed HashTables。
數(shù)據(jù)模型:鍵值對
例子:Membase, Riak
優(yōu)點:處理大量數(shù)據(jù),快速處理大量讀寫請求。編程友好。
BigTable類型數(shù)據(jù)庫
源起:Google的論文 BigTable。
數(shù)據(jù)模型:列簇,每一行在理論上都是不同的
例子:HBase, Hypertable, Cassandra
優(yōu)點:處理大量數(shù)據(jù),應對極高寫負載,高可用,支持跨數(shù)據(jù)中心, MapReduce。
數(shù)據(jù)結(jié)構(gòu)服務
源起: ?
數(shù)據(jù)模型:字典操作,lists, sets和字符串值
例子:Redis
優(yōu)點:不同于以前的任何數(shù)據(jù)庫
網(wǎng)格數(shù)據(jù)庫
源起:數(shù)據(jù)網(wǎng)格和元組空間研究。
數(shù)據(jù)模型:基于空間的架構(gòu)
例子:GigaSpaces, Coherence
優(yōu)點:適于事務處理的高性能和高擴展性
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
首先通過
select *,flag=0 from d_dept
union all
select *,1 from d_unit
將所有內(nèi)容合并在一起 這樣合一起是亂序的
然后將它作為臨時表
from (
select *,flag=0 from d_dept
union all
select *,1 from d_unit) k
注意這里我加個了個FLAG字段 是為了標志0為部門 1為單位 為之后排序做準備
然后利用這個臨時表 我進行排序 看下面
select ID=Dept_ID,Name=Dept_Name
這句的意思 理解的吧 選取臨時結(jié)果集的2個字段,注意這里的Dept_ID和Dept_Name分別語句包含了unit_ID 和unit_Name(這個自己執(zhí)行下臨時結(jié)果集就知道了)
我們重點來說排序
order by left(Dept_ID,3) asc,flag asc,Dept_ID asc
先看第一個left(Dept_ID,3) 首先要進行部門排序的 我們是以左邊三個符號位排序信息的 排出來就是
001
001001
..
002
..
003
003...
上面的排序不保證每個部門里面的排序時按照部門號先 然后再改部門的單位的順序 所以加上flag asc
在每組里面 要讓部門號先 通過FLAG=0 將部門號放在了前面
所以這里出來:
001
001001
..
002
..
003
003...
請看 在001號部門里面 001 肯定在 001XXX前面了
但是這排序不能保證 001XXX 001XXY這樣的單位號排序 就是加上
Dept_ID asc 明白了吧
改變數(shù)據(jù)庫的排序規(guī)則(做ALTER之前,要中斷所有用戶對此數(shù)據(jù)庫的訪問)
語法:
use
master
go
ALTER
DATABASE
數(shù)據(jù)庫名
COLLATE
排序規(guī)則名
例子:
use
master
go
ALTER
DATABASE
luwanzhufa
COLLATE
Chinese_PRC_CS_AS
Chinese_PRC_CS_AS這個是簡體中文。而且區(qū)分大小寫的排序規(guī)則。
192
Japanese_BIN
二進制順序、用于
932(日文)字符集。
193
Japanese_CI_AS
字典順序、不區(qū)分大小寫、用于
932(日文)字符集。
200
Japanese_CS_AS
字典順序、區(qū)分大小寫、用于
932(日文)字符集。
198
Chinese_PRC_BIN
二進制順序、用于
936(簡體中文)字符集。
199
Chinese_PRC_CI_AS
字典順序、不區(qū)分大小寫、用于
936(簡體中文)字符集。
203
Chinese_PRC_CS_AS
字典順序、區(qū)分大小寫、用于
936(簡體中文)字符集。
NoSQL,泛指非關系型的數(shù)據(jù)庫。隨著互聯(lián)網(wǎng)web2.0網(wǎng)站的興起,傳統(tǒng)的關系數(shù)據(jù)庫在應付web2.0網(wǎng)站,特別是超大規(guī)模和高并發(fā)的SNS類型的web2.0純動態(tài)網(wǎng)站已經(jīng)顯得力不從心,暴露了很多難以克服的問題,而非關系型的數(shù)據(jù)庫則由于其本身的特點得到了非常迅速的發(fā)展。NoSQL數(shù)據(jù)庫的產(chǎn)生就是為了解決大規(guī)模數(shù)據(jù)集合多重數(shù)據(jù)種類帶來的挑戰(zhàn),尤其是大數(shù)據(jù)應用難題。
雖然NoSQL流行語火起來才短短一年的時間,但是不可否認,現(xiàn)在已經(jīng)開始了第二代運動。盡管早期的堆棧代碼只能算是一種實驗,然而現(xiàn)在的系統(tǒng)已經(jīng)更加的成熟、穩(wěn)定。不過現(xiàn)在也面臨著一個嚴酷的事實:技術越來越成熟——以至于原來很好的NoSQL數(shù)據(jù)存儲不得不進行重寫,也有少數(shù)人認為這就是所謂的2.0版本。這里列出一些比較知名的工具,可以為大數(shù)據(jù)建立快速、可擴展的存儲庫。
NoSQL(NoSQL = Not Only SQL ),意即“不僅僅是SQL”,是一項全新的數(shù)據(jù)庫革命性運動,早期就有人提出,發(fā)展至2009年趨勢越發(fā)高漲。NoSQL的擁護者們提倡運用非關系型的數(shù)據(jù)存儲,相對于鋪天蓋地的關系型數(shù)據(jù)庫運用,這一概念無疑是一種全新的思維的注入。
對于NoSQL并沒有一個明確的范圍和定義,但是他們都普遍存在下面一些共同特征:
不需要預定義模式:不需要事先定義數(shù)據(jù)模式,預定義表結(jié)構(gòu)。數(shù)據(jù)中的每條記錄都可能有不同的屬性和格式。當插入數(shù)據(jù)時,并不需要預先定義它們的模式。
無共享架構(gòu):相對于將所有數(shù)據(jù)存儲的存儲區(qū)域網(wǎng)絡中的全共享架構(gòu)。NoSQL往往將數(shù)據(jù)劃分后存儲在各個本地服務器上。因為從本地磁盤讀取數(shù)據(jù)的性能往往好于通過網(wǎng)絡傳輸讀取數(shù)據(jù)的性能,從而提高了系統(tǒng)的性能。
彈性可擴展:可以在系統(tǒng)運行的時候,動態(tài)增加或者刪除結(jié)點。不需要停機維護,數(shù)據(jù)可以自動遷移。
分區(qū):相對于將數(shù)據(jù)存放于同一個節(jié)點,NoSQL數(shù)據(jù)庫需要將數(shù)據(jù)進行分區(qū),將記錄分散在多個節(jié)點上面。并且通常分區(qū)的同時還要做復制。這樣既提高了并行性能,又能保證沒有單點失效的問題。
異步復制:和RAID存儲系統(tǒng)不同的是,NoSQL中的復制,往往是基于日志的異步復制。這樣,數(shù)據(jù)就可以盡快地寫入一個節(jié)點,而不會被網(wǎng)絡傳輸引起遲延。缺點是并不總是能保證一致性,這樣的方式在出現(xiàn)故障的時候,可能會丟失少量的數(shù)據(jù)。
BASE:相對于事務嚴格的ACID特性,NoSQL數(shù)據(jù)庫保證的是BASE特性。BASE是最終一致性和軟事務。
NoSQL數(shù)據(jù)庫并沒有一個統(tǒng)一的架構(gòu),兩種NoSQL數(shù)據(jù)庫之間的不同,甚至遠遠超過兩種關系型數(shù)據(jù)庫的不同??梢哉f,NoSQL各有所長,成功的NoSQL必然特別適用于某些場合或者某些應用,在這些場合中會遠遠勝過關系型數(shù)據(jù)庫和其他的NoSQL。