Berkeley DB 课程设计答辩

Download Report

Transcript Berkeley DB 课程设计答辩

Berkeley DB
课程设计答辩
张天意 周冰楠
9班第1小组
介绍





基本数据结构和函数
B-Tree设计与逻辑实现
UB-Tree设计与逻辑实现
性能分析
感悟和结语
实验环境和性能测试指标

实验环境






计算机:Intel® Core™ i5 CPU / 4GB RAM
操作系统:Ubuntu 12.03
编译器:gcc
程序语言:C
已有源代码:BerkeleyDB 1.86
性能测试指标



建立的索引大小
建立索引的时间
查询时I/O读写情况
Intel,Intel Core 是英特尔公司在美国和/或其他国家和地区的商标。
Berkeley DB 课程设计答辩
基本数据结构和函数
Berkeley DB 1.86 数据结构
数据结构名
描述与用途
定义位置
DB
数据库定义
DB.h
DBT
B-Tree节点结构,包括key,data均是此结构
DB.h
EPG
记录寻址结构,包含pgno 和index
btree.h
EPGNO
记录寻址结构,包含pgno 指针和index
btree.h
BTREEINFO
B树建立时候系列参数,包括缓冲大小、页数、支持重
复与否等
btree.h
BTREE
保存在内存中的树结构,可调用internal中系列函数
btree.h
PAGE
B-Tree中页属性结构,包含页号、指针等
btree.h
Berkeley DB 1.86 函数
函数名
功能
函数名
功能
dbopen
打开数据库
__bt_first
找到指定键值的
第一条记录
dbclose
关闭数据库
__bt_seqset
从指定键值顺序
访问
__bt_seq
顺序访问 B 树
__bt_seqadv
提前进行顺序访
问
__bt_ret
获取指定记录
的信息
mpool_put
获取页面基本信
息
__bt_put
往btree
插入数据
__bt_defcmp
比较key大小
在实验过程中,还调用了string系列函数,以及
atoi,atof,sscanf 等库函数。
Berkeley DB 课程设计答辩
B-TREE设计与逻辑实现
B-Tree设计与实现
设计思路
查询
条件
index2
index1
lineitem.tbl

根据属性shipdate对lineitem表建立<key,data> B-Tree索引;
在(1)基础上,根据属性discount对lineitem表建立<key,rid>索引;
完成范围查询。

本质是建立两个索引,其中一个是“索引的索引”。


共同的问题



如何利用Berkeley代码?
Berkeley代码有几大部分?
哪些代码可以用?
我需要实现/解决哪些问题?
Berkeley中哪些部分是和这个问题相关的?
还需要添加哪些部分?
从需求出发,按需调配相关模块
建立B-Tree索引Index1
需求分析

如何从lineitem里逐行读取条目,并分离出需要
的key和data部分?
sscanf(char *buffer,char *format,[argument ]...)

分离后的key和data应该如何插入?
来源:dbtest
dbp->put(dbp, &key, &data, 0);
dbp指向需要插入的索引
key,data作为DBT结构传入函数
建立index1 <key,data>
逻辑实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
DB *dbp = (DB*)malloc(sizeof(DB*)),
DBT data, key;
char *fname = “index1_new.db”;
char buf[8*1024];
FILE *ifp = fopen(file_name, "r");
while(fgets(buf, sizeof(buf), ifp) != NULL) {
sscanf(buf,"%*[^|]|%*[^|]|%*[^|]|%*[^|]|%*[^|]|%*[^
|]|%*[^|]|%*[^|]|%*[^|]|%*[^|]|%10[^|]",
mydata.key);
规格化
key data
key.data = mydata.key;
key.size = strlen(mydata.key)+1;
data.data = buf;
data.size = strlen(buf)+1;
dbp->put(dbp, &key, &data, 0);
}
获得index1
94/1/1 | 0.06 | XXXXX
94/1/1 94/1/1 | 0.06 | XXXXX
index1
lineitem.tbl
建立B-Tree索引index2
需求分析

如何遍历index1?
__bt_seq(dbp, key, data, flags)
来源:bt_get()

如何获取对应的页号和槽号?
利用EPG结构,来源:bt_seq()
__bt_seqset(t, &e, &key, flags);

页号和槽号即构成rid。
如何进一步获取index2所需的key呢?
__bt_ret(t, &e, &key, &t->bt_rkey, &data, &t->bt_rdata, 0);
建立Index2 <key,rid>
逻辑实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//The details above have been omitted.
status = __bt_seqset(t, &e, &key, R_FIRST);通过e在index1
中找相应条目
为下一步获取
while (status == RET_SUCCESS) {
discount作准
pagenum = (e.page)->pgno;
备
将页号槽号
slotnum = e.index;
作为Index2
__bt_setcur(t, pagenum, slotnum); 的Data,即
rid
status = __bt_ret(t, &e, &key, &t->bt_rkey,
&data, &t->bt_rdata, 0);
//use sscanf() to get the discount attr.
//Put the data and key(rid) into new index2
//Continue;
}
Index1 Index2



lineitem.tbl <data>
Index1 <Key,data> Key = shipdate
Index2 <key,rid> Key = discount, rid = slot+no.
94/1/1 94/1/1 | 0.06 | XXXXX
94/1/1 | 0.06 | XXXXX
0.06 1 | 1
index2
index1
lineitem.tbl
范围查询
需求分析

方案一:仅根据index1范围查询
94/1/1 94/1/1 | 0.06 | 50 | XXXXXXX
index1
Discount
Quantity
符合条件?
NO

如何比较Key的大小
__bt_defcmp(DBT a, DBT b) 来源:bt_search();
根据返回值确定大小
YES
计算结果
范围查询
逻辑实现
1
2
3
4
5
6
7
8
status = dbp->seq(dbp, &key, &data, R_FIRST);
while (status == RET_SUCCESS) {
if (__bt_defcmp()= 0 is satisfied for each attr.)
{
sum += atof(extendedprice) * atof(discount);
}
status = dbp->seq(dbp, &key, &data, R_NEXT);
}
范围查询
实验测试与结果
测试数据(query.in)
测试结果(query.out)
query.out中数据和给定的理论数据相符
范围查询
需求分析

方案二:通过index2、index1
比较 discount
比较 shipdate
K ey P ageno S lot
quantity
Key DATA
通过页号、槽号,
INDEX2
在 index1 中定位
INDEX1
计算结果
范围查询

方案二:通过Index2、Index1
更少
更省
I/O更少
下推,优
化查询方
案
更快
处理字符
串更少
范围查询

方案二:通过Index2、Index1
更少
更省
I/O更少
Index2 是非聚簇的B树
Key次序不对应于记录的储存次序
对任何数据页读取都可能重复
最坏情况开销等于数据记录的数目
下推,优
化查询方
案
更快
处理字符
串更少
范围查询

方案二:通过Index2,再到Index1
更少
更省
I/O更少
下推,优
化查询方
案
更快
并没有得到较大改进的表现
处理字符
串更少
Berkeley DB 课程设计答辩
UB-TREE设计与逻辑实现
UB-Tree设计与实现
设计思路




将shipdate、discount、quantity 三维的数据通过
interleave(按位交叉)方式,映射为一个一维
的ubkey;
根据得到的ubkey,建立 <key,data>的 UB-Tree
索引;
根据建立的UB-Tree索引进行点查询;
根据建立的UB-Tree索引完成范围查询。
如何按位交叉得到Z_Value?
24
按位交叉得到Z_Value
1. 将每一维度属性值转化为二进制字符串;
2. 将各个字符串统一位数,按位交叉生成新的二进制字符串;
3. 新的二进制字符串作为UB-Key
按位交叉得到Z_Value
逻辑实现
1
2
3
4
5
6
7
8
9
10
11
char* getZvalue(char* attr1, char* attr2, char* attr3)
{
char* z_value;
char* temp1 = tobinary(attr1);
char* temp2 = tobinary (attr2);
char* temp3 = tobinary (attr3);
int z_value_length = max(temp1,temp2,temp3);
z_value = Interleave(tmep1,temp2,
temp3,z_value_length);
return (z_value);
}
这里将UB-Key直接保存为char型是一种方法。为了减小索引大小,加快查询速度,对UBKey更好的处理包括不等长Key、压缩以及保存为int型。
上述方法可交叉重叠使用。详细参见“性能分析”。
建立 <UB-key,data>的 UB-Tree索引
逻辑实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
DB *dbp = (DB*)malloc(sizeof(DB*));
DBT data, key;
char *fname = index3_new.db; char buf[8*1024];
FILE *ifp = fopen(file_name, "r");
while(fgets(buf, sizeof(buf), ifp) != NULL)
{
sscanf(buf,"%*[^|]|%*[^|]|%*[^|]|%*[^|]|%4[^|]|%*[^|]|
%5[^|]|%*[^|]|%*[^|]|%*[^|]|%10[^|]",quantity,discount,s
hipdate);
char *z_value;
z_value = getZvalue(quantity, discount, shipdate);
......
dbp3->put(dbp3, &key, &data, 0) ;
}
点查询 PK 范围查询
fgets(buf, sizeof(buf), fp)
Sizeof(buf) < 30
点查询
范围查询
UB-Tree点查询
设计思路
1、读取输入文件中的点信息;
2、根据读取到的三维信息生成一维的ubkey;
3、 顺序遍历生成的ubtree索引,比较ubkey 与索引
中的 key;
4、 如果 key值相同,计算sum值;
5、 继续遍历;
6、 遍历结束输出结果.
UB-Tree点查询
逻辑实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
while(fgets(buf2, sizeof(buf2), openfp) != NULL)
{
sscanf(buf2,“%10[^ ] %4[^ ] %5[^\n]",
shipdate_,discount_,quantity_);
int status;
status = dbp3->seq(dbp3, &key, &data, R_FIRST);
while (status == RET_SUCCESS) {
if ( __bt_defcmp(&key_t, &key) == 0 )
{
sscanf(buf,"%*[^|]|%*[^|]|%*[^|]|%*[^|]|%*[^|]
|%10[^|]|%5[^|]",_extendedprice,_discount);
sum += atof(_extendedprice) * atof(_discount);
}
status = dbp3->seq(dbp3, &key, &data, R_NEXT);
}
}
点查询
实验测试与结果
测试数据(query.in)
测试结果(query.out)
query.out中数据和通过SQL查询结果相符
UB-Tree结果
SQL结果
点查询 PK 范围查询
fgets(buf, sizeof(buf), fp)
Sizeof(buf) < 30
点查询
范围查询
范围查询
查找开始
Flags =R_CURSOR, cur/start = ql, end=qh
流程图
N
Key < qh
Y
Y
Key各维
N
在查找范
围内
Y
继续遍历
Flags=R_NEXT
下一条目Key
在查找范围内
N
跳转到nisp(实现优化)
Flags = R_CURSOR
计算Sum
END
范围查询
设计思路






读取输入文件中的范围信息;
根据读取到的三维信息生成两个一维的ubkey:ql和qh;
从索引开头顺序遍历生成的ubtree索引,比较 ql qh与索引中的key;
如果 key值相同,计算sum值;
如果不同,检查CURSOR所指向的条目下一个条目,如果下一个
数据的Key在查询范围内,则继续遍历;如果下一个数据Key不在
范围内,则需要修改Key的值,跳转到下一个合适的查询起始点。
遍历结束,输出结果。
本质其实就是对key的操作,得到一个更合适的key,并从它开始查询
范围查询
逻辑实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
flags = R_CURSOR;
start = cursor = ql;
end = qh;
int status;
status = dbp3->seq(dbp3, &key_z, &data_z, flags);
while (status == RET_SUCCESS) {
if (strcmp(key_z.data, qh) >= 0)
break;
if( ifKeyInQurey(key_z, start, end) == 0) {
//details are omitted.
sum+= atof(_extendedprice) * atof(_discount);
flags=R_NEXT;
}
范围查询
逻辑实现
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
else {
status = dbp3->seq(dbp3, &key_z, &data_z, R_NEXT);
if ( strcmp(key_z.data, qh) > 0)
break;
if ( ifKeyInQurey ( key_z, start, end) == 0){
sum+= atof(_extendedprice) * atof(_discount);
flags =R_NEXT;
}
else {
new_z = changeZvalue(key_z, start, end);
flags = R_CURSOR;
}
}
status = dbp3->seq(dbp3, &key_z, &data_z, flags);
}
范围查询
实验测试与结果
测试数据(query.in)
测试结果(query.out) query.out中数据和给定的理论数据相符。其中范围查询部
分结果应该和B-Tree一致。
UB-Tree查询结果
B-Tree查询结果
Berkeley DB 课程设计答辩
性能分析
性能分析

性能测试指标




建立的索引大小
建立索引时间
查询时I/O读写情况
测试数据


建立索引以lineitem.tbl为源数据
查询条件
B树
UB树
性能分析

索引大小

B-Tree Index1 大小

B-Tree Index2 大小

UB-Tree Index 大小
可以通过删
去不必要的
属性以减小
大小
可以通过优
化UB-Key保
存方式减小
大小
性能分析

建立索引时间

B-Tree index1
128 缓冲页
8 缓冲页
建立相同索引所用的时间有少许减少,这可能大的缓冲页使程序不必频繁
在内存和辅存中交换数据页,减少I/O开销。
性能分析

建立索引时间

B-Tree index2
128 缓冲页
8 缓冲页
128页时间有少许减少。这可能index2所储存的数据仅是Key和槽号页号,数据不
必频繁在内存和辅存中交换数据页,因而没有很大程度上减少建立索引的时间。
对于UB-Key的处理优化

各维属性不等长*
1994 – 01 – 01
0. 0 1
77
4 x 4 + 4 + 5 + 4 x 2 + 4 x 2 = 41 Bytes
通过提取各维属性中有效部分的信息,减少UB-Key长度。
代价是要维护一个变量来保存各个维度属性的长度。
对于UB-Key的处理优化

将UB-Key压缩**
a 01100001 b 01100010 c 01100011
00011111 10000000 00011101
(char) 31
(char)128
(char)29
压缩为长度为3的字符串
通过将原来UB-Key中每8为组合为一个数字,用char型保存减少长度。
代价是在每次生成和取用UB-Key时候,都需要一个压缩和解压缩过程。
性能分析

查询时I/O读写
PAGE = 8
*上述测试基于 Ubuntu系统监视器数据获得。在特定计算机、特定条件特定条件下实验获得。
性能分析

查询时I/O读写
PAGE = 128
*上述测试基于 Ubuntu系统监视器数据获得。在特定计算机、特定条件特定条件下实验获得。
I/O
下降
≈18.9%
Berkeley DB 课程设计答辩
感悟和结语
感悟和结语
…
上层应用
针对Key优化
UB-Tree
底层结构
实现基本功能
B-Tree Berkeley DB
感悟和结语




优中取优,多种方法,多种模式,不断地去探
索,交流和讨论。
基础工作很重要。
错误不可怕,关键是找到错误的原因。
数据库课程不仅仅是SQL。
致谢
本次答辩PPT的修改得到了冯老师的宝贵指导意见,以及两位TA周盈盈
师姐和阮淑梨师姐的意见和建议。这使得我们小组的答辩PPT和课程设
计愈加完善和规范。在此我们特表感谢!
“各维属性不等长”的优化处理方法来自9班第五小组:劳思、钟益强。
“UB-Key压缩”的优化处理方法来自9班第三小组:陈志炯、卿志鹏。
我们特向以上两个小组同学的慷慨分享表示感谢。
谢谢大家
张天意 周冰楠
9班第1小组