1. 程式人生 > >bind資料儲存—Berkeley DB

bind資料儲存—Berkeley DB

這裡還需要講一個資訊,就是bind的資料是通過怎樣的方式組織起來的,Bind通過Berkeley DB的方式組織資料的,它是一個開源的檔案資料庫軟體,介於關係資料庫和記憶體資料庫之間,使用方式和記憶體資料庫類似,提供一系列可以直接訪問資料庫的函式,它可以儲存任意型別的鍵值對

 

它的結構:它內部支援B+樹,支援hash等演算法

核心資料結構

資料庫環境控制代碼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中屬於高階特性,本質上看,環境是多個數據庫的包裝器。當一個或多個數據庫在環境中開啟後,環境可以為這些資料庫提供多種子系統服務,例如多線/程序處理支援、事務處理支援、高效能支援、日誌恢復支援等。

最簡單的一個例子:
//宣告一個數據
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;

DB *dbp;
DBT key, data;
ret = db_create(&dbp, NULL, 0);
/* 建立一個名為single.db的資料庫,使用B+樹訪問演算法,本段程式碼演示對簡單資料型別的處理 */
ret = dbp->open(dbp, NULL, "single.db", NULL, DB_BTREE, flags, 0);
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);
/* 手動把快取中的資料重新整理到硬碟檔案中,實際上在關閉資料庫時,資料會被自動重新整理 */
dbp->sync();
或者儲存這樣的資料:
key.size = sizeof(int);
key.data = &(cust.c_id);
data.size = sizeof(CUSTOMER);
data.data = &cust;

遊標的使用:
/* 定義一個遊標變數 */
  DBC * cur;
  /* 首先開啟資料庫,再開啟遊標 */
  dbp->open(dbp, ……);
  dbp->cursor(dbp, NULL, &cur, 0);
  /* do something with cursor */
  /* 首先關閉,在關閉資料庫 */
  cur->c_close(cur);
  dbp->close(dbp, 0);
在遊標開啟後,可以以多種方式遍歷特定記錄。
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 */
  }
環境使用
環境是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);