複製鏈接
請複製以下鏈接發送給好友

Berkeley DB

鎖定
Berkeley DB是一個開源的文件數據庫,介於關係數據庫與內存數據庫之間,使用方式與內存數據庫類似,它提供的是一系列直接訪問數據庫的函數,而不是像關係數據庫那樣需要網絡通訊、SQL解析等步驟。
外文名
Berkeley DB
類    型
文件數據庫
分    類
開源
平    台
UNIX/LINUX操作系統

Berkeley DB簡介

Berkeley DB是歷史悠久的嵌入式數據庫系統,主要應用在UNIX/LINUX操作系統上,其設計思想是簡單、小巧、可靠、高性能。 [1] 
Berkeley DB (DB)是一個高性能的,嵌入數據庫編程庫,和C語言,C++,Java,Perl,Python,PHP,Tcl以及其他很多語言都有綁定。Berkeley DB可以保存任意類型的鍵/值對,而且可以為一個鍵保存多個數據。Berkeley DB可以支持數千的併發線程同時操作數據庫,支持最大256TB的數據,廣泛
Berkeley DB Berkeley DB
用於各種操作系統包括大多數Unix類操作系統和Windows操作系統以及實時操作系統
2.0版本或以上的Berkeley DB由Sleepycat Software公司開發,並使用基於自由軟件許可協議/私有許可協議的雙重授權方式提供[1],附有源代碼。開發者如果想把Berkeley DB嵌入在私有軟件內需要得到Sleepycat公司的許可,若將軟件同樣遵循GPL發佈,則不需許可即可使用。而2.0版本以下的則使用BSD授權,可自由作商業用途。
Berkeley DB最初開發的目的是以新的HASH訪問算法來代替舊的hsearch函數和大量的dbm實現(如AT&T的dbm,Berkeley的 ndbm,GNU項目的gdbm),Berkeley DB的第一個發行版在1991年出現,當時還包含了B+樹數據訪問算法。在這以後,Berkeley DB得到了廣泛的應用,成為一款獨樹一幟的嵌入式數據庫系統。2006年Sleepycat公司被Oracle 公司收購,Berkeley DB成為Oracle數據庫家族的一員,Sleepycat原有開發者繼續在Oracle開發Berkeley DB,Oracle繼續原來的授權方式並且加大了對Berkeley DB的開發力度,繼續提升了Berkeley DB在軟件行業的聲譽。Berkeley DB的當前最新發行版本是6.4.9
值得注意的是DB是嵌入式數據庫系統,而不是常見的關係/對象型數據庫,對SQL語言不支持(目前已經支持SQL),也不提供數據庫常見的高級功能,如存儲過程觸發器等。

Berkeley DB結構

Berkeley DB以擁有比Microsoft SQL Server和Oracle等數據庫系統而言更簡單的體系結構而著稱。例如,它不支持網絡訪問—程序通過進程內的API訪問數據庫。 他不支持其他的數據庫查詢語言,最新的版本已支持sql,不支持表結構和數據列。 訪問數據庫的程序自主決定數據如何儲存在記錄裏,Berkeley DB不對記錄裏的數據進行任何包裝,每個記錄有且只有兩部分:鍵、值,所以在Berkeley DB的背景下通常用key/data pair指代一個記錄。記錄和它的鍵都可以達到4G字節的長度。
儘管架構很簡單,Berkeley DB卻支持很多高級的數據庫特性,比如ACID 數據庫事務處理,細粒度鎖,XA接口,熱備份以及同步複製。
DB中核心數據結構在使用前都要初始化,隨後可以調用結構中的函數(指針)完成各種操作,最後必須關閉數據結構。從設計思想的層面上看,這種設計方法是利用面向過程語言實現面對對象編程的一個典範。
Berkeley DB數據訪問算法
在數據庫領域中,數據訪問算法對應了數據在硬盤上的存儲格式和操作方法。在編寫應用程序時,選擇合適的算法可能會在運算速度上提高1個甚至多個數量級。大多數數據庫都選用B+樹算法,DB也不例外,同時還支持HASH算法、Recno算法和Queue算法。接下來,我們將討論這些算法的特點以及如何根據需要存儲數據的特點進行選擇。
B+樹算法
B+樹是一個平衡樹,關鍵字有序存儲,並且其結構能隨數據的插入和刪除進行動態調整。為了代碼的簡單,DB沒有實現對關鍵字的前綴碼壓縮。B+樹支持對數據查詢、插入、刪除的常數級速度。關鍵字可以為任意的數據結構.
HASH算法
DB中實際使用的是擴展線性HASH算法(extended linear hashing),可以根據HASH表的增長進行適當的調整。關鍵字可以為任意的數據結構。
要求每一個記錄都有一個邏輯紀錄號,邏輯紀錄號由算法本身生成。實際上,這和關係型數據庫中邏輯主鍵通常定義為int AUTO型是同一個概念。Recho建立在B+樹算法之上,提供了一個存儲有序數據的接口。記錄的長度可以為定長或不定長。 和Recno方式接近, 只不過記錄的長度為定長。數據以定長記錄方式存儲在隊列中,插入操作把記錄插入到隊列的尾部,相比之下插入速度是最快的。
對算法的選擇首先要看關鍵字的類型,如果為複雜類型,則只能選擇B+樹或HASH算法,如果關鍵字為邏輯記錄號,則應該選擇Recno或Queue算法。當工作集關鍵字有序時,B+樹算法比較合適;如果工作集比較大且基本上關鍵字為隨機分佈時,選擇HASH算法。Queue算法只能存儲定長的記錄,在高的併發處理情況下,Queue算法效率較高;如果是其它情況,則選擇Recno算法,Recno算法把數據存儲為平面文件格式。
Berkeley DB包含有與某些經典Unix數據庫編程庫兼容的接口,包括:dbm,ndbm和hsearch。
Berkeley DB的核心數據結構
數據庫環境句柄DB_ENV:每個DB_ENV相當於一個數據庫,它包含了數據庫全局信息,比如緩衝區大小、以及對事務日誌、鎖等子系統的全局配置信息。
數據庫句柄結構DB:每個DB相當於關係數據庫的一個表,其中存儲了很多key/data pair。DB句柄代表了一個包含了若干描述數據庫表屬性的參數,如數據庫訪問方法類型、邏輯頁面大小、數據庫名稱等;同時,DB結構中包含了大量的數據庫處理函數指針,大多數形式為 (*dosomething)(DB *, arg1, arg2, …)。其中最重要的有open,close,put,get等函數。
數據庫記錄結構DBT:DB中的記錄由關鍵字和數據構成,關鍵字和數據都用結構DBT表示。實際上完全可以把關鍵字看成特殊的數據。結構中最重要的兩個字段是 void * data和u_int32_t size,分別對應數據本身和數據的長度。
數據庫遊標結構DBC:遊標(cursor)是數據庫應用中常見概念,其本質上就是一個關於特定記錄的遍歷器。注意到DB支持多重記錄(duplicate records),即多條記錄有相同關鍵字,在對多重記錄的處理中,使用遊標是最容易的方式。
數據庫環境句柄結構DB_ENV:環境在DB中屬於高級特性,本質上看,環境是多個數據庫的包裝器。當一個或多個數據庫在環境中打開後,環境可以為這些數據庫提供多種子系統服務,例如多線/進程處理支持、事務處理支持、高性能支持、日誌恢復支持等。

Berkeley DB發展歷史

Berkeley DB函數庫早期版本只有300K大小,但卻可管理高達256TB的數據,現在的最新版4.7也只有幾MB,既能在小型的嵌入式設備上使用,也可以在大型設備上管理重要的數據。它當前已經應用在Apache、MySQL、Sendmail、Subversion、OpenLDAP、Mozilla、Google等很多地方,而在MySQL數據庫中擔任的更是核心數據處理引擎,使MySQL成為一個小型的快速的關係數據庫,不過從MySQL5.1版本開始不再使用Berkeley DB,因為它已經被Oracle以10億美金之巨收歸囊中,而MySQL也已進了Sun的家門。
Berkeley DB對C、C++、Perl、Java、Python、Ruby、PHP等基本上所有的語言都提供了接口,對一條記錄只分為兩個字段,一個為鍵,一個為值,鍵與值可以是任意的數據,並且可以長達4GB,它提供了四種數據存取算法:B+樹、Hash、Recno、Queue,根據不同數據類型,可以選擇適當的算法以達到最佳性能。
1991年,Berkeley DB的第一個版發行(Linux系統也是在這一年誕生)。
1992年,BSD UNIX第4.4發行版中包含了Berkeley DB1.85版。基本上認為這是Berkeley DB的第一個正式版。
1996年,Sleepycat軟件公司成立,提供對Berkeley DB的商業支持。
2006年,Sleepycat被Oracle收購,當前最新版本是4.7.25。
2009年,SUN被Oracle收購,不知道MySQL會不會再次啓用Berkeley DB。

Berkeley DB系統特點

1. 訪問速度快
2. 省硬盤空間
Berkeley DB可以輕鬆支持上千個線程同時訪問數據庫,支持多進程、事務等特性。
Berkeley DB運行在大多數的操作系統中,例如大多數的UNIX系統, 和windows系統,以及實時操作系統。
Berkeley DB 還擁有對一些老的UNIX數據庫,例如dbm, ndbm und hsearch的兼容接口.
對於在java系統中的使用,Berkeley DB提供了一個壓縮成jar單個文件的java版本。 這個版本可以運行在java虛擬機上使用,並且擁有和C語言版本相同的所有操作和功能。
Berkeley DB XML,是一個接口,通過它可以實現對XML數據存貯的支持。對XML數據的訪問,會使用相應的查詢語句如Xquery, Xpath。
Berkeley DB只支持單一的數據結構,它的所有數據包括兩個部分:key 和 data.
Berkeley DB原則上是為嵌入式數據庫設計的。

Berkeley DB範例

Berkeley DB函數使用

#include <db.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
/* DB的函數執行完成後,返回0代表成功,否則失敗 */
void print_error(int ret)
{
if(ret != 0)
printf("ERROR: %s/n",db_strerror(ret));
}
/* 數據結構DBT在使用前,應首先初始化,否則編譯可通過但運行時報參數錯誤 */
void init_DBT(DBT * key, DBT * data)
{
memset(key, 0, sizeof(DBT));
memset(data, 0, sizeof(DBT));
}
void main(void)
{
DB *dbp;
DBT key, data;
u_int32_t flags;
int ret;
char *fruit = "apple";
int number = 15;
typedef struct customer
{
int c_id;
char name[10];
char address[20];
int age;
} CUSTOMER;
CUSTOMER cust;
int key_cust_c_id = 1;
cust.c_id = 1;
strncpy(cust. name, "javer", 9);
strncpy(cust.address, "chengdu", 19);
cust.age = 32;
/* 首先創建數據庫句柄 */
ret = db_create(&dbp, NULL, 0);
print_error(ret);
/* 創建數據庫標誌 */
flags = DB_CREATE;
/* 創建一個名為single.db的數據庫,使用B+樹訪問算法,本段代碼演示對簡單數據類型的處理 */
ret = dbp->open(dbp, NULL, "single.db", NULL, DB_BTREE, flags, 0);
print_error(ret);
init_DBT(&key, &data);
/* 分別對關鍵字和數據賦值和規定長度 */
key.data = fruit;
key.size = strlen(fruit) + 1;
data.data = &number;
data.size = sizeof(int);
/* 把記錄寫入數據庫中,不允許覆蓋關鍵字相同的記錄 */
ret = dbp->put(dbp, NULL, &key, &data,DB_NOOVERWRITE);
print_error(ret);
/* 手動把緩存中的數據刷新到硬盤文件中,實際上在關閉數據庫時,數據會被自動刷新 */
dbp->sync();
init_DBT(&key, &data);
key.data = fruit;
key.size = strlen(fruit) + 1;
/* 從數據庫中查詢關鍵字為apple的記錄 */
ret = dbp->get(dbp, NULL, &key, &data, 0);
print_error(ret);
/* 特別要注意數據結構DBT的字段data為void *型,所以在對data賦值和取值時,要做必要的類型轉換。 */
printf("The number = %d/n", *(int*)(data.data));
if(dbp != NULL)
dbp->close(dbp, 0);
ret = db_create(&dbp, NULL, 0);
print_error(ret);
flags = DB_CREATE;
/* 創建一個名為complex.db的數據庫,使用HASH訪問算法,本段代碼演示對複雜數據結構的處理 */
ret = dbp->open(dbp, NULL, "complex.db", NULL, DB_HASH, flags, 0);
print_error(ret);
init_DBT(&key, &data);
key.size = sizeof(int);
key.data = &(cust.c_id);
data.size = sizeof(CUSTOMER);
data.data = &cust;
ret = dbp->put(dbp, NULL, &key, &data,DB_NOOVERWRITE);
print_error(ret);
memset(&cust, 0, sizeof(CUSTOMER));
key.size = sizeof(int);
key.data = &key_cust_c_id;
data.data = &cust;
data.ulen = sizeof(CUSTOMER);
data.flags = DB_DBT_USERMEM;
dbp->get(dbp, NULL, &key, &data, 0);
print_error(ret);
printf("c_id = %d name = %s address = %s age = %d/n",
cust.c_id, cust .name, cust.address, cust.age);
if(dbp != NULL)
dbp->close(dbp, 0);
}

Berkeley DB遊標使用

遊標是依賴於數據庫句柄的,應用程序代碼框架如下:
/* 定義一個遊標變量 */
DBC * cur;
/* 首先打開數據庫,再打開遊標 */
dbp->open(dbp, ……);
dbp->cursor(dbp, NULL, &cur, 0);
/* do something with cursor */
/* 首先關閉,在關閉數據庫 */
cur->c_close(cur);
dbp->close(dbp, 0);
在遊標打開後,可以以多種方式遍歷特定記錄。
Memset(&key, 0, sizeof(DBT));
Memset(&data, 0, sizeof(DBT));
/* 因為KEY和DATA為空,則遊標遍歷整個數據庫記錄 */
While((ret = cur->c_get(cur, &key, &data, DB_NEXT)) == 0)
{
/* do something with key and data */
}
當想查詢特定關鍵字對應的記錄,則應對關鍵字賦值,並把cur->c_get()函數中標誌位設置為DB_SET。例如:
key.data = "xxxxx";
key.size = XXX;
While((ret = cur->c_get(cur, &key, &data, DB_SET)) == 0)
{
/* do something with key and data */
}
遊標的作用還有很多,如查詢多重記錄,插入/修改/刪除記錄等。

Berkeley DB環境使用

環境是DB數據庫的包裝器,提供多種高級功能。應用程序代碼框架如下:
/* 定義一個環境變量,並創建 */
DB_ENV *dbenv;
db_env_create(&dbenv, 0);
/* 在環境打開之前,可調用形式為dbenv->set_XXX()的若干函數設置環境 */
/* 通知DB使用Rijndael加密算法(參考資料4)對數據進行處理 */
dbenv->set_encrypt(dbenv, "encrypt_string", DB_ENCRYPT_AES);
/* 設置DB的緩存為5M */
dbenv->set_cachesize(dbenv, 0, 5 * 1024 * 1024, 0);
/* 設置DB查找數據庫文件的目錄 */
dbenv->set_data_dir(dbenv, "/usr/javer/work_db");
/* 打開數據庫環境,注意後四個標誌分別指示DB啓動日誌、加鎖、緩存、事務處理子系統 */
dbenv->open(dbenv,home,DB_CREATE|DB_INIT_LOG|DB_INIT_LOCK| DB_INIT_MPOOL|DB_INIT_TXN, 0);
/* 在環境打開後,則可以打開若干個數據庫,所有數據庫的處理都在環境的控制和保護中。注意db_create函數的第二個參數是環境變量 */
db_create(&dbp1, dbenv, 0);
dbp1->open(dbp1, ……);
db_create(&dbp2, dbenv, 0);
dbp1->open(dbp2, ……);
/* do something with the database */
/* 最後首先關閉打開的數據庫,再關閉環境 */
dbp2->close(dbp2, 0);
dbp1->close(dbp1, 0);
dbenv->close(dbenv, 0);
參考資料