国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 網(wǎng)絡(luò)通信 > 正文

開源嵌入式數(shù)據(jù)庫BerkeleyDB(2)

2019-11-04 21:03:16
字體:
供稿:網(wǎng)友

  應用統(tǒng)一的編程接口
  使用Berkeley DB提供的函數(shù)來進行數(shù)據(jù)庫的訪問和治理并不復雜,在大多數(shù)場合下只需按照統(tǒng)一的接口標準進行調(diào)用就可以完成最基本的操作。
  
  打開數(shù)據(jù)庫
  打開數(shù)據(jù)庫通常要分兩步進行:首先調(diào)用db_create()函數(shù)來創(chuàng)建DB結(jié)構(gòu)的一個實例,然后再調(diào)用DB->open()函數(shù)來完成真正的打開操作。Berkeley DB將所有對數(shù)據(jù)庫的操作都封裝在名為DB的結(jié)構(gòu)中。db_create()函數(shù)的作用就是創(chuàng)建一個該結(jié)構(gòu),其原型如下所示:
  typedef strUCt__db DB;
  int db_create(DB **dbp, DB_ENV *dbenv, u_int32_t flags);
  將磁盤上保存的文件作為數(shù)據(jù)庫打開是由DB->open()函數(shù)來完成的,其原型如下所示:
  int DB->open(DB *db, DB_TXN *txnid, const char *file,
  const char *database, DBTYPE type, u_int32_t flags, int mode);
  下面這段代碼示范了如何創(chuàng)建DB對象句柄及如何打開數(shù)據(jù)庫文件:
  #include <sys/types.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <db.h>
  #define DATABASE "demo.db"
  /* 以下程序代碼的程序頭同此*/
  int main()
  { DB *dbp;
   int ret;
   if ((ret = db_create(&dbp, NULL, 0)) != 0) {
   f   exit (1);
   }
   if ((ret = dbp->open(dbp, NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
   dbp->err(dbp, ret, "%s", DATABASE);
   exit (1);
   }
  }
  代碼首先調(diào)用db_create()函數(shù)來創(chuàng)建一個DB對象句柄。變量dbp在調(diào)用成功后將成為數(shù)據(jù)庫句柄,通過它可以完成對底層數(shù)據(jù)庫的配置或訪問。接下去調(diào)用DB->open()函數(shù)打開數(shù)據(jù)庫文件,參數(shù)“DATABASE”指明對應的磁盤文件名為demo.db;參數(shù)“DB_BTREE”表示數(shù)據(jù)庫底層使用的數(shù)據(jù)結(jié)構(gòu)是B樹;而參數(shù)“DB_CREATE”和“0664”則表明當數(shù)據(jù)庫文件不存在時創(chuàng)建一個新的數(shù)據(jù)庫文件,并且將該文件的屬性值設(shè)置為0664。
  
  錯誤處理是在打開數(shù)據(jù)庫時必須的例行檢查,這可以通過調(diào)用DB->err()函數(shù)來完成。其中參數(shù)“ret”是在調(diào)用Berkeley DB函數(shù)后返回的錯誤代碼,其余參數(shù)則用于顯示結(jié)構(gòu)化的錯誤信息。
  
  添加數(shù)據(jù)
  向Berkeley DB數(shù)據(jù)庫中添加數(shù)據(jù)可以通過調(diào)用DB->put()函數(shù)來完成,其原型如下所示:
  int DB->put(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags);
  下面這段代碼示范了如何向數(shù)據(jù)庫中添加新的數(shù)據(jù):
  
  int main()
  { DB *dbp;
   DBT key, data;
   int ret;
   if ((ret = db_create(&dbp, NULL, 0)) != 0) {
   fprintf(stderr, "db_create: %s/n", db_strerror(ret));
   exit (1);
   }
   if ((ret = dbp->open(dbp,
   NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
   dbp->err(dbp, ret, "%s", DATABASE);
   exit (1);
   }
   memset(&key, 0, sizeof(key));
   memset(&data, 0, sizeof(data));
   key.data = "sport";
   key.size = sizeof("sport");
   data.data = "football";
   data.size = sizeof("football");
   if ((ret = dbp->put(dbp, NULL, &key, &data, 0)) == 0)
   printf("db: %s: key stored./n", (char *)key.data);
   else
   dbp->err(dbp, ret, "DB->put");
  }
  代碼首先聲明了兩個DBT結(jié)構(gòu)變量,并分別用字符串“sport”和“football”進行填充。它們隨后作為要害字和數(shù)據(jù)傳遞給用來添加數(shù)據(jù)的DB->put()函數(shù)。DBT結(jié)構(gòu)幾乎會在所有同數(shù)據(jù)訪問相關(guān)的函數(shù)中被用到。
  
  在向數(shù)據(jù)庫中添加數(shù)據(jù)時,假如給定的要害字已經(jīng)存在,大多數(shù)應用會對于已經(jīng)存在的數(shù)據(jù)采用覆蓋原則。也就是說,假如數(shù)據(jù)庫中已經(jīng)保存了一個“sport/basketball”對,再次調(diào)用DB->put()函數(shù)添加一個“sport/football”對,那么先前保存的那些數(shù)據(jù)將會被覆蓋。但Berkeley DB答應在調(diào)用DB->put()函數(shù)時指定參數(shù)“DB_NOOVERWRITE”,聲明不對數(shù)據(jù)庫中已經(jīng)存在的數(shù)據(jù)進行覆蓋,其代碼如下:
  
  if ((ret = dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE)) == 0)
   printf("db: %s: key stored./n", (char *)key.data);
  else
   dbp->err(dbp, ret, "DB->put");
  一旦給出“DB_NOOVERWRITE”標記,假如DB->put()函數(shù)在執(zhí)行過程中發(fā)現(xiàn)給出的要害字在數(shù)據(jù)庫中已經(jīng)存在了,就無法成功地把該Key/Data對添加到數(shù)據(jù)庫中,于是將返回錯誤代號“DB_KEYEXIST”。
  
  檢索數(shù)據(jù)
  從Berkeley DB數(shù)據(jù)庫中檢索數(shù)據(jù)可以通過調(diào)用DB->get()函數(shù)來完成,其原型如下所示:
  
  int DB->get(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags);
  下面這段代碼示范了如何從數(shù)據(jù)庫中檢索出所需的數(shù)據(jù):
  int main()
  { DB *dbp;
   DBT key, data;
   int ret;
   if ((ret = db_create(&dbp, NULL, 0)) != 0) {
   fprintf(stderr, "db_create: %s/n", db_strerror(ret));
   exit (1);
   }
   if ((ret = dbp->open(dbp,
   NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
   dbp->err(dbp, ret, "%s", DATABASE);
   exit (1);
   }
   memset(&key, 0, sizeof(key));
   memset(&data, 0, sizeof(data));
   key.data = "sport";
   key.size = sizeof("sport");
   if ((ret = dbp->get(dbp, NULL, &key, &data, 0)) == 0)
   printf("db: %s: key retrieved: data was %s./n",
   (char *)key.data, (char *)data.data);
   else
   dbp->err(dbp, ret, "DB->get");
  }
  代碼同樣聲明了兩個DBT結(jié)構(gòu)變量,并且調(diào)用memset()函數(shù)對它們的內(nèi)容清空。雖然Berkeley DB并不強制要求在進行數(shù)據(jù)操作之前先清空它們,但出于提高代碼質(zhì)量考慮還是建議先進行清空操作。在進行數(shù)據(jù)檢索時,對DB->get()函數(shù)的返回值進行處理是必不可少的,因為它攜帶著檢索操作是否成功完成等信息。下面列出的是DB->get()函數(shù)的返回值:
  
  ◆ 0 函數(shù)調(diào)用成功,指定的要害字被找到;
  
  ◆ DB_NOTFOUND 函數(shù)調(diào)用成功,但指定的要害字未被找到;
  
  ◆大于0 函數(shù)調(diào)用失敗,可能出現(xiàn)了系統(tǒng)錯誤。
  
  刪除數(shù)據(jù)
  從Berkeley DB數(shù)據(jù)庫中刪除數(shù)據(jù)可以通過調(diào)用DB->del()函數(shù)來完成,其原型如下所示:
  
  int DB->del(DB *db, DB_TXN *txnid, DBT *key, u_int32_t flags);
  下面這段代碼示范了如何從數(shù)據(jù)庫中刪除數(shù)據(jù):
  
  int main()
  { DB *dbp;
   DBT key;
   int ret;
   if ((ret = db_create(&dbp, NULL, 0)) != 0) {
   fprintf(stderr, "db_create: %s/n", db_strerror(ret));
   exit (1);
   }
   if ((ret = dbp->open(dbp,
   NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
   dbp->err(dbp, ret, "%s", DATABASE);
   exit (1);
   }
   memset(&key, 0, sizeof(key));
   key.data = "sport";
   key.size = sizeof("sport");
   if ((ret = dbp->del(dbp, NULL, &key, 0)) == 0)
   printf("db: %s: key was deleted./n", (char *)key.data);
   else
   dbp->err(dbp, ret, "DB->del");
  }
  刪除數(shù)據(jù)只需給出相應的要害字,不用指明與之對應的數(shù)據(jù)。
  
  關(guān)閉數(shù)據(jù)庫
  對于一次完整的數(shù)據(jù)庫操作過程來說,關(guān)閉數(shù)據(jù)庫是不可或缺的一個環(huán)節(jié)。這是因為Berkeley DB需要依靠于系統(tǒng)底層的緩沖機制,也就是說只有在數(shù)據(jù)庫正常關(guān)閉的時候,修改后的數(shù)據(jù)才有可能全部寫到磁盤上,同時它所占用的資源也才能真正被全部釋放。關(guān)閉數(shù)據(jù)庫的操作是通過調(diào)用DB->close()函數(shù)來完成的,其原型如下所示:
  
  int DB->close(DB *db, u_int32_t flags);
  下面這段代碼示范了如何在需要的時候關(guān)閉數(shù)據(jù)庫:
  
  int main()
  { DB *dbp;
   DBT key, data;
   int ret, t_ret;
   if ((ret = db_create(&dbp, NULL, 0)) != 0) {
   fprintf(stderr, "db_create: %s/n", db_strerror(ret));
   exit (1);
   }
   if ((ret = dbp->open(dbp,
   NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
   dbp->err(dbp, ret, "%s", DATABASE);
   goto err;
   }
   memset(&key, 0, sizeof(key));
   memset(&data, 0, sizeof(data));
   key.data = "sport";
   key.size = sizeof("sport");
   if ((ret = dbp->get(dbp, NULL, &key, &data, 0)) == 0)
   printf("db: %s: key retrieved: data was %s./n",
   (char *)key.data, (char *)data.data);
   else
   dbp->err(dbp, ret, "DB->get");
   if ((t_ret = dbp->close(dbp, 0)) != 0 && ret == 0)
   ret = t_ret;
   exit(ret);
  }
  小結(jié)
  Berkeley DB這個嵌入式數(shù)據(jù)庫系統(tǒng)使用非常簡單。它沒有數(shù)據(jù)庫服務(wù)器的概念,也不需要復雜的SQL語句,所有對數(shù)據(jù)的操作和治理都可以


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 德清县| 溧水县| 宝应县| 大新县| 肃南| 当雄县| 苏尼特右旗| 湘乡市| 南和县| 新干县| 罗定市| 黎平县| 徐闻县| 高州市| 延吉市| 华阴市| 班玛县| 鹤山市| 通州区| 卢氏县| 嘉峪关市| 朝阳区| 庐江县| 朝阳县| 孝昌县| 斗六市| 太谷县| 稷山县| 台北市| 甘肃省| 绥阳县| 哈巴河县| 故城县| 波密县| 北海市| 麦盖提县| 江山市| 信丰县| 民县| 潍坊市| 三都|