发明内容
本发明的目的之一在于提供一种数据库检索方法及系统,旨在降低数据存储量,并提高检索效率。
为了实现发明目的,所述数据库检索系统包括数据库及与其交互的检索装置,所述数据库包括:
域处理单元,将所述数据库中的多个域处理成一合并域,并对所述合并域中的各子域进行操作设置;
写操作单元,根据各子域的操作设置向所述各子域存入数据;
所述检索装置包括:
解析单元,对用户输入的查询语句进行解析,得到与所述各子域的操作设置相关的运算表达式;
检索单元,利用所述解析单元得到的所述运算表达式在从数据库导出的合并域中进行查找。
其中,所述域处理单元包括:
域合并模块,将数据库中的多个域处理成一合并域,所述合并域包含多个子域;
操作设置模块,构建与所述各子域具有映射关系的操作函数。
其中,所述解析单元包括:
分析模块,对用户输入的查询语句进行分析,确定与合并域中各子域对应的运算表达式;
设置关联模块,将所述各子域的操作函数关联到所述各子域对应的运算表达式,得到合并域的运算表达式。
其中,所述检索单元包括:
数据提取模块,将合并域从数据库中导出;
查询模块,利用所述运算表达式在从数据库导出的合并域中进行查找。
所述数据库检索方法包括:
A.将数据库中的多个域处理成一合并域,并对所述合并域中的各子域进行操作设置;
B.根据各子域的操作设置向所述各子域存入数据;
C.对用户输入的查询语句进行解析,得到与合并域中各子域的操作设置相关的运算表达式;
D.利用所述运算表达式在从数据库导出的合并域中进行查找。
其中,所述步骤A中对各子域进行操作设置的过程包括:
构建与各子域具有映射关系的操作函数。
其中,所述操作函数包括写操作函数和读操作函数。
其中,所述写操作函数包括设置函数和清除函数,所述读操作函数包括查询函数。
其中,所述步骤B包括:通过各子域的写操作函数在数据库中插入数据或更新数据。
其中,所述步骤C包括:
C1.对用户输入的查询语句进行分析,确定与合并域中各子域对应的运算表达式;
C2.根据运算表达式中的子域名得到操作函数中的读操作函数;
C3.将读操作函数关联到各子域的运算表达式,从而生成合并域的运算表达式。
其中,所述查询语句包括结构化查询语言。
其中,所述步骤D包括:
D1.从数据库中导出合并域;
D2.调用合并域的运算表达式,并利用所述运算表达式在合并域中进行查找。
其中,若查询记录M是否存在于数据库中,则所述步骤D2包括:
D21对从数据库中导出的合并域进行或逻辑操作;
D22.利用所述运算表达式在所述合并域的或逻辑操作结果中查找所述记录M。
其中,所述步骤D2进一步包括:利用所述运算表达式在每条记录的合并域中查找记录M的详细内容。
由上可知,本发明在进行数据库检索的过程中,将多个域合并为一个域,然后通过与合并域中各子域的操作设置相关的运算表达式进行检索,不仅降低了数据存储量,并且提高了检索效率。
具体实施方式
图1示出了本发明的一个实施例中数据库检索系统的结构,该系统包括数据库10、检索装置20。应当说明的是,本发明所有图示中各设备之间的连接关系是为了说明其信息交互及控制过程的需要,因此应当视为逻辑上的控制关系。另外需要说明的是,各功能模块之间的通信方式可以采取多种,本发明的保护范围不应限定为某种特定类型的通信方式。
数据库10包括域处理单元11和写操作单元12,其中:
(1)域处理单元11,将数据库10中的多个域处理成一合并域,并对各子域进行操作设置。
(2)写操作单元12,与域处理单元11相连,根据各子域的操作设置向前述的各子域中存入数据。
检索装置20包括解析单元21和检索单元22,其中:
(1)解析单元21,对用户输入的查询语句进行解析,得到与合并域中各子域的操作设置相关的运算表达式。
(2)检索单元22,与解析单元21相连,利用解析单元21得到的所述运算表达式在从数据库10导出的合并域中进行查找。。
图2示出了本发明一个实施例中域处理单元11的结构,包括域合并模块111和操作设置模块112,其中:
域合并模块111将数据库10中的多个域处理成一合并域。
目前数据库支持的域的数据类型有五种:字符型、文本型、数值型、逻辑型、日期型,实际应用中,它们的表达能力可能无法被充分利用,例如用数值型中的UNSIGNED INT类型来描述工资时,它的表达范围是0-4294967295,实际上正常使用的范围可能只是0-10000,则造成了表达能力和存储的浪费。本发明通过域合并模块111对域进行合并,实际上就是进行了压缩存储,主要目的就是为了充分利用数据类型的表达能力,避免存储的浪费。
在一个实例中,进行数据压缩后的数据表定义如下:
域 | 数据类型 | 说明 |
工号 | 数值(INT) | 工号,Index |
姓名 | 字符(char) | 职员姓名 |
出生日期 | 日期(DATE) | 职员出生日期 |
职员信息 | 二进制(bin)长度为20比特(bit) | 含职员的性别、婚否、职务、工资。其中:1个bit表示性别(0:男,1:女)1个bit表示婚否(0:未婚,1:已婚)2个bit表示职务(00:职员,01:科长、10:处长)14个bit用来表示工资(最大可以表示10000) |
在进行域合并后的职员信息域中,每个子域(对应合并前的域)占据一段存储,x表示一个bit位,如图3所示。应当说明的是,实际上可以将工号、姓名、出生日期都合并到“职员信息”域中,因为任何类型的数据都可以被二进制类型表示,但工号单独被检索的可能性较大,而姓名和出生日期作为查询域的概率远大于作为条件域的概率,所以在此实例中没有被合并。另外应当说明的是,除了二进制的数据类型,还可以用其他的数据类型来合并表达多个域,如定义N个字符,其中X个字符表示职员姓名,Y个字符表示职员的出生日期,且X+Y<=N。
操作设置模块112,与域合并模块111交互,构建与各子域具有映射关系的操作函数。在本发明中,操作设置模块112首先定义子域的掩码,为了方便程序计算,则进一步定义写操作函数和读操作函数,最后在各操作函数和各子域之间建立一个函数映射表。
在一个实例中,该写操作函数包括设置函数和清除函数,该读操作函数包括查询函数,其中:设置、清除函数在向数据库10插入、更新记录时使用,分别用于设置对应子域的bit位、清除对应子域的bit位;查询函数在向数据库10检索时使用,用于查询对应子域的bit位是否被设置。
图4示出了本发明一个实施例中解析单元21的结构,包括:
分析模块211,对用户输入的查询语句进行分析,得到与合并域中各子域对应的运算表达式。
本发明中,用户输入的查询语句可为多种。在一个实例中,用户输入的查询语句是SQL查询语句,其中包含查询域、条件域等,例如:select姓名,性别,职务from职员个人信息表where工号<=002。当然,本发明还可基于其他类型的查询语句进行操作。
设置关联模块212,与分析模块211交互,将各子域的操作函数关联到运算表达式,得到合并域的运算表达式。
在本发明中,设置关联模块212将操作函数关联到运算表达式的方式有多种。在一个实例中,当分析模块211得到与合并域中各子域对应的运算表达式之后,设置关联模块212则根据运算表达式里出现的子域名,到前述操作设置模块112所建立的函数映射表中找到相应的查询函数指针,替换相应的子域名,得到以函数指针为操作数的运算表达式,因此得到合并域的运算表达式。
图5示出了本发明一个实施例中检索单元22的结构,包括:
数据提取模块221,将合并域从数据库10中导出。在一个实例中,数据提取模块221可从数据库10中导出全部记录的查询域、合并域,由于这一步骤没有施加任何过滤条件,所以速度与数据库10的总数据量成类似正比的关系。
查询模块222,与数据提取模块221进行交互,利用运算表达式在从数据库10导出的合并域中进行查找,得到检索结果。在本发明中,查询模块222可根据不同的查询条件,进行各种类型的检索。
在一个实例中,若要查询数据库10中是否含有符合检索条件的记录,则检索方式是:查询模块222先对全部记录的合并域进行或逻辑操作,然后利用含函数指针的合并域的运算表达式在或逻辑操作的结果中进行查找,根据结果判断是否含有符合条件的记录。在该实例中,对合并域进行或逻辑操作的目的,是为了避免对每条结果的合并域都进行一次函数运算,而是在合并域进行了或逻辑操作之后只做一次函数运算,因此可以大大提高检索效率。
在另一实例中,若要查询数据库10中某条记录的详细内容,则检索方式是:查询模块222利用含函数指针的合并域的运算表达式在每条记录的合并域中进行查找,从而得到过滤结果,也即该条记录的详细内容。
图6示出了本发明一个实施例中数据库检索方法流程。包括以下步骤:
在步骤S51中,将数据库10中的多个域处理成一合并域,并对各子域进行操作设置。
在步骤S52中,根据各子域的操作设置向数据库10存入数据。
在步骤S53中,对用户输入的查询语句进行解析,得到与合并域中各子域的操作设置相关的运算表达式。
在步骤S54中,将运算表达式施加到合并域之上进行查找,得到检索结果。
图7是图5所示实施例中步骤S51的流程图,包括以下步骤:
在步骤S511中,将数据库10中的多个域处理成一合并域。
需要说明的是,目前数据库支持的域的数据类型有五种:字符型、文本型、数值型、逻辑型、日期型,实际应用中,它们的表达能力可能无法被充分利用,例如用数值型中的UNSIGNED INT类型来描述工资时,它的表达范围是0-4294967295,实际上正常使用的范围可能只是0-10000,则造成了表达能力和存储的浪费。本发明通过域合并模块111对域进行合并,实际上就是进行了压缩存储,主要目的就是为了充分利用数据类型的表达能力,避免存储的浪费。
在一个实例中,进行数据压缩后的数据表定义如下:
域 | 数据类型 | 说明 |
工号 | 数值(INT) | 工号,Index |
姓名 | 字符(char) | 职员姓名 |
出生日期 | 日期(DATE) | 职员出生日期 |
职员信息 | 二进制(bin)宽度为20bit | 含职员的性别、婚否、职务、工资。其中:1个bit表示性别(0:男,1:女)1个bit表示婚否(0:未婚,1:已婚)2个bit表示职务(00:职员,01:科长、10:处长)14个bit用来表示工资(最大可以表示10000) |
进行域合并后的职员信息域,每个子域(对应合并前的域)占据一段存储,x表示一个bit位。如图3所示。应当说明的是,实际上可以将工号、姓名、出生日期都合并到“职员信息”域中,因为任何类型的数据都可以被二进制类型表示,但工号单独被检索的可能性较大,而姓名和出生日期作为查询域的概率远大于作为条件域的概率,所以在此实例中没有被合并。另外应当说明的是,除了二进制的数据类型,还可以用其他的数据类型来合并表达多个域,如定义N个字符,其中X个字符表示职员姓名,Y个字符表示职员的出生日期,且X+Y<=N。
在步骤S512中,构建与各子域具有映射关系的操作函数。在本发明中,所称的操作函数可包括多种,例如写操作函数和读操作函数。
图8是图6所示实施例中步骤S512的流程图,包括以下步骤:
在步骤S5121中,定义子域的掩码,并构建各子域的操作函数。具体过程是:首先利用操作设置模块112定义子域的掩码,为了方便程序计算,则进一步定义写操作函数和读操作函数,最后在各操作函数和各子域之间建立一个函数映射表。
在该实施例中,写操作函数包括设置函数和清除函数,该读操作函数包括查询函数,其中:设置、清除函数在向数据库10插入、更新记录时使用,分别用于设置对应子域的bit位、清除对应子域的bit位;查询函数在向数据库10检索时使用,用于查询对应子域的bit位是否被设置。
在步骤S5122中,通过各子域的写操作函数在数据库10中插入数据或更新数据。此时则需要利用前述写操作函数中的设置函数设置子域的bit位,利用清除函数清除对应子域的bit位。
图9是图5所示实施例中步骤S53的流程图,包括以下步骤:
在步骤S531中,对用户输入的查询语句进行分析,得到与合并域中各子域对应的运算表达式。在一个实例中,该查询语句是SQL查询语句,其中包含查询域、条件域等,例如:select姓名,性别,职务from职员个人信息表where工号<=002。当然,本发明还可基于其他类型的查询语句进行操作。
在步骤S532中,根据运算表达式中的子域名得到操作函数中的读操作函数。在一个实例中,当分析模块211得到与合并域中各子域对应的运算表达式之后,设置关联模块212根据运算表达式里出现的子域名,到前述操作设置模块112所建立的函数映射表中找到相应的查询函数指针。
在步骤S533中,将读操作函数关联到各子域的运算表达式,从而生成合并域的运算表达式。在一个实例中,当设置关联模块212在函数映射表中找到查询函数指针后,则替换相应的子域名,得到以函数指针为操作数的运算表达式,因此得到包含函数指针的合并域的运算表达式。
图10是图5所示实施例中步骤S54的流程图,包括以下步骤:
在步骤S541中,从数据库10中导出合并域。在一个实例中,数据提取模块221可从数据库10中导出全部记录的查询域、合并域,由于这一步骤没有施加任何过滤条件,所以速度与数据库10的总数据量成类似正比的关系。
在步骤S542中,调用合并域的运算表达式。在一个实例中,查询模块222从设置关联模块212中调用包含函数指针的合并域的运算表达式,用于进行不同检索条件下的查询。
若查询记录M是否存在于数据库10中,则:
步骤S543,对从数据库10中导出的合并域进行或逻辑操作。
步骤S544,利用运算表达式在该合并域的或逻辑操作结果中查找记录M。在该实例中,对合并域进行或逻辑操作的目的,是为了避免对每条结果的合并域都进行一次函数运算,而是在合并域进行了或逻辑操作之后只做一次函数运算,因此可以大大提高检索效率。
若查询记录M的详细内容,则包括:
步骤S545,将运算表达式施加于每条记录的合并域之上,得到过滤结果,也即该记录M的详细内容。
本发明还提供了一个实例。假设某数据库表的定义为如下表:
域 | 数据类型 | 说明 |
ID | UNSIGNED INT | 流水号、Index |
Attr1 | char | 属性1 |
Attr2 | char | 属性2 |
Attr3 | char | 属性3 |
Flag1 | BOOL | 标志1 |
Flag2 | BOOL | 标志2 |
... | ... | ... |
FlagN | BOOL | 标志N |
设该表有N=64个Flag(标志),且都是BOOL类型的,取值为true或false,是一个开关型的域。表的记录条数为100万,ID、Attr1、Attr2、Attr3是查询域(即经常被查询,但很少作为过滤条件),Flag1-FlagN经常被作为条件域。
假设有一个检索请求:select Attr1、Attr2from Sample where(Flag1&&Flag3‖(Flag2 &&!Flag4)&&!Flag5)&&!(Flag5‖Flag6 &&!Flag4)...,检索条件包含的域非常多,与或非的运算非常复杂,那么常规的检索方法将耗费很长的时间;如果对Flag1-FlagN都建索引,则在大数据量的情形下将增加不少存储,即便如此,速度仍然比较慢。
采用本发明的方法,具体处理过程如下所示:
将Flag1-FlagN合并到一个域,定义为Flag,使用二进制类型(或8字节的长整数),宽度为64bit,每个子域(Flag1-FlagN)占据一个bit,0表示False,1表示true。
定义每个子域(Flag1-FlagN)的掩码:宽度为64bit的长整数(8字节),每个bit代表一个子域(Flag-FlagN),某个bit为1(其余bit均为0)的长整数即是相应的Flag的掩码,如第一个bit为1的长整数是Flag1的掩码。
为了方便程序运算,在掩码的基础上,定义一组函数:bool IsSet(char*Flag Name)、void Set(char*Flag Name)、void Clear(char*Flag Name),分别用于判断某个Flag是否被设置、设置某个Flag的bit位、清除某个Flag的bit位,Flag Name的取值范围为Flag1-FlagN。
定义Flag到函数的映射表:isset_map<Flag Name,IsSet*>,set_map<FlagName,Set*>,clear_map<Flag Name,Clear*>,根据Flag Name可以找到对应的IsSet、Set、Clear函数指针。
插入、更新记录时,若某个Flag需要被设置,则根据子域名Flag1-FlagN到set_map里找到Set函数,若某个Flag需要清除,则到clear_map里找到Clear函数,然后将Set或Clear函数施加到合并域上,即完成对应子域的bit位的设置或清除。
分解检索请求,为方便描述,只取前6个Flag,即Flag1-Flag6。得到查询域:Attr1、Attr2,条件域:Flag1-Flag6,并得到运算表达式:(Flag1&&Flag3‖(Flag2&&!Flag4)&&!Flag5)&&!(Flag5‖Flag6&&!Flag4)。根据Flag Name到isset_map里找到Flag1-Flag6的IsSet函数,假设为F1-F6,则表达式可以被转化为含函数指针的表达式:(F1&&F3‖(F2&&!F4)&&!F5)&&!(F5‖F6&&!F4)。
从数据库10中导出全部记录的Attr1、Attr2、Flag(合并域)到内存,遍历每一条记录,对该记录的Flag域的值进行运算:(F1(Flag)&&F3(Flag)‖(F2(Flag)&&!F4(Flag))&&!F5(Flag))&&!(F5(Flag)‖F6(Flag)&&!F4(Flag)),计算结果为0或1,表示该记录应被过滤或输出。
对于某些查询,例如只需要知道数据库10中是否有符合条件的记录,而不需要知道具体哪条记录符合条件时,直接将全部记录的Flag域进行或逻辑操作,得到一个汇总的Flag,然后将含函数指针的运算表达式施加在这个汇总的Flag上,计算得出1或0,即存在或不存在,这是一个非常快速的过程,比常规方法的效率要高出很多。
以上所述仅为本发明的较佳实施例而已,并不用以限制本发明,凡在本发明的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明的保护范围之内。