lmdb是一款开源的高效快速的内存映射数据库,C语言编写,基于B+树索引,支持MVCC事务处理,是一个嵌入到进程的数据库,不需要单独的数据库进程,在代码中使用lmdb的接口即可方便地实现读写lmdb数据库。
与几年前我曾经使用过的BerkelyDB有些小关系,这个数据库可支持多进程/线程的读写,
下载并编译、安装
git clone https://github.com/LMDB/lmdb.git
cd lmdb/libraries/liblmdb
make
sudo make install
示例代码,main.cpp:
#include <iostream>
#include <string>
#include <chrono>
#include "lmdb.h"
using namespace std;
int main(int argc, char* argv[]){
int res;
MDB_env *env;
MDB_dbi dbi;
MDB_val key, data;
MDB_txn *txn;
MDB_cursor *cursor;
//init lmdb
cout<<"lmdb version:"<<mdb_version(0, 0, 0)<<endl;
res = mdb_env_create(&env);
if(res){
cout<<"mdb_env_create error,error:"<<mdb_strerror(res)<<endl;
return -1;
}
res = mdb_env_open(env, "./lmdb_test", 0, 0644);
if(res){
cout<<"mdb_env_open error,detail:"<< mdb_strerror(res)<<endl;
return -1;
}
res = mdb_txn_begin(env, NULL, 0, &txn);
if(res){
cout<<"mdb_txn_begin error,detail:"<< mdb_strerror(res)<<endl;
return -1;
}
res = mdb_dbi_open(txn, NULL, 0, &dbi);
if(res){
cout<<"mdb_dbi_open error,detail:"<< mdb_strerror(res)<<endl;
return -1;
}
do{
//write data to lmdb
for(int i=0;i<10;++i){
MDB_val key, data;
int value=i*i;
key.mv_size =sizeof(i);
key.mv_data =(void*)&i;
data.mv_size = sizeof(value);
data.mv_data = (void*)&value;
res = mdb_put(txn, dbi, &key, &data, 0);
}
res = mdb_txn_commit(txn);
if (res) {
cerr<<"mdb_txn_commit:"<< res<<":"<< mdb_strerror(res)<<endl;
break;
}
res = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
res = mdb_cursor_open(txn, dbi, &cursor);
//read data from lmdb
while ((res = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
int r_key=*(int *)key.mv_data;
int r_value=*(int *)data.mv_data;
cout<<"<"<<r_key<<","<<r_value<<">"<<endl;
}
mdb_cursor_close(cursor);
mdb_txn_abort(txn);
}while(0);
//free
mdb_dbi_close(env, dbi);
mdb_env_close(env);
return 0;
}
编译代码:
g++ -Wall -g main.cpp -o main -llmdb
在main程序所在目录,创建数据库目录testdb, 执行main程序(如果遇到找不到lmdb.so的错误, export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib):
./main
输出:
以上示例代码简单展示了lmdb库的用法,更详细的api使用请参考lmdb官方文档。