Berkeley DB的数据存储结构

BDB支持四种数据存储结构及相应算法,官方称为访问方法(Access Method),分别是哈希表(Hash Table)、B树(BTree)、队列(Queue)、记录号(Recno)。在创建数据库的时候,必须通过dbtype参数将存储结构指定为上述结构中的一种,一旦数据库文件已创建则不能再更改其结构。

结构 描述
BTree 数据存储在一个有序的,平衡的树型结构中。在B树结构中,Key和Value都可以复杂的数据,这意味着它们可以是整数、字符串或复杂的数据结构。同时,这种结构允许重复的Key值,即两个记录拥有同样的Key(需要在创建数据库时打开XXX开关)。
哈希 数据存储在一个扩展的线性哈希表。同B树类似,Key和Value可以是复杂的数据,它也支持相同Key的记录(需要打开XXX)
队列 数据存储在一个固定记录长度的队列中。每个记录使用一个逻辑记录号作为它的Key。这种结构有利于快速在尾部插入,而且针对这种结构有一个专用的操作可以让你从队列头部删除并返回数据。这种结构的特点在于它提供记录级的锁,这非常有利于在并发访问队列时提供更高的性能。
记录号 基本同队列类似,它也使用一个逻辑记录号作为Key,但这里的记录可以是定长的,也可以是不定长的

B树(BTree)

通过指定dbtype=db.DB_BTREE用哈希表作为存储结构。B树中的B是Balanced的缩写,实际使用过程中,B树同哈希表基本一样。

哈希表(Hash)

通过指定dbtype=db.DB_HASH使用哈希表作为存储结构。

队列(Queue)

通过指定dbtype=db.DB_QUEUE使用队列作为存储结构。初次使用这种结构你能感觉到它与B树和哈希有较大的差异。

>>> from bsddb import db >>> quedb = db.DB() >>> quedb.open('quedb.db',dbtype=db.DB_QUEUE,flags=db.DB_CREATE) >>> quedb.put("number1","1") Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: String keys not allowed for Recno and Queue DB's >>>

上面的代码我们新建了一个名字为quedb的队列数据库,在使用我们熟悉的put方法时出错,原因是队列类型是不接受字符串类型的Key名称,Key只能是数字。

>>> quedb.put(1,"first item") >>> print quedb.items() [(1, 'first item ')]

实际应用中,经常Key对我们来说并不重要,我们可以使用一个简化的append方法向队列添加元素,这个方法会将添加元素的Key(记录号)作为返回值:

>>> quedb.append("second item") 2 >>> print quedb.items() [(1, 'first item '), (2, 'second item ')]

在队列中仍可以使用get方法获取值、使用put方法更改值,以及使用delete删除值:

>>> print quedb.get(1) first item >>> quedb.put(1,"1st item") >>> print quedb.items() [(1, '1st item '), (2, 'second item ')] >>> quedb.delete(1) >>> print quedb.items() [(2,'second item ')]

你可能想让这种数据结构操作起来也更像一个队列。可以使用另一个简化的功能consume,这样我们使用append在队列尾部加入数据,使用consume取出队列首部的数据,很方便地实现了FIFO的操作:

>>> quedb.append("third item") 3 >>> quedb.consume() ('\x02\x00\x00\x00', 'second item ')>>> quedb.consume() ('\x03\x00\x00\x00', 'third item ') >>> quedb.consume() >>>

记录号

记录号数据结构有些特性和队列很类似,它支持put,get,append,delete等方法,同样,它的Key也只能是数字类型。需要注意的是,在创建数据库之前不需要指定记录长度,它也不能象队列类型那样使用consume方法。

选择正确的数据结构

首先你要知道准备使用BDB解决什么样的问题,如果你需要存储复杂的数据(包括字符串),那么你应当使用B树或者哈希。如果你想使用逻辑编号,那么应当使用队列或记录号。 
那么问题来了,在B树、哈希,队列、记录号之间应当如何做选择呢?

选择B树还是哈希?

当在主键有序时,Btree算法应该被使用。

Hash 和 Btree 两种方式在小的数据集合上几乎没有性能的差别。不过,由于Hash使用的是扩展线性HASH算法(extended linear hashing),可以根据HASH表的增长进行适当的调整。所以当一个数据集合足够大且关键字为随机分布时,采用Hash算法比较好。

选择队列还是记录号?

当用记录号作为数据存取的主键时,应该使用 Queue和Recno存取方法。记录号由算法本身生成。实际上,这和关系型数据库中逻辑主键通常定义为int AUTO型是同一个概念。两者基本上都是建立在Btree算法之上,提供存储有序数据的接口。Queue的优势在于:由于其记录为定长,在插入操作时把记录插入到队列的尾部,所以速度最快,而且它执行上锁和并发处理的水平也相当高。 Recno 的长处在于它支持一些Queue不能实现的特征,比如可变长记录和支持flat-text文件。记录号可以是可变的或者不变的: 可变指的是当记录被删除或者插入记录号发生变化;不变指的是记录号无论数据库如何操作,记录号都不会发生改变。 Recno 可以被设置为不变和可变两种形式。

Berkeley DB的数据存储结构——哈希表(Hash Table)、B树(BTree)、队列(Queue)、记录号(Recno)的更多相关文章

  1. HashSet集合存储数据的结构(哈希表)和Set集合存储㢝不重复的原理

    HashSet集合存储数据的结构(哈希表) Set集合存储㢝不重复的原理 前提:存储的元素必须重写hashCode方法和equals方法

  2. 算法与数据结构基础 - 哈希表(Hash Table)

    Hash Table基础 哈希表(Hash Table)是常用的数据结构,其运用哈希函数(hash function)实现映射,内部使用开放定址.拉链法等方式解决哈希冲突,使得读写时间复杂度平均为O( ...

  3. Hashtable数据存储结构-遍历规则,Hash类型的复杂度为啥都是O(1)-源码分析

    Hashtable 是一个很常见的数据结构类型,前段时间阿里的面试官说只要搞懂了HashTable,hashMap,HashSet,treeMap,treeSet这几个数据结构,阿里的数据结构面试没问 ...

  4. 什么叫哈希表(Hash Table)

    散列表(也叫哈希表),是根据关键码值直接进行访问的数据结构,也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的数组叫做散列表. - 数据结构 ...

  5. PHP关联数组和哈希表(hash table) 未指定

    PHP有数据的一个非常重要的一类,就是关联数组.又称为哈希表(hash table),是一种很好用的数据结构. 在程序中.我们可能会遇到须要消重的问题,举一个最简单的模型: 有一份username列表 ...

  6. 数据结构 哈希表(Hash Table)_哈希概述

    哈希表支持一种最有效的检索方法:散列. 从根来上说,一个哈希表包含一个数组,通过特殊的索引值(键)来访问数组中的元素. 哈希表的主要思想是通过一个哈希函数,在所有可能的键与槽位之间建立一张映射表.哈希 ...

  7. 词典(二) 哈希表(Hash table)

    散列表(hashtable)是一种高效的词典结构,可以在期望的常数时间内实现对词典的所有接口的操作.散列完全摒弃了关键码有序的条件,所以可以突破CBA式算法的复杂度界限. 散列表 逻辑上,有一系列可以 ...

  8. 哈希表(Hash table)

  9. 【Python算法】哈希存储、哈希表、散列表原理

    哈希表的定义: 哈希存储的基本思想是以关键字Key为自变量,通过一定的函数关系(散列函数或哈希函数),计算出对应的函数值(哈希地址),以这个值作为数据元素的地址,并将数据元素存入到相应地址的存储单元中 ...

随机推荐

  1. 浅析call和apply

    call, apply都属于Function.prototype的一个方法,它是JavaScript引擎内在实现的,因为属于Function.prototype,所以每个Function对象实例,也就 ...

  2. NOIP 2014 Day2 T1 无线网络发射器

    #include<iostream> #include<cmath> #include<cstdlib> #include<cstdio> #inclu ...

  3. cordova 打包发布正式版 apk

    cordova build android —release 笔者观察了一下新版Cordova,用的是gradle来build项目,所以网上的那些设置ant.properties的解决方法都排除掉,不 ...

  4. POSTMAN as debugger for integration APPs

    Chrome Menu: Window > Extensions > Postman - REST Client 0.8.4.10 起个标题,有空总结一下一个经验,关于Netsuite i ...

  5. CSS使用

    CSS介绍 css是英文Cascading Style Sheets的缩写,称为层叠样式表,用于对页面进行美化. 语法:style = 'key1:value1;key2:value2;' 存在方式有 ...

  6. $smarty获取变量get,post等用法

    {$smarty}保留变量不需要从PHP脚本中分配,是可以在模板中直接访问的数组类型变量,通常被用于访问一些特殊的模板变量.例如,直接在模板中访问页面请求变量.获取访问模板时的时间邮戳.直接访问PHP ...

  7. windows页面打印div(弹出新页面)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  8. Cheatsheet: 2016 07.01 ~ 07.31

    Mobile What to Expect From Swift 3 Web A practical security guide for web developers Gulp Succinctly ...

  9. ASP.NET MVC 静态资源打包和压缩问题小记

    ASP.NET MVC 中有个 BundleConfig 用于静态资源的打包和压缩,我在使用的过程中遇到一些问题,现在做下总结,并给出具体的解决方案. 问题一:打包压缩后的 JavaScript 和 ...

  10. hadoop2.7.3配置文件中过时的属性

    过时的属性:Deprecated Properties 该列表保存于:hadoop-2.7.3-src\hadoop-common-project\hadoop-common\src\site\mar ...