Berkeley DB的数据存储结构——哈希表(Hash Table)、B树(BTree)、队列(Queue)、记录号(Recno)
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)的更多相关文章
- HashSet集合存储数据的结构(哈希表)和Set集合存储㢝不重复的原理
HashSet集合存储数据的结构(哈希表) Set集合存储㢝不重复的原理 前提:存储的元素必须重写hashCode方法和equals方法
- 算法与数据结构基础 - 哈希表(Hash Table)
Hash Table基础 哈希表(Hash Table)是常用的数据结构,其运用哈希函数(hash function)实现映射,内部使用开放定址.拉链法等方式解决哈希冲突,使得读写时间复杂度平均为O( ...
- Hashtable数据存储结构-遍历规则,Hash类型的复杂度为啥都是O(1)-源码分析
Hashtable 是一个很常见的数据结构类型,前段时间阿里的面试官说只要搞懂了HashTable,hashMap,HashSet,treeMap,treeSet这几个数据结构,阿里的数据结构面试没问 ...
- 什么叫哈希表(Hash Table)
散列表(也叫哈希表),是根据关键码值直接进行访问的数据结构,也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的数组叫做散列表. - 数据结构 ...
- PHP关联数组和哈希表(hash table) 未指定
PHP有数据的一个非常重要的一类,就是关联数组.又称为哈希表(hash table),是一种很好用的数据结构. 在程序中.我们可能会遇到须要消重的问题,举一个最简单的模型: 有一份username列表 ...
- 数据结构 哈希表(Hash Table)_哈希概述
哈希表支持一种最有效的检索方法:散列. 从根来上说,一个哈希表包含一个数组,通过特殊的索引值(键)来访问数组中的元素. 哈希表的主要思想是通过一个哈希函数,在所有可能的键与槽位之间建立一张映射表.哈希 ...
- 词典(二) 哈希表(Hash table)
散列表(hashtable)是一种高效的词典结构,可以在期望的常数时间内实现对词典的所有接口的操作.散列完全摒弃了关键码有序的条件,所以可以突破CBA式算法的复杂度界限. 散列表 逻辑上,有一系列可以 ...
- 哈希表(Hash table)
- 【Python算法】哈希存储、哈希表、散列表原理
哈希表的定义: 哈希存储的基本思想是以关键字Key为自变量,通过一定的函数关系(散列函数或哈希函数),计算出对应的函数值(哈希地址),以这个值作为数据元素的地址,并将数据元素存入到相应地址的存储单元中 ...
随机推荐
- SQL 语句调优 where 条件 数据类型 临时表 索引
基本原则 避免全表扫描 建立索引 尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理 尽量避免大事务操作,提高系统并发能力 使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方 ...
- 关于Android中ArrayMap/SparseArray比HashMap性能好的深入研究
由于网上有朋友对于这个问题已经有了很详细的研究,所以我就不班门弄斧了: 转载于:http://android-performance.com/android/2014/02/10/android-sp ...
- 用STM32CubeMX创建FreeRTOS项目
1. 目标, PG13,PG14双线程双闪灯. 2. 测试平台 stm32f429i-disco keil v5.13.0.0 CubeMx 4.8.0 3. 步骤 3.1 打开cube, PG13, ...
- Mysql修改字段长度
alter table '表名' modify column '列名' varchar(50);
- sql server CTE递归使用测试
--CTE递归查询 if(object_id(N'menu') > 0) drop table menu CREATE TABLE MENU ( name nvarchar(50) NOT NU ...
- Java Web之JavaBean
一.什么是javaBean javaBean是一个遵循特定写法的java类,通常具有如下的特点: 这个java类必须具有一个无参的构造函数. 属性必须私有化. 私有化的属性必须通过public类型的方 ...
- 泛型数组列表 ArrayList
为什么使用泛型数组列表而不使用普通数组? 1.普通数组经常会发生容量太大以致浪费的情况 2.普通数组无法动态更改数组 基本概念: 1.采用[类型参数]的[类]---->[泛型类] 2.[泛型类型 ...
- Sublime Text 配置记录
sublime userSetting sublime theme sublime plug sublime userSetting 对sublime的配置 { "color_scheme& ...
- 关于HTML5你必须知道的28个新特性,新技巧以及新技术
1. 新的Doctype 尽管使用<!DOCTYPE html>,即使浏览器不懂这句话也会按照标准模式去渲染 2. Figure元素 用<figure>和<figcapt ...
- 【Java】集合_学习笔记
一.集合 1.集合类也称容器类,主要负责保存.盛装其他数据. 2.集合可以保存数量不确定的数据,保存具有映射关系的数据(也称关联数组). 3.Java5后提供一些多线程安全的集合类,放在java.ut ...