dbm与mysql_DBM数据库 | 学步园
1. dbm數(shù)據(jù)庫
dbm數(shù)據(jù)庫適合于儲存相對比較靜態(tài)的索引化數(shù)據(jù),是一個索引化得文件存儲系統(tǒng)。它的優(yōu)點是非常容易被編譯進一個可發(fā)布的二進制可執(zhí)行程序,因為它無需安裝獨立的服務(wù)器,而且即使它需要的底層文件還未安裝,也不會有什么危險。
dbm數(shù)據(jù)庫允許你通過使用索引來存儲可變長數(shù)據(jù)結(jié)構(gòu),然后通過索引或簡單的順序掃描數(shù)據(jù)庫來檢索結(jié)構(gòu)。Dbm數(shù)據(jù)庫適用于處理那些被頻繁訪問但卻很少被更新的數(shù)據(jù),因為它創(chuàng)建數(shù)據(jù)項時非常慢,而檢索時非常快。
2. dbm例程
dbm工具也是由頭文件和庫文件組成,而且?guī)煳募仨氃诔绦蚓幾g時鏈接進來。庫文件被稱為dbm,因此鏈接它時需要加上選項-ldbm(-lgdbm)。其頭文件是ndbm.h。
dbm數(shù)據(jù)庫的基本元素是需要存儲的數(shù)據(jù)塊以及與它關(guān)聯(lián)的在檢索數(shù)據(jù)庫時用作關(guān)鍵字的數(shù)據(jù)塊。每個dbm數(shù)據(jù)庫必須有一個針對每個要存儲的數(shù)據(jù)塊的唯一關(guān)鍵字。規(guī)范中允許把關(guān)鍵字/數(shù)據(jù)對的長度限制為1023個字節(jié),但通常不限制。關(guān)鍵字的取值被用作存儲數(shù)據(jù)的索引。
頭文件ndbm.h定義了一個名為datum的新數(shù)據(jù)類型,該類型確切內(nèi)容依賴于具體實現(xiàn),但它至少包括以下成員:
void *dptr;
size_t dsize;
datum是一個用typedef語句定義的類型。在ndbm.h中還定義了一個DBM類型,這是一個用來訪問數(shù)據(jù)庫的結(jié)構(gòu),其作用和用來訪問文件的FILE結(jié)構(gòu)很相似。
當(dāng)使用dbm庫時,要想引用一個數(shù)據(jù)塊,必須聲明一個datum類型的變量,將成員dptr指向數(shù)據(jù)的起始點,并把成員dsize設(shè)為數(shù)據(jù)的長度。無論是待存儲的數(shù)據(jù)還是用來訪問它的索引都總是通過一個datum類型來引用的。
當(dāng)打開一個dbm數(shù)據(jù)庫時,將創(chuàng)建兩個物理文件,它們的后綴分別是.gag和.dir,而僅僅返回一個dbm指針,它被用來訪問這兩個文件。這兩個文件決不應(yīng)該被直接讀寫,對它們的訪問一定要通過dbm例程來進行。
dbm數(shù)據(jù)庫工作在非結(jié)構(gòu)化的二進制數(shù)據(jù)塊基礎(chǔ)上。
3. dbm訪問函數(shù)
#include
DBM *dbm_open(const char *filename, int
flags, mode_t file_mode);
int dbm_store(DBM *dbdes,? datum key, datum data, int store_mode);
datum dbm_fetch(DBM *dbdes, datum key);
void dbm_close(DBM *dbdes);
int dbm_delete(DBM *dbdes, datum key);
int dbm_error(DBM *dbdes);
int dbm_clearerr(DBM *dbdes);
datum dbm_firstkey(DBM *dbdes);
datum dbm_nextkey(DBM *dbdes);
3.1. db_open函數(shù)
這個函數(shù)用來打開一個已經(jīng)存在或創(chuàng)建一個新數(shù)據(jù)庫,filename參數(shù)是一個基本文件名稱,不包括.dir或.pag后綴。
第二個參數(shù)控制數(shù)據(jù)庫的讀、寫或讀/寫權(quán)限。如果你是創(chuàng)建一個新的數(shù)據(jù)庫,這些標(biāo)志必須與O_CREAT進行二進制或來允許文件被創(chuàng)建。
第三個參數(shù)指定被創(chuàng)建文件的初始權(quán)限。
dbm_open返回一個DBM類型的指針。它被用于所有后續(xù)對數(shù)據(jù)庫的訪問。如果失敗,返回(DBM*)0。
3.2. dbm_store函數(shù)
該函數(shù)是把數(shù)據(jù)存儲到數(shù)據(jù)庫中。為了定義我們希望存儲的數(shù)據(jù)和用來引用它的索引,必須設(shè)置兩個datum類型:一個用于索引,一個用于實際數(shù)據(jù)。最后一個store_mode用于控制當(dāng)試圖以一個已有的關(guān)鍵字來存儲數(shù)據(jù)時發(fā)生地情況。如果它被設(shè)置為dbm_insert,存儲操作將失敗并且返回1。如果它被設(shè)置為dem_replace,新數(shù)據(jù)將覆蓋已有數(shù)據(jù)并且返回0。
當(dāng)發(fā)生其他錯誤時,dbm_store返回一個負值。
3.3. dbm_fetch函數(shù)
該函數(shù)用于從數(shù)據(jù)庫中獲取數(shù)據(jù)。它使用一個前面dbm_open調(diào)用返回的指針和一個指向關(guān)鍵字的datum類型的結(jié)構(gòu)。它將返回一個datum類型的結(jié)構(gòu)。如果在數(shù)據(jù)庫中找到關(guān)聯(lián)這個關(guān)鍵字的數(shù)據(jù),返回的datum結(jié)構(gòu)的dptr和dsize成員的值將被設(shè)為相應(yīng)的數(shù)據(jù)的值。如果沒有找到關(guān)鍵字,dptr將被設(shè)置為null。
3.4. dbm_close函數(shù)
該函數(shù)關(guān)閉用dbm_open打開的數(shù)據(jù)庫。
3.5. dbm_delete函數(shù)
該函數(shù)用于從數(shù)據(jù)庫中刪除數(shù)據(jù)項。成功返回0。
3.6. Dbm_error函數(shù)
該函數(shù)用于簡單的測試數(shù)據(jù)庫中是否有錯誤發(fā)生,如果沒有就返回0。
3.7. Dbm_clearerr函數(shù)
該函數(shù)用于清除數(shù)據(jù)庫中所有已經(jīng)被置位的錯誤條件標(biāo)志。
3.8. dbm_firstkey函數(shù)和dbm_nextkey函數(shù)
這兩個函數(shù)成對使用,用于對數(shù)據(jù)庫中的所有關(guān)鍵字進行掃描。
4. 實例
#include
#include
#include
#include
#include
#include
#define CONFIG_FILE "/root/dbm/access"
#define USER_AMOUNT 3
typedef struct tagUserAccess
{
char username[32];
int access;
} USER_ACCESS_S;
int main()
{
USER_ACCESS_S user_to_store[USER_AMOUNT];
USER_ACCESS_S user_to_retrieved;
char key_to_use[16];
int i, result;
datum key_datum;
datum data_datum;
DBM * dbm_des;
//創(chuàng)建一個數(shù)據(jù)庫用來讀寫
dbm_des = dbm_open(CONFIG_FILE, O_RDWR | O_CREAT, 0666);
if(!dbm_des)
{
printf("Failed to open database/n");
exit(EXIT_FAILURE);
}
//初始化待存儲的數(shù)據(jù)
memset(user_to_store, 0, sizeof(user_to_store));
for(i = 0; i < USER_AMOUNT; i++)
{
snprintf(user_to_store[i].username, sizeof(user_to_store[i].username),"%s%d","user",i);
user_to_store[i].access = i;
}
//存儲數(shù)據(jù)
for(i = 0; i < USER_AMOUNT; i++)
{
//用戶ID標(biāo)示關(guān)鍵字
snprintf(key_to_use, sizeof(key_to_use),"%d",1000 + i);
key_datum.dptr = (void*)key_to_use;
key_datum.dsize = strlen(key_to_use);
data_datum.dptr = (void *)&user_to_store[i];
data_datum.dsize = sizeof(USER_ACCESS_S);
result = dbm_store( dbm_des, key_datum, data_datum, DMB_REPLACE);
if(0 != result)
{
printf("dbm_store:Failed to store the data/n");
exit(EXIT_FAILURE);
}
}
//獲取新存入的數(shù)據(jù)
snprintf(key_to_use, sizeof(key_to_use),"%d",1000 + 1);
key_datum.dptr = (void*)key_to_use;
key_datum.dsize = strlen(key_to_use);
data_datum = dbm_fetch(dbm_des, key_datum);
if(data_datum.dptr)
{
memcpy(&user_to_retrieved, data_datum.dptr, data_datum.dsize);
printf("Retrieved:username = %s, acces=%d/n", user_to_retrieved.username, user_to_retrieved.access);
}
else
{
printf("dbm_fetch:Failed to retrieve the data/n");
}
//關(guān)閉數(shù)據(jù)庫
dbm_close(dbm_des);
exit(EXIT_SUCCESS);
}
總結(jié)
以上是生活随笔為你收集整理的dbm与mysql_DBM数据库 | 学步园的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用计算机求a的平方根的顺序,算术平方根练
- 下一篇: dbm与mysql区别_dbm数据库