BerkeleyDB 多索引查询.pdf
文本预览下载声明
CCoolliinnOOrrgg
BBeerrkkeelleeyyDDBB 多多索索引引查查询询
分类: C++编程 LinuxUnix 2 13- 9-26 14:22 143人阅读 评论 ( ) 收藏 举报
由于性能原 因,我们打算将关系型数据库转移到内存数据库中;在 内存数据库产品的选型中,我们
确 的候选对象有Redis和Berkeley DB;
Redis查询效率不错 ,并且支持丰富的数据存储结构 ,但不支持多索引,这样对于比较复杂的sql移
植可能会造成数据膨胀 ;Berkeley DB只支持简单的Key/Value, 但支持多索引查询 ,对我们 目前
的应用来说 ,移植起来更有优势 ;
下面我们看看 ,如何为DB建立二级索引;
还是用例子来说明:
一张表中记录学生的信息 ;每个学生有个唯一的ID,这个id通常就是表的主键 ;
现在 ,我们希望通过学生的last_name来查询 ,这就需要建立二级索引;
注 :用词约 :
* 本文提到的 “数据库”是指Berkeley DB的database,相当于关系数据库的一个表 。
作为SQL的常用表 :
CREATE TABLE students(student_id CHAR (4) NOT NULL,lastname CHAR (15),
firstname CHAR (15), PRIMARY KEY (student_id)); CREATE INDEX lname ON students(lastname);
在Berkeley DB中,就是 义为如下结构 :
struct student_record {
char student_id[4];
char last_name[15];
char first_name[15];
};
void second()
{
DB *d p, *sd p;
int ret;
/* 创建/打开第一个数据库*/
if ((ret = d _create(d p, d env, 0)) != 0)
handle_error(ret);
if ((ret = d p-open(d p, NULL,
students.d , NULL, DB_BTREE, DB_CREATE, 0600)) != 0)
handle_error(ret);
/* 打开第二个数据库,注意,需要申明这个库支持重复记录,因为学生的last_name不是唯一的,是可能重复的*/
if ((ret = d _create(sd p, d env, 0)) != 0)
handle_error(ret);
if ((ret = sd p-set_flags(sd p, DB_DUP | DB_DUPSORT)) != 0)
handle_error(ret);
if ((ret = sd p-open(sd p, NULL,
lastname.d , NULL, DB_BTREE, DB_CREATE, 0600)) != 0)
handle_error(ret);
1
/* 将二级个库关联到第一个库上 . 注:getname是提取key函数*/
if ((ret = d p-associate(d p, NULL, sd p, getname, 0)) != 0)
handle_error(ret);
}
/*
* getname -- 从第一个库的键值对中提取第二个库的key(即 last name)
*/
int getname(DB *secondary, const DBT *pkey, const DBT *pdata, DBT *skey)
{
/*
* 这里第二个key是数据的简单结构,所以并不需要做其它的工作,直接返回就完事。
* 如果第二个key是需要从复杂记录中提取出来再组建,这个用户函数可能需要做分配空间和copy数据的工作;在这种情况
memset(skey, 0, sizeof(DBT
显示全部