欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
嵌入式數據庫系統Berkeley DB

2005 年 4 月 01 日

Berkeley DB是歷史悠久的嵌入式數據庫系統,主要應用在UNIX/LINUX操作系統上,其設計思想是簡(jiǎn)單、小巧、可靠、高性能。本文是對DB開(kāi)發(fā)的一個(gè)入門(mén)級指南,重點(diǎn)討論了DB的核心數據結構和數據訪(fǎng)問(wèn)算法,并通過(guò)實(shí)際的代碼演示如何使用DB。最后有一個(gè)對DB的簡(jiǎn)單總結,并提出作者對工具選擇的一些感想。

前言

UNIX/LINUX平臺下的數據庫種類(lèi)非常多,參考資料1中列舉了其中的大部分。通常,我們在設計UNIX/LINUX平臺下的應用軟件時(shí),如果數據種類(lèi)繁多,數據與數據之間關(guān)系比較復雜,就會(huì )選用一些大型的企業(yè)級數據庫系統,如DB2,ORACLE、SYBASE等,如果軟件規模不大,就傾向選用如MYSQL、POSTGRESQL等中小型數據庫。例如使用PHP/PERL + MYSQL/POSTGRESQL設計網(wǎng)站基本上是一個(gè)很常規的做法。但是,當應用軟件管理的數據類(lèi)型較少(特別注意:這并不是說(shuō)需要管理的數據量?。?,數據管理本身不復雜,且對數據操作要求高效率,則由大名鼎鼎的Berkeley(美國加州大學(xué)伯克利分校)開(kāi)發(fā)的 Berkeley DB可能是一個(gè)很明智的選擇。



回頁(yè)首


DB綜述

DB最初開(kāi)發(fā)的目的是以新的HASH訪(fǎng)問(wèn)算法來(lái)代替舊的hsearch函數和大量的dbm實(shí)現(如AT&T的dbm,Berkeley的ndbm,GNU項目的gdbm),DB的第一個(gè)發(fā)行版在1991年出現,當時(shí)還包含了B+樹(shù)數據訪(fǎng)問(wèn)算法。在1992年,BSD UNIX第4.4發(fā)行版中包含了DB1.85版?;旧险J為這是DB的第一個(gè)正式版。在1996年中期,Sleepycat軟件公司成立,提供對DB的商業(yè)支持。在這以后,DB得到了廣泛的應用,當前最新版本是4.3.27。

DB支持幾乎所有的現代操作系統,如LINUX、UNIX、WINDOWS等,也提供了豐富的應用程序接口,支持C、C++、JAVA、PERL、TCL、PYTHON、PHP等。DB的應用十分廣泛,在很多知名的軟件中都能看到其身影。例如參考資料2中作者談到利用DB在LINUX下實(shí)現內核級文件系統;參考資料3中通過(guò)實(shí)際測試數據說(shuō)明DB提高了OPENLDAP的效率。LINUX下的軟件包管理器RPM也使用DB管理軟件包相關(guān)數據,可以使用命令file查看RPM數據目錄/var/lib/rpm下的文件,則有形式如下的輸出:

Dirnames: Berkeley DB (Btree, version 9, native byte-order)
Filemd5s: Berkeley DB (Hash, version 8, native byte-order)

值得注意的是DB是嵌入式數據庫系統,而不是常見(jiàn)的關(guān)系/對象型數據庫,對SQL語(yǔ)言不支持,也不提供數據庫常見(jiàn)的高級功能,如存儲過(guò)程,觸發(fā)器等。



回頁(yè)首


DB的設計思想

DB的設計思想是簡(jiǎn)單、小巧、可靠、高性能。如果說(shuō)一些主流數據庫系統是大而全的話(huà),那么DB就可稱(chēng)為小而精。DB提供了一系列應用程序接口(API),調用本身很簡(jiǎn)單,應用程序和DB所提供的庫在一起編譯成為可執行程序。這種方式從兩方面極大提高了DB的效率。第一:DB庫和應用程序運行在同一個(gè)地址空間,沒(méi)有客戶(hù)端程序和數據庫服務(wù)器之間昂貴的網(wǎng)絡(luò )通訊開(kāi)銷(xiāo),也沒(méi)有本地主機進(jìn)程之間的通訊;第二:不需要對SQL代碼解碼,對數據的訪(fǎng)問(wèn)直截了當。

DB對需要管理的數據看法很簡(jiǎn)單,DB數據庫包含若干條記錄,每一個(gè)記錄由關(guān)鍵字和數據(KEY/VALUE)構成。數據可以是簡(jiǎn)單的數據類(lèi)型,也可以是復雜的數據類(lèi)型,例如C語(yǔ)言中結構。DB對數據類(lèi)型不做任何解釋, 完全由程序員自行處理,典型的C語(yǔ)言指針的"自由"風(fēng)格。如果把記錄看成一個(gè)有n個(gè)字段的表,那么第1個(gè)字段為表的主鍵,第2--n個(gè)字段對應了其它數據。DB應用程序通常使用多個(gè)DB數據庫,從某種意義上看,也就是關(guān)系數據庫中的多個(gè)表。DB庫非常緊湊,不超過(guò)500K,但可以管理大至256T的數據量。

DB的設計充分體現了UNIX的基于工具的哲學(xué),即若干簡(jiǎn)單工具的組合可以實(shí)現強大的功能。DB的每一個(gè)基礎功能模塊都被設計為獨立的,也即意味著(zhù)其使用領(lǐng)域并不局限于DB本身。例如加鎖子系統可以用于非DB應用程序的通用操作,內存共享緩沖池子系統可以用于在內存中基于頁(yè)面的文件緩沖。



回頁(yè)首


DB核心數據結構

數據庫句柄結構DB:包含了若干描述數據庫屬性的參數,如數據庫訪(fǎng)問(wèn)方法類(lèi)型、邏輯頁(yè)面大小、數據庫名稱(chēng)等;同時(shí),DB結構中包含了大量的數據庫處理函數指針,大多數形式為 (*dosomething)(DB *, arg1, arg2, …)。其中最重要的有open,close,put,get等函數。

數據庫記錄結構DBT:DB中的記錄由關(guān)鍵字和數據構成,關(guān)鍵字和數據都用結構DBT表示。實(shí)際上完全可以把關(guān)鍵字看成特殊的數據。結構中最重要的兩個(gè)字段是 void * data和u_int32_t size,分別對應數據本身和數據的長(cháng)度。

數據庫游標結構DBC:游標(cursor)是數據庫應用中常見(jiàn)概念,其本質(zhì)上就是一個(gè)關(guān)于特定記錄的遍歷器。注意到DB支持多重記錄(duplicate records),即多條記錄有相同關(guān)鍵字,在對多重記錄的處理中,使用游標是最容易的方式。

數據庫環(huán)境句柄結構DB_ENV:環(huán)境在DB中屬于高級特性,本質(zhì)上看,環(huán)境是多個(gè)數據庫的包裝器。當一個(gè)或多個(gè)數據庫在環(huán)境中打開(kāi)后,環(huán)境可以為這些數據庫提供多種子系統服務(wù),例如多線(xiàn)/進(jìn)程處理支持、事務(wù)處理支持、高性能支持、日志恢復支持等。

DB中核心數據結構在使用前都要初始化,隨后可以調用結構中的函數(指針)完成各種操作,最后必須關(guān)閉數據結構。從設計思想的層面上看,這種設計方法是利用面向過(guò)程語(yǔ)言實(shí)現面對對象編程的一個(gè)典范。



回頁(yè)首


DB數據訪(fǎng)問(wèn)算法

在數據庫領(lǐng)域中,數據訪(fǎng)問(wèn)算法對應了數據在硬盤(pán)上的存儲格式和操作方法。在編寫(xiě)應用程序時(shí),選擇合適的算法可能會(huì )在運算速度上提高1個(gè)甚至多個(gè)數量級。大多數數據庫都選用B+樹(shù)算法,DB也不例外,同時(shí)還支持HASH算法、Recno算法和Queue算法。接下來(lái),我們將討論這些算法的特點(diǎn)以及如何根據需要存儲數據的特點(diǎn)進(jìn)行選擇。

B+樹(shù)算法:B+樹(shù)是一個(gè)平衡樹(shù),關(guān)鍵字有序存儲,并且其結構能隨數據的插入和刪除進(jìn)行動(dòng)態(tài)調整。為了代碼的簡(jiǎn)單,DB沒(méi)有實(shí)現對關(guān)鍵字的前綴碼壓縮。B+樹(shù)支持對數據查詢(xún)、插入、刪除的常數級速度。關(guān)鍵字可以為任意的數據結構。

HASH算法:DB中實(shí)際使用的是擴展線(xiàn)性HASH算法(extended linear hashing),可以根據HASH表的增長(cháng)進(jìn)行適當的調整。關(guān)鍵字可以為任意的數據結構。

Recno算法: 要求每一個(gè)記錄都有一個(gè)邏輯紀錄號,邏輯紀錄號由算法本身生成。實(shí)際上,這和關(guān)系型數據庫中邏輯主鍵通常定義為int AUTO型是同一個(gè)概念。Recho建立在B+樹(shù)算法之上,提供了一個(gè)存儲有序數據的接口。記錄的長(cháng)度可以為定長(cháng)或不定長(cháng)。

Queue算法:和Recno方式接近, 只不過(guò)記錄的長(cháng)度為定長(cháng)。數據以定長(cháng)記錄方式存儲在隊列中,插入操作把記錄插入到隊列的尾部,相比之下插入速度是最快的。

對算法的選擇首先要看關(guān)鍵字的類(lèi)型,如果為復雜類(lèi)型,則只能選擇B+樹(shù)或HASH算法,如果關(guān)鍵字為邏輯記錄號,則應該選擇Recno或Queue算法。當工作集關(guān)鍵字有序時(shí),B+樹(shù)算法比較合適;如果工作集比較大且基本上關(guān)鍵字為隨機分布時(shí),選擇HASH算法。Queue算法只能存儲定長(cháng)的記錄,在高的并發(fā)處理情況下,Queue算法效率較高;如果是其它情況,則選擇Recno算法,Recno算法把數據存儲為平面文件格式。



回頁(yè)首


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在使用前,應首先初始化,否則編譯可通過(guò)但運行時(shí)報參數錯誤  */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;	/* 首先創(chuàng  )建數據庫句柄 */	ret = db_create(&dbp, NULL, 0);	print_error(ret);		/* 創(chuàng  )建數據庫標志 */	flags = DB_CREATE;    	/* 創(chuàng  )建一個(gè)名為single.db的數據庫,使用B+樹(shù)訪(fǎng)問(wèn)算法,本段代碼演示對簡(jiǎn)單數據類(lèi)型的處理 */	ret = dbp->open(dbp, NULL, "single.db", NULL, DB_BTREE, flags, 0); 	print_error(ret);	init_DBT(&key, &data);		/* 分別對關(guān)鍵字和數據賦值和規定長(cháng)度 */	key.data = fruit;	key.size = strlen(fruit) + 1;	data.data = &number;	data.size = sizeof(int);	/* 把記錄寫(xiě)入數據庫中,不允許覆蓋關(guān)鍵字相同的記錄 */	ret = dbp->put(dbp, NULL, &key, &data,DB_NOOVERWRITE); 	print_error(ret);	/* 手動(dòng)把緩存中的數據刷新到硬盤(pán)文件中,實(shí)際上在關(guān)閉數據庫時(shí),數據會(huì )被自動(dòng)刷新 */dbp->sync();	init_DBT(&key, &data);	key.data = fruit;	key.size = strlen(fruit) + 1;		/* 從數據庫中查詢(xún)關(guān)鍵字為apple的記錄 */	ret = dbp->get(dbp, NULL, &key, &data, 0);	print_error(ret);	/* 特別要注意數據結構DBT的字段data為void *型,所以在對data賦值和取值時(shí),要做必要的類(lèi)型轉換。 */	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;    	/* 創(chuàng  )建一個(gè)名為complex.db的數據庫,使用HASH訪(fǎng)問(wèn)算法,本段代碼演示對復雜數據結構的處理 */	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); }



回頁(yè)首


DB游標使用范例

游標是依賴(lài)于數據庫句柄的,應用程序代碼框架如下:

	/* 定義一個(gè)游標變量 */	DBC * cur;	/* 首先打開(kāi)數據庫,再打開(kāi)游標 */	dbp->open(dbp, ……);	dbp->cursor(dbp, NULL, &cur, 0);		/* do something with cursor */	/* 首先關(guān)閉,在關(guān)閉數據庫 */	cur->c_close(cur);	dbp->close(dbp, 0);	

在游標打開(kāi)后,可以以多種方式遍歷特定記錄。

		Memset(&key, 0, sizeof(DBT));	Memset(&data, 0, sizeof(DBT));	/* 因為KEY和DATA為空,則游標遍歷整個(gè)數據庫記錄 */	While((ret = cur->c_get(cur, &key, &data, DB_NEXT)) == 0)	{		/* do something with key and data */	}	

當想查詢(xún)特定關(guān)鍵字對應的記錄,則應對關(guān)鍵字賦值,并把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 */	}	

游標的作用還有很多,如查詢(xún)多重記錄,插入/修改/刪除記錄等。



回頁(yè)首


DB環(huán)境使用范例

本文前面已說(shuō)明環(huán)境是DB數據庫的包裝器,提供多種高級功能。應用程序代碼框架如下:

		/* 定義一個(gè)環(huán)境變量,并創(chuàng  )建 */	DB_ENV *dbenv;	db_env_create(&dbenv, 0);	/* 在環(huán)境打開(kāi)之前,可調用形式為dbenv->set_XXX()的若干函數設置環(huán)境 */	/* 通知DB使用Rijndael加密算法(參考資料4)對數據進(jìn)行處理 */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");	/* 打開(kāi)數據庫環(huán)境,注意后四個(gè)標志分別指示DB啟動(dòng)日志、加鎖、緩存、事務(wù)處理子系統 */	dbenv->open(dbenv,home,DB_CREATE|DB_INIT_LOG|DB_INIT_LOCK| DB_INIT_MPOOL|DB_INIT_TXN, 0);		/* 在環(huán)境打開(kāi)后,則可以打開(kāi)若干個(gè)數據庫,所有數據庫的處理都在環(huán)境的控制和保護中。注意db_create函數的第二個(gè)參數是環(huán)境變量 */db_create(&dbp1, dbenv, 0);dbp1->open(dbp1, ……);db_create(&dbp2, dbenv, 0);dbp1->open(dbp2, ……);	/* do something with the database */	/* 最后首先關(guān)閉打開(kāi)的數據庫,再關(guān)閉環(huán)境 */	dbp2->close(dbp2, 0);	dbp1->close(dbp1, 0);	dbenv->close(dbenv, 0);	



回頁(yè)首


DB軟件的安裝和編譯

從DB的官方站點(diǎn)http://www.sleepycat.com/下載最新的軟件包db-4.3.27.tar.gz,解壓到工作目錄,進(jìn)入該目錄,依次執行下列三條命令即可。

../dist/configuremakemake install

執行make uninstall,則可卸載已安裝的DB軟件。

DB缺省把庫和頭文件安裝在目錄/usr/local/BerkeleyDB.4.3/下,使用gcc test.c -ggdb -I/usr/local/BerkeleyDB.4.3/include/ -L/usr/local/BerkeleyDB.4.3/lib/ -ldb -lpthread就可正確編譯程序。如果讀者的測試主機操作系統為RED HAT9,則安裝的DB版本可能是4.0。特別要注意到這兩個(gè)版本的庫是不兼容的。例如打開(kāi)數據庫函數DB->open(),在4.0版本中入參為6個(gè),而在4.3版中則為7個(gè)(可自行比較兩個(gè)庫的頭文件db.h中DB->open函數的定義)。因為在DB相關(guān)的應用程序中,open函數基本上都是要執行的,所以如果函數和版本不匹配,編譯肯定會(huì )出錯。當然,編譯完成后,可以使用命令ldd查看庫的依賴(lài)關(guān)系。



回頁(yè)首


總結

DB是一個(gè)具有工業(yè)強度的嵌入式數據庫系統,數據處理的效率很高。DB功能的穩定性歷經(jīng)時(shí)間的考驗,在大量應用程序中使用便是明證??梢韵胍?jiàn),在同等代碼質(zhì)量的條件下,軟件的BUG數和代碼的長(cháng)度是成正比的,相對幾十兆、幾百兆大型數據庫軟件,DB的只有不到500K的大??!

從實(shí)現功能上看,DB是輕量級數據庫系統,或可稱(chēng)為"極" 輕量級數據庫系統。但是,我認為不能因此而心存輕視之意,所謂"尺有所短,寸有所長(cháng)",以絕對角度比較工具之間的好壞是沒(méi)有什么意義的,關(guān)鍵在于對工具的選擇和運用(似乎可以參考一下極限編程的思想)。也許,正確的"表達范式"應該是:在當前應用背景下,選擇這種工具是最合適的。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
BerkeleyDB庫簡(jiǎn)介
Berkeley DB 中常用 SQL 函數使用指南
berkeley db效率如何
學(xué)習Berkeley DB
Berkeley DB——Cursor
BerkeleyDB 測試
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久