1 概述
本文讲述基于多级树开发的有序内存数据表数据结构的技术特点、功能描述、应用领域以及性能参数。
目前实时处理系统对内存数据结构的普遍有以下要求:
1、功能要求
功能要强大且完备,满足业务功能的需求。
2、性能要求
要能满足实时处理系统对处理速度的需求,同时能长期运行且性能保持稳定
3、系统容量大
要能保持超大规模数据,且在海量数据情况下还能保持优异的性能。
有序HASH内存表是目前速度最快功能最强大的数据结构,可以满足电信以及其他行业软件开发对数据结构的要求。
2 版权说明
1、本开发包免费,用户可用于学习、测试、商业用途,本软件没有功能上的限制和使用期限限制,可自由复制、传播。
2、用户可发邮件到Freeland007@163.com 向作者获取最新版本。欢迎用户朋友
对本软件提出宝 贵意见,作者会及时修改软件的BUG,并对软件进行持续的
改进。
3、作者联系方式
e-mail:freeland007@163.com
QQ: 723273055
博客:http://blog.youkuaiyun.com/freeland008
3 有序HASH内存表介绍
3.1 内存表基本概念
内存表数据结构是指在内存中建立类似传统关系数据库管理系统(ORCALE、
MS SQL SERVER)建立的表,区别在于内存表中的所有记录数据和索引数据都保存在内存,其中有序HASH内存表的索引采用有序HASH树数据结构,关于有序HASH树请参考网址:
http://hi.youkuaiyun.com/link.php?url=http://blog.youkuaiyun.com%2Ffreeland008
3.2 内存表的构成
有序HASH内存表由字段、索引、以及记录构成。
1)字段
内存表有多个字段构成,每个字段拥有在表中唯一的名字,字段的数据类型
目前支持整数、字符串数据类型,字段的名字在生成索引和访问字段值时使
用,字段名不区分大小写。
2)索引
有序HASH内存表拥有1个或多个索引,每个索引由表中的一个或多个字段构
成。由一个字段构成的索引称为单列索引,由多列构成的索引称为复合索引。
索引采用的数据结构为有序HASH树,单列索引用的是单级有序HASH树,复合
索引采用的是多级有序HASH树。索引分为唯一索引、非唯一索引,唯一索引
中的主键必须唯一,非唯一索引中的记录可以拥有相同的主键。
3)记录
一个内存表可以拥有上千万的记录,程序通过索引对表记录进行访问,支持的
访问方式包括精确查询,like方式的正向模糊匹配,match方式的反向模糊
匹配,整体遍历。
3.3 访问内存表的方法
访问有序内存表中的记录都是通过索引完成的,可以通过以下方式访问记录。
1、可以通过外部提供的键值在索引中定位一条记录(单列索引)或多条记录(复合索引)。
2、可以通过外部提供的值在索引中快速定位到符合条件的匹配规则记录,称之为反向模糊匹配,匹配规则表达式字符串由字符和2种通配符组成,例如以
下形式的规则表达式:
1)0755%、138%5678、%5678、%1234%
2)?234567890、12345678??、?23???789?
3)0755%56??、????1234%
通配符为%和?。
通配符%:包含零个或更多个字节的任意字符串。
通配符?:任意单字节字符。
3、可以通过外部提供的匹配模式字符串在索引中定位到符合条件的记录,称之为正向模糊匹配。
说明:本搜索方式和方式2是完全相反的方式,一般情况下可能会有多个记录的键值符合匹配模式,对于符合条件的记录可以指定排序方式顺序访问。
4、可以在索引中定位指定键值长度的记录。
例如:
1)定位键值长度为10字节的所有记录
2)定位键值长度为大于5小于10个字节的所有记录
5、可以在索引中定位键值在某个区域的记录。
例如:
1)返回大于“1234000000”的记录
2)返回小于“1235000000”的记录
3)返回大于“1234000000”并且小于“1235000000” 的记录
6、用整体遍历的方式访问索引中的记录,在遍历时可以指定排序方式,可以按主键的升序或降序顺序遍历
7、根据指定排序(升、降)方式获取头(尾)记录
8、根据指定排序(升、降)方式删除头(尾)记录,同时获取头(尾)记录的句柄。
除了以上的访问内存表记录的方式外,还有以下功能:
1、对于返回多个记录的情况可以指定排序方式(升序、降序)的方式访问记录
例如:上面的方式3、4、5、6
2、对于返回多个记录的情况可以指定访问的最大记录数量。
3、可以在访问记录过程中调用回调函数对记录数据经行再处理。
4 运行效率高
1、根据索引精确访问(插入、删除、查询、模糊匹配)节点的速度快。
1)在有 1000万记录的内存表中插入或插入一个记录需要1~2个微秒,相当
于60~100万次/秒插入或删除记录操作。
2)在有 1000万记录的内存表中查找一个节点需要0.5~1个微秒,相当于
100~200万次/秒查找操作。
2、对有序HASH内存表的其它操作指标参考性能指标部分
3、支持超大容量记录
在内存表有庞大数量记录的情况下,仍然保持高效运行。根据主键精确访问
(插入、删除)节点的耗时与内存表记录数量无关,只与键值的长度和索引
数量有关; 根据主键精确访问(查询)记录的耗时与内存表记录数量无关,
只与键值的长度有关。
4、在频繁插入、删除记录的情况下,系统仍然保持运行稳定,不会出现性能抖
动的情况。
5 功能强大
有序HASH内存表的核心组件式索引,索引采用的有序HASH树,单(多)级HASH
树功能强大,可以满足目前应用程序开发中对数据结构功能上的需求,是对目前C、C++标准库强有力的补充或部分替代功能。
以下是有序HASH树和MFC中CMAP类的功能比较。
序号 | 比较功能 | 快速HASH树 | CMAP(MFC) |
1 | 精确查询节点 | 支持 | 支持 |
2 | 精确删除节点 | 支持 | 支持 |
3 | 根据匹配模式匹配节点 | 支持 | 不支持 |
4 | 根据字符串匹配规则表达式节点 | 支持 | 不支持 |
5 | 查询指定键值长度的节点 | 支持 | 不支持 |
6 | 查询指定键值范围的节点 | 支持 | 不支持 |
7 | 支持键值有序(升、降)遍历 | 支持 | 不支持 |
8 | 支持头(尾)节点操作 | 支持 | 不支持 |
9 | 根据节点位置获取键值 | 支持 | 不支持 |
10 | 根据节点位置获取用户指针数据 | 支持 | 不支持 |
11 | 根据节点位置删除树节点 | 支持 | 不支持 |
12 | 支持多级(树、MAP)方式 | 支持 | 不支持 |
13 | 多级(树、表)的功能 | 支持 | N/A |
14 | 其它功能 | 支持 | 不支持 |
有序HASH内存表基于有序HASH树开发,同时加入了字段、记录、索引的概念和管理功能,开发人员可以根据实际需求选择有序HASH树或者有序HASH内存表。
一般遵循以下原则:
对于数据只需要一个索引而且该索引时唯一索引时,可以考虑使用有序HASH树,否则选用有序HASH内存表。
有序HASH内存表SDK提供以下功能:
1、创建、删除内存表
2、创建、删除索引
3、插入、删除
4、根据索引访问记录,访问记录时支持回调函数
5、可以访问和修改记录中的列值。
6、其它功能
具体功能可参考第6章SDK中API函数的功能介绍。
6 有序HASH内存表SDK介绍
有序HASH内存表以动态库的形式提供给开发人员,下面介绍常用的API。
1、HANDLE CacheCreateTable(LPTABLEDESC pTableDesc);
功能:生成有序HASH内存表,返回内存表句柄。
2、int CacheDropTable(HANDLE hTable);
功能:删除内存HASH表。
3、int CacheTruncate(HANDLE hTable);
功能:删除内存表中所有记录。
4、HANDLE CacheCreateIndex(HANDLE hTable, LPINDEXDESC pIndexDesc);
功能:在有序HASH内存表中新建索引。
5、int CacheDropIndex(HANDLE hTable, char* sIndex);
功能:在内存表中删除指定名字的索引。
6、int CacheGetIndexCount(HANDLE hTable);
功能:获取指定内存表中索引的数量。
7、int CacheGetRowCount(HANDLE hTable);
功能:获取内存数据表记录数量
8、HANDLE CacheInsert(HANDLE hTable, char* sFieldValue[]);
功能:在内存表中插入一条记录。
9、int CacheDelete(HANDLE hTable, HANDLE hRecord);
功能:在内存表中删除指定的一条记录
10、int CacheDeleteByKey(HANDLE hTable, HANDLE hIndex,
char* sMultiKey[]);
功能: 在内存表中删除某索引中具有相同键值的一个或多个记录,键值由函
数参数提供。
11、int CacheUpdate(HANDLE hTable, HANDLE hRecord, int nField,
int* nFieldNO, char* sFieldValue[]);
功能:修改内存表指定记录的某些字段的值。
12、int CacheUpdateByKey(HANDLE hTable, HANDLE hIndex, char* sMultiKey[],
int nField, int* nFieldNO, char* sFieldValue[]);
功能:修改内存表修改记录指定字段的值,这些记录在指定索引中具有相同
的指定键值
13、int CacheGetFieldNO(HANDLE hTable, char* sField);
功能:根据字段名字获取字段在表中的序号
14、 CacheGetFieldString(HANDLE hTable, HANDLE hRecord, int nFieldNO,
char* pBuf);
功能:获取记录中指定记录的字符串值。
其它类似函数:
int CacheGetFieldInt8(HANDLE hTable, HANDLE hRecord, int nFieldNO,
char* nValue);
int CacheGetFieldUInt8(HANDLE hTable, HANDLE hRecord, int nFieldNO,
unsigned char* nValue);
int CacheGetFieldInt16(HANDLE hTable, HANDLE hRecord, int nFieldNO,
short* nValue);
int CacheGetFieldUInt16(HANDLE hTable, HANDLE hRecord, int nFieldNO,
unsigned short* nValue);
int CacheGetFieldInt32(HANDLE hTable, HANDLE hRecord, int nFieldNO,
int* nValue);
int CacheGetFieldUInt32(HANDLE hTable, HANDLE hRecord, int nFieldNO,
unsigned int* nValue);
int CacheGetFieldInt64(HANDLE hTable, HANDLE hRecord, int nFieldNO,
__int64* nValue);
15、int CacheSelect(HANDLE hTable, LPSELECTCOND pSelectCond);
功能:此函数用来根据指定的条件访问单(多)级HASH树中的节点,此函数
功能强大,可以指定访问各级子树的访问方式,对于满足访问条件的节点可
以由用户编写的回调函数处理。
16、HANDLE HTreeGetCurrentValue(LPSELECTCOND pSelectCond);
功能:此函数在执行HTreeSelect中的回调函数中使用,用来获取当前节点
的句柄值。
其它功能函数:略
7 有序HASH内存表行业应用
有序HASH内存表已经广泛应用到可应用于多个行业软件开发领域,特别适合于超大规模信息的实时处理的情况。
7.1 电信实时处理系统
1、电话(手机)号码路由
2、电话号码区号匹配
3、手机号码归属地查询
4、手机短信违禁词过滤
5、电话(手机)号码黑白名单查询过滤
6、号码路由
7、订购关系处理
8、实时鉴权系统
9、实时计费系统
7.2 互联网应用
1、高效数据库缓存服务器
2、产品编码查询
3、身份查询
4、网络游戏服务器
7、域名系统
8、路由查询
9、邮件系统
7.3 实时处理系统
1、实时监控系统
2、数据采集系统
3、跟踪系统
7.4 内存数据库系统
内存数据库的其中之一的核心数据结构式内存数据库表,可以采用有序HASH内存表为基础开发适合需要的内存数据库系统。
8 运行环境
1、windows 2000、windows 2003、windows XP
2、linux
3、unix(solarix、HP-UX、AIX等)
9 性能指标
9.1 测试环境
1、操作系统:windows xp professional
2、内存:1G /DDR2
3、CPU:AMD LE1100/1.9GHz
9.2 单列唯一索引内存表性能指标
测试数据:
1、有序HASH内存表描述如下:
表结构定义:
字段名 | 字段说明 | 数据类型 | 长度(字节) |
cardid | 身份证号码 | CACHE_STRING | 18 |
sex | 性别 | CACHE_UINT8 | 1 |
name | 名字 | CACHE_STRING | 16 |
age | 年龄 | CACHE_UINT16 | 2 |
address | 联系地址 | CACHE_STRING | 32 |
| Email地址 | CACHE_STRING | 32 |
索引:
索引名称 | 列 | 唯一索引 | 说明 |
cardid | cardid | 是 | 根据身份证ID建立唯一索引 |
测试项目:
1、插入记录
插入100万记录到内存表中,记录的索引键值从123456780000000000到
123456780000999999,耗时1.718秒。
2、根据键值精确删除记录
从有序HASH内存表中根据键值删除100万个记录,记录的索引键值从
123456780000000000到123456780000999999,耗时1.125秒。
3、根据键值精确查询记录
根据键值从有序HASH内存表中精确查询100万记录,记录的索引的键值从
123456780000000000到123456780000999999,耗时0.750秒。
4、整体遍历
遍历有序HASH内存表中的100万记录,记录的索引键值从
123456780000000000到123456780000999999,耗时0.093秒。
6、清除HASH树中所有记录
一次清除有序HASH内存表中的所有100万记录,记录的索引键值从
123456780000000000到123456780000999999,耗时0.234秒。