值一实例连接的计算机实现的数据库的制作方法

文档序号:6419142阅读:198来源:国知局

专利名称::值一实例连接的计算机实现的数据库的制作方法
技术领域
:本发明总体涉及计算机实现的数据库,特别是涉及一种的多维数据的高效、有序、节省空间的表示。现有技术水平的数据库管理系统(DBMS),像它们历史上所出自并在其上面成长的基础性数据文件一样,继续以密切反映用户的数据观的方式存储和处理数据。用户一般将数据视为一系列的记录(或“元组”),每个记录逻辑上由固定数量的、含有关于该记录所描述的实体的特定内容的“字段”(或“属性”)组成。这个观点自然地由一种逻辑表(或“关系”)结构(本文称之为“基于记录的表”)-诸如直线网格-来代表,其中的行代表记录,列代表字段。在没有普遍认同的缺点的情况下,基于记录的表和它们与传统性用户观的一致长期存在,这致使它们被近乎普遍地接受为是数据库的主要基础性内部表示。然而基于记录的表含有关键的结构性弱点,包括传统上被视为不可避免的高度的无序性和冗余性。例如,可以将这种表可以按最多一个准则(根据列值或者列值或多重列值的某个函数)进行排序或分组(即相同值的邻接定位)。这个限制使按这个特权标准以外的所有其它准则进行的诸如查询和更新的基本数据库功能拙苯且过分耗费资源。以上缺陷是基于记录的表结构的根本属性中固有的,特别是要求使每个字段的定位与同一记录中所有其它字段共线(co-linear)这个缺陷。在基于记录的表结构中对字段的这种随意定位,排斥所有其它安排。它因此使由更有序、紧凑和高效的数据安排所揭示的自然和可利用的潜在数据关系模糊不清。此外,基于记录的表缺乏有效地对数据分组和排序的能力,这导致现有技术水平的数据库管理系统具有负面特点,诸如无序、冗余、不方便、算法低效和性能不稳。数据库研究提供了减轻这些问题的手段,但是不能揭示和解决它们的根本原因(即对基于记录的表结构的依赖)。例如,由于不能在基于记录的表结构内表示自然、多维的组合而导致了基于索引的数据结构。这些辅助性结构固有地并经常大规模地冗余,但是它们能建立用常规的表不能直接表现的组合和排序。基于索引的结构一般增长得过分冗长、迂回,不方便于维护、优化,尤其不方便于更新。常见索引的例子是b-树、t-树、星-索引(star-indexes)和各种位图。现有技术中开发的其它辅助性结构都有不同的缺点。例如,散列表能提供对个别数据项的快速查询,但由于它们缺乏排序次序,不适合范围查询或要求以特定次序返回数据的任何其它操作。用灵活的排序和/或分组准则维护一个有序、不冗余的多维数据集合的能力,对数据库管理极其有用。排序的数据通过例如二进制检索算法和插入排序,使快速检索和更新成为可能。分组的数据使得能够进行减少空间需求并进一步提高例如检索和更新的速度的压缩。因此极其需要这样一种数据存储系统,在该系统中,数据表的大多数或全部的列能以分组的和/或排序的次序存储。以前的研究调查过“完全倒置数据库”,该数据库通过传统方法索引每个列,保留了记录和索引的所有不足。此外,为容纳完整的索引所需的膨胀的存储条件会使全倒置数据库不实用-特别是(但不仅仅是)在主存储器数据库中。因此本发明的一个目的是提供一种没有如上所述的现有技术的缺陷特点的、全部或部分有序的(即分组和/或排序的)数据库。简而言之,本发明不是将数据库构造成像以前的数据库那样的表的形式-表中的每个行是一个记录,每个列含有该记录中的字段,而是置换(permute)或是修改各列,以提供例如在空间利用和/或存取速度方面的益处,使得各行不再必须对应于各记录。例如,一种这样的修改是通过去除冗余值来压缩列(这减少存储器的占用);另一个修改是对列排定次序,保证值组将总是以某特定次序出现(这能大大地缩短检索有特定值的列所需的时间);还有另一个修改是对列既压缩又排序。其它具有其它优点的排列和修改也是可能的。排列/修改过的值的表在本文中被称作“值表”。逻辑上,尽管未必物理上,单独的数据结构提供重构数据库中的“记录”所需的信息。特别地,它们提供“实例”和“连接”信息,实例信息标识记录内字段中每个值的实例,连接信息将每个实例与至少在另一个字段中的值的特定实例相关联。在本发明的一个实施例中,实例和连接信息二者都在一个本文称作“实例表”的表中提供。实例表中每个列对应于数据库中记录的一个属性,并与值表中含有该属性(以及可能的其它属性)的值的列相关联。实例表中的每个单元(行/列位置)有一个位置(在本发明一个实施例中,是其行号)和一个实例值(单元的内容)。值表中相关列中的相关单元是从各个单元的位置导出的。属于相同记录的实例表的另一个列中的相关实例单元也是从每个实例单元的实例值导出的。所以在本实施例中,实例单元的位置标识该单元是其一个实例的值,实例单元的内容提供将该实例与另一个字段中的另一个实例单元相关联的连接信息。然后就可以从实例表中某单元开始,通过从该单元的位置、值表中相关的值单元以及该单元的实例值导出相关实例单元的位置,重构一个记录,并在相关实例单元重复这个过程等等-在一个实施例中,链中的最后单元提供起始单元的对应位置。如果值表的一列被排序,但是没有被压缩,则该值表列和实例表中的相关列-在本发明的一个实施例中-由相同的行数。在这一个实施例中,实例单元的相关值单元是相关值表列中与实例单元有相同行号的值单元。实例单元的相关实例单元(即属于同一记录的实例表的另一列)是具有由实例单元的实例值给出的行号的特定列。在一个实施例中,该特定列是实例表中的下一列,其中最后一列指回到第一列。例如,如果值表的列1是未压缩的,排列后,值表的列1、行2和列2、行5属于同一个记录,并且列2、行5的一个实例位于实例表的列2、行5,则实例表就在列1、行2含有数字5(指出下一列的行5属于同一个记录)。如果值表列是压缩了的,则在该列与与其关联的实例表列之间一般没有一对一的对应。在这种情况下,提供一个本文中称作“位移表”的表,在本发明的一个实施例中,该表有对应每个与一个压缩值表列相关联的实例表列的列,并规定值表列的每行相关联的实例表行号的范围。与实例单元相关联的值单元然后由相应的位移表列根据该实例单元的位置(行号)确定。在一个实施例中,一个位移表列有与相关的值表列相同的行数,位移表中的每个单元提供与相应的值单元相关的实例表行号范围内的第一行号。或者,位移表中的每个单元例如也可以提供实例表行号范围内最后行号,该范围的总行数,或者有可能由其导出与每个值单元相关的实例表行号(即每个值的实例)的范围的某个其它值。上述的位移表的一个缺点是,如上所述,在位移表中检索对应某实例单元的值单元,降低记录重构的速度。这个缺点在本发明的另一个实施例中被解决,在该实施例中,将相关实例单元位于一个有位移列的列中的实例单元的实例值设置在与该相关实例单元相关的值单元的位置(而不是如上述实施例中那样在该相关实例单元本身的位置)。于是不检索位移表就能直接获得相关实例单元的值。在本实施例中,一个本文称作“出现表”(occurrencetable)的表提供用于确定相关实例单元的信息。在出现表的一个实施例中,实例表中每个有具有上述实例值的单元的列在出现表中有一个有相同行数的相关列。在本实施例中,出现表中的单元根据其位置与实例表中的单元相关联,并规定一个位移量。将该偏移量加上与值单元相关的实例表行号的范围中的第一行号,就到达相关的实例单元。第一行号是根据实例单元的实例值由位移表导出的。实例单元的连接信息于是在本实施例中就通过该实例单元的内容、出现表和位移表而提供。本文中所描述数据结构可以(但不必)整个位于RAM中或分布在由多个数据处理器组成的网络上。它们也可以以各种方式实现,本文的发明决不限于特定实现给出的例子。例如一个实施例可能只用本文所述的计算机实现的数据库和方法部分地存储数据集合,其余数据则用传统的基于表的方法存储。信息可以按各种格式存储,本发明不限于任何定格式。特定列的内容可以由函数由与其它储存信息组合的函数或者由包括位图的任何形式的储存数据来表示。更概括地说,尽管值表、实例表、位移表和出现表被描述成是具有行、列和单元的“表”,本发明并不限于这种结构。可以用任何计算机化数据结构在这些表中存储信息。例如,上述的值表是“值存储区”的具体例子(即,它在数据库中存储代表用户观点的信息的值的数据值);实例表是“实例存储区”和“连接存储区”的具体例子(即,它既标识值存储区中数据项的实例,又表现值存储区中数据项的实例之间的关系);位移表是“基数存储区”的具体例子(即,它表示数据值的相等实例的出现频率)。表的列是“列表”或更概括的“集合”的具体例子。在本发明中,一个“集合”包含一个或多个“元素”,每个元素有一个或若干值和一个“位置”,其中“位置”规定元素在集合中的位置。在以上讨论中,表的列中的单元是“元素”的例子,其在集合中的位置是其行号。此外,尽管本发明所述的实施例涉及并处理传统的“记录”,本发明并不限于记录,而是普遍适合表现数据值之间的关系。所有这种变异都是本发明的可替代的实施方案。本发明所支持的典型的数据库操作包括-但不限于1)重构物理记录;2)发现记录匹配查询准则;3)以标准方式联接(join)表;4)删除和/或添加记录;5)修改现有记录;和6)为执行有用的任务对这些和其它标准数据库操作的组合。本发明提供一种新的有效的方法来构造数据库,使得能高效地进行查询和更新处理,降低数据库存储要求,简化数据库的组织和维护。本发明不是通过增加冗余(即除原始的无序的数据表示之外,添加相同数据的有序表示)来取得有序性,而是在根本上消除冗余。这降低了数据库存储要求,从而使更多数据能同时在RAM中存储(增强应用性能,减少硬件花费),并且,这加快了数据库在通信网络上的传输速度,使高速主存数据库对广泛的商业和科学应用切实可行。没有全倒置数据库中所见的开销就有可能进行快速的查询处理。此外,有了本发明的数据结构,数据比传统数据库中的更加容易处理,因为常常只要改变实例表中的某些条目,而不复制数据。因此用本发明进行数据库操作总体上更加高效。此外,某些用面向记录的结构计算强度大的操作,如直方图分析、数据压缩和多重排序,可以从本文中所述的结构直接获得。本发明也提供并行计算环境中改进的处理。本发明的数据库系统可被用作与采用标准中间件(例如微软公司的开放式数据库连接(ODBC:OpenDatabaseConnectivity)或微软公司的Active-X数据对象(ADO:Active-XDataObjects))的几乎任何数据库前端兼容的有效数据库的后端。或者,可以通过例如C++函数、模板和/或类库直接地实现一个本机独立引擎(nativestandaloneengine)。无论是以中间件的后端还是以独立引擎实现的,本发明都提供一种用户看起来熟悉、但内部管理方式新颖高效的的数据库。图1是本发明一个实施例的框图;图2表示一个简单的环形拓扑;图3表示一个具有带桥字段(bridgefield)的子环的拓扑;图4表示一个“星型”拓扑;图5是表示查找与一个实例表单元相关的值表单元的例程的流程图;图6表示一个确定当前列是V/O拆分的下一列的行的例程;图7是表示将记录的拓扑数据变换为线性阵列的流程图;图8是表示向实例表写入线性化记录拓扑的过程的流程图;图9表示实例表中两个记录的单元的互换的流程图;图10是表示以有用的单元交换被删除的单元的流程图;图11是表示对于实例表中给定值的实例单元查找紧邻被删除单元(如果有的话)的未删除单元(如果有的话)的流程图;图12是表示将实例表中的自由(被删除实例)单元从其原始的相关值移动到紧邻的前一个值的流程图;图13是表示将实例表中的自由(被删除实例)单元从其原始的相关值移动到紧邻的后一个值的流程图;图14是表示确定给定值的实例(包括被删除实例)的总数的流程图;图15是表示删除实例表中以前有用的单元的流程图;图16是表示当指入一个值表列的指针不是V/O拆分的时向该列插入新值的流程图;图17是表示当指入一个值表列的指针是V/O拆分的时向该列插入新值的流程图;图18是表示自由(被删除)实例表单元向值表中的给定值的分配的流程图;图19是表示删除记录操作中的步骤的示意图;图19是表示添加记录操作中的步骤的示意图;图19是表示修改记录操作中的步骤的示意图;图19是表示查询操作中的步骤的示意图;图23是表示连接操作中的步骤的示意图。图1表示本发明实施例的基本硬件设置。程序储存器4是一个含有执行本发明数据库系统的功能的软件的存储器,如硬盘。这个软件例如包括用于生成基础数据库的数据结构的例程和用于将诸如面向记录的文件中的那些传统数据库重新格式化成这些数据结构的例程。此外,软件还包括用于控制和存取数据库的例程,诸如查询、删除、添加、修改和连接例程。数据文件存储在存储器2中,含有与一个或多个数据库相关联的数据。数据文件可按本文的数据结构的二进制映象或者按面向记录的文件格式化。程序储存器4和存储器2可以是单一存储器的不同部分。程序储存器4中的软件由有随机存取存储器(RAM)的处理器5执行。对要由数据库系统执行的任务的选择由用户或用户站6决定。在以下讨论中,术语“指针”用来在笼统的意义上既包括C/C++语言的含义(含有存储器地址的变量),也更概括地包括用于唯一地描述存储器中位置(无论存储器是RAM还是磁盘等等)的任何数据类型。一个以自给定数据结构的起始算起的整数位移量实现的指针将执行与C/C++相同的功能,与此同时有要求较少存储空间的好处。本文中所用的存储器指的是任何存储数据的电子、光学或其它装置。本文用术语“多维的”在数学或准数学的意义上指这样一种数据观,即将n列的基于记录的表视为占据一个n维的向量空间。不是使用该术语在数据储存和在线分析处理(OLAP)中被使用的更狭窄的意义-此时多维性指的是数据分析的多层次。基本数据结构在现有技术的数据库中普遍使用的基于记录的表中,每行代表一个记录,每列是记录中的一个字段。按照本发明的数据库不同于这种已知结构。在一个实施例中,将数据库划分成两个基本数据结构一个未压缩的值表和一个实例表。值表含有与现有技术的数据库相同的数据实例,但是每列可以被改序或以其它方式修改,由此,一个行不再必定对应于一个特定记录。按照该实施例,实例表提供用于由值表重构记录的手段。具体来说,在一个实施例中,实例表有与未压缩值表的相同的行数和列数,实例表中的每个单元(即行/列位置)含有同一记录中下一个字段的行号(“下一个”在下文定义)。这样,含有值-表(r,c)的记录的下一个字段的值-其中r和c是值表中特定位置的行和列,是value_table(instance_table(r,c),next(c)),其中instance_table(r,c)是下一个字段的行号。函数next(x)从当前列得出下一列。在本发明的一个采用环形拓扑的实施例中,next(c)=((c+1)modn),其中n是列数,该列数从0计到n-1(基于零的下标)。在另一种形式的实施例中(列从1计到n),next(c)=cmodn+1。各种拓扑都是可能的,每个都有相应的next(c)函数。例如,以下是标准的“一行一记录”格式的、以1为基础行号的数据库现有技术的数据库按照本发明特定实施例的对应的值表和实例表是值表(Value_Table)实例表(InstanceTable)以上显示的值表是通过对每列(在本例中按字母顺序)排序而创建的。仅为解释目的,在每个值后边设置一个上标,指示其在原始数据库中的记录号。在将各列排序后,值表中的一行一般将不与原始数据库中的一个记录对应。然而实例表却提供将这些记录重构成传统记录的外观所必需的信息。具体来说,在以上实施例中,将实例表中的每个单元(即行/列位置)与一个记录相关联。具有与值表中的相同的行/列位置的单元含有与该列的相关字段的记录的值。实例表单元本身含有该记录的下一个字段的行号。例如,假设要重构含有实例表的“英语”列(列0)的行1的记录。值表中的相关单元(即行1,列0)含有值“Five”。如果顺序地提取其它字段(或列),首先被确定的就是与“英语”列(列0)的行1属于相同记录的“西班牙语”列(列1)。这个信息是由实例表在行1/列0的位置提供的,此例中该位置含有数字1,意思是西班牙语列的行“1”与该英语列的行“1”位于相同的记录。下一步,为了确定“德语”列(列2)的来自相同记录的行,读取实例表中的行1/列1,该位置含有数字3,意思是“德语”列的行“3”是来自相同记录的。通过实例表中“德语”列(列2)的行3跟踪这个记录,能得出相同记录中“类型”列(列3)的行,它含有数字5-意思是“类型”列的行“5”来自与“德语”列的行3的相同的记录。“类型”列(列3)的行5指示在“奇偶”列(列4)中对应的行是行6。最后,“奇偶”列(列4)的行6指示,从“英语“列即表中第一列(列0)的对应行是行1,这是该过程开始的地方。这是因本例中所用的是环形拓扑的缘故。所以,按照以上解释的实施例,实例表中的每个行/列位置都含有属于相同记录的下一个列的行号,最后一列中含有相同记录的第一列的行号。在该实施例中,属于相同记录的行/列位置之间的连接,将形成一个贯穿实例表的环-如图2中所示的那样。如果遍历这个环,用值表中直接对应的行/列位置就能恢复每个字段的值。在本发明其它形式的实施例中也可以采用除环以外的拓扑。从面向记录的数据生成值表和实例表按照本发明,可以用现有技术的面向记录的数据库格式的数据生成值和实例表。第一,通过排列或以其它方式改变原始数据库的每列中的数据,创建值表。在值表列中的改变的例子是对数据排定顺序,将相似的值组合在一起。不同的列可以按不同方式进行排列和改变。应根据其在实际应用中是显示还是检索的用途选择排序顺序。对可能的排序次序的要求是,它有一个可计算的排定值的顺序的判定。有些列可以不排序。在以上的例子中,所有列都是按字母顺序排序的。在一个实施例中,在该第一步骤期间,生成一个临时中间表(Intermediate_Table),以方便在以下的第二步骤中生成实例表。该实施例中的中间表有像原始的现有技术数据库中那样的对应于记录的行和指示值表中相应字段的排列位置的列。上述例子的中间表(其中的排列是排定次序)如下所示中间表这样,例如,中间表指出,原始记录5的“英语”字段在值表的行1中,原始记录5的“西班牙语”字段在值表的行1中,原始记录5的“德语”字段在值表的行3中,原始记录5的“类型”字段在值表的行5中,原始记录5的“奇偶校验”字段在值表的行6中。然后按照该实施例,对于中间表中的每个行r和列c,如下地确定实例表Instance_Table(Intermiate_Table(r,c),)=Intermediate_Table(r,next(c)),其中next(c)是上文定义过的。换言之,中间表中的每个单元规定实例表中的一行相应的列;实例表中的该行接收中间表的下一列中的值。例如,参看上例中的记录号5,中间表中的“英语”字段(列0)含有数字1,下一字段“西班牙语”(列1)也含有数字1。根据该信息,将值1(即在排序的值表中记录5的“西班牙语”字段的行号)放置到实例表的行1(即排序的值表中记录5的“英语”字段的位置)中。将实例表中“西班牙语”字段的行1设置成中间表中记录号5的“德语”字段(列2)中的值(即值3),该值相当于“德语”字段在排序的值表中的行号。对每个字段重复这个过程,最后一个字段还是回绕到第一个字段。本领域的熟练人员将会认识到,存在用于生成实例表的等同算法,有些有可能避免使用中间表,本发明并不限于这里所表示的算法。压缩值表在某些情况下,如果通过去除冗余值而“压缩”某些列,就空间(例如存储器或磁盘占用)而言能更有效地表示值表中的数据。例如,在以上的值表中,“奇偶校验”字段只有两种不同的值(“Even”和“Odd”),“类型”字段只有四种不同的值(“Compos”、“Power2”、“Prime”和“Unit”)。(将给定字段的唯一性值的个数称为该字段的“基数”。)相应地,在本发明最佳实施例中,通过构造一个压缩值表,就能去除冗余。对应上例的压缩值表如下所示压缩值表(CondensedValueTable)为了实现这种空间节省,必须以适当方式为值表分配存储区;例如,将每列分配成单独的向量或列表,而不是将表分配成二维数组。此外,向列应用的改变应当将相等的值组合在一起。为了保留未压缩值表的原始信息,最佳实施例中提供另外一个结构-本文中称作“位移”表。在本发明的一个实施例中,位移表提供列中的唯一性值在原始未压缩值表中出现的位置的第一行或最后行的行号(本文中分别称作“首行号”和“末行号”格式)。例如,对应上述压缩值表的位移表如下所示(按“首行号”格式)位移表(DisplacementTable)位移表的“奇偶校验”列因此指出,压缩值表中第1行中的值(即“Even”)原来在未压缩值表中的行1中(即,值“Even”首次出现的行1中),压缩值表中第2行中的值(即“Odd”)原来在未压缩值表中的行4中。另一种形式可以是将每个值的记录计数存储在位移表中,每个值的首行是以算术方法导出的,或者,可以采用该计数和位移的某种算术组合。一个有W个字节宽的字段和基数C(即C个唯一性值)的列,由一个唯一性值的“压缩”列与一个大小为P个字节的、整数值(行号)的位移表一起表示,而未压缩列的存储区则要求有W×N个字节(其中N是记录数)。所以,如果W×C+P×C<W×N,或者C<N/(1+P/N)时,这种压缩就有益。该实施例中的压缩列完全打破了实例表的单元(即行/列位置)与值表的单元之间的一一对应。所以在记录重构期间,遍历实例表时就不能简单地通过查找值表中相同行/列位置的值来检索某单元的值。例如,在值表中与上述例子中的实例表的列3(“类型”)、行5相同的行/列位置不再有一个单元。但是按照最佳实施例,与Instance_Table(r,c)相关的字段的值(其中c是一个压缩列)由Value_Table(disp_row_num,c)给出,其中disp_row_num是位移表中满足下述关系式的第c列的单元的行号对于“首行号”位移表格式来说,该关系式为Displacement_Table(disp_row_num,c)<=r<Displacement_Table(disp_row_num+1,c)其中,如果disp_row_num+1不存在(即如果disp_row_num是列c的最后位移表行)则不进行上限测试(upper-boundtest);或者对于“末行号”位移表格式来说,该关系式为Displacement_Table(disp_row_num-1,c)<=r<Displacement_Table(disp_row_num,c)其中,如果disp_row_num不存在则不进行下限测试(lower-boundtest)。再次参照以上的例子,要查找值表中与列3的行5相关的值,就要定位到位移表的列3中有不大于5的最大值的行。那就是上述位移表中的行3(行4有大于5的值6)。所以,值表中的列3的行3有与实例表中的列3的行5相关的值。适合于某些数据类型的空间节省技术按照特定的实施例,不用以上描述的某些结构(即值表、位移表和/或实例表)就能把带有有某些属性的数据的字段纳入本发明的数据库系统。如果要被包含在这些结构中的信息已经以暗含的形式存在于该系统中-就是说,该信息是可以从已经存在的数据或其它信息推导出来的,则情况就是如此。例如,如果某未压缩值表列含有从1到N的数字,就根本不需要在值表中存储该信息,因为该信息隐含在实例表中(实例表的行1对应于值1,等等)。每个列(字段)描述符(descriptor)的信息申明对该字段隐含哪些结构和何处及任何获得隐含数据。在刚刚给出的例子中,实例表列的列描述符申明对应于每个行的值是行号。该数据于是就能在本文所述的算法中或者这些算法的其它实现中被应用。如果存在“隐含”结构能被使用的特殊情形,则能实现空间节省。这种情形的例子包括(但不限于)以下情形1)具有唯一性值的字段,不要求有位移列表(list),因为该字段值列表只在实例列表中出现一次;2)具有相邻的、唯一性的与值表的行的范围相同的整数值的字段,不要求有值列表和位移列表。这些值将被排序,使得它们的值要等于它们在值列表中的位置,该位置也就是它们在实例列表中的位置。所以,它们的值等于它们在实例列表中的位置(行),因此不需要单独的值列表。由于这些值是唯一性的,也不需要有位移列表。3)具有是相邻整数输入值的一个函数的输出值的值的字段,如果该函数是以有序的输入产生有序的输出(例如就像单调函数那样)的,则不要求有值列表。通过对实例表中单元的位置(行)应用该函数就能计算出各值。由于行位置是有序相邻整数,函数的输出将也是有序的。所以,不需要值列表,因为各值可以从实例表计算出来。由于函数的输出值对唯一性的输入总是唯一性的,也不需要有位移列表。4)具有是通过相邻整数输入值的一个函数的输出值近似出来的值的字段,如果该函数是以有序的输入产生有序的输出(例如就像单调函数那样)的,则可以用一个节省空间的值列表来实现。这种情况下的值表只需要含有该函数的输出的偏移量,而不是整个值,其排列使得各偏移量与该函数的各输出相加后得出各有序值。5)全部与相同数据值相关并且全部有与相同数据值相关(例如下一个)的实例列表元素的一系列相邻的实例列表元素,可以在对位移列表作适当调整后,用单一的条目来表示-该条目例如标识该相关数据值、该相关实例元素的相关数据值的位置和该系列中实例元素的数目。此外,已知的压缩和空间节省技术可以应用于值表和实例表(和其它结构)。例如,对值的表示可以采用字典类型的方法,包括匹配小于值的整个长度的位模式(bitpattern)的方法。这个压缩和以上压缩技术的一个效果是产生更随机的位模式,这进而提高散列性能。此外,对值表、实例表和其它结构的压缩,例如也可以用利用重复位模式的方法,诸如行程编码(run-lengthencoding)和字紧致(wordcompaction)(就是说,当值的大小与物理存储单元失配时将值紧缩(packing)到物理数据存储单元中)。对于实例表,如果允许的话,例如可以通过对列的相对位置和列内的实例的重新定序而进一步压缩,以使以上压缩技术最优化。选择性的带压缩值表的实例表以上讨论的位移表降低记录重构的速度,因为只有在搜索位移表后才能从压缩列获得值。本发明另一个实施例中使用一种选择性的配置,是要修改实例表,使得列中的条目指向一个压缩列点,而不是直接指向值表。于是提供另外一个本文称作“出现”表的表,该表含有能由其计算出实例表中下一列的行号的信息。“出现”表含有由实例表中相应单元指向的特定值的出现次数。具体来说,在一个其中的位移表是“首行号”格式的实施例中,实例表中的行数是基于1的,出现表也是基于1的,下一个字段的实例表行号等于Displcae_Table(r,c)+Displacement_Table(Instance_Table(r,c),next(c))-1。该实施例的变数包括(但不限于),在各种结构中基于零的行编号,和/或在出现表中基于零的行编号,和/或位移表条目的“末行号”格式。这些变数上述用于确定下一个字段的实例表行号的公式。例如,对于出现表和实例表中基于零的行编号、位移表中基于零的行编号和“末行号”格式来说,下一个字段的实例表行号是如果Instance_Table(r,c)=0,则为Occurrence_Table(r,c);如果Instance_Table(r,c)>0,则为Occurrence_Table(r,c)+Displacement_Table(Instance_Table(r,c)-1,next(c))+1,(因为Instance_Table(r,c)-1,next(c))是前一个值的最后行号)。在所有这些实施例中,可以将实例表和出现表合并成一个有两部分元素的表。在以上实施例中,“类型”列指入实例表的“奇偶校验”列,值表中的“奇偶校验”列是压缩的。按照这个选择性的实施例,实例表和出现表如下所示选择性实例表(AlternativeInstanceTable)出现表(0ccurrenceTable)这样,实例表的“类型”列现在直接指在“奇偶校验”列在值表中的相关行。例如,上述实例表的行2处的“类型”列含有2,意思是值表中“奇偶校验”列的行2含有与“类型”列的行5相关的相同记录的“奇偶校验”值。此例中,“奇偶校验”列的行2含有值“Odd”。实例表中“奇偶校验”列的相关行是出现表的“类型”列的行5中的值加上位移表的“奇偶校验”列的行2中的值减1,即3+4-1=6。以上是将值表、实例表、位移表和出现表按分开的存储表来说明的。然而,选择性实施例中,这就不必是这样。例如,用压缩值表,可以将值表和位移表的元素相邻地存储在那些列中,同样能将实例表和出现表的元素相邻地存储在那些列中。这可以在从数据库检索数据时减少存储器高速缓存未命中,也通过让相邻的元素共享相同的存储基址而减少操作数提取时间。交叉(skewering)或嵌套排序对于给定的值和位移表,有许多可能的生成相同记录集合的实例和出现表。这是因为,对于某个有多个出现的值来说,该值的出现可能被以任意顺序分配给有该值的物理记录。一般来说,各个值的重数的阶乘的积,就是生成相同物理记录集合的实例/出现表的数量。(所以,生成以下给出的SPJmod数据库的不同的实例/出现表有414,720个(3!×1!×3!×1!×2!×1!×2!×5!×2!×1!×3!×2!×1!)。)在环形拓扑中,存在唯一的同时存储N多键“词汇”排序(N是数据库中属性的个数)、开销不多于存储各个排序的列(本文中称作“交叉”的特征)所要求的开销的实例/出现表示。每个列c定义一个这样的排序,使得该列被作为键中最重要的属性,next(c)作为下一个最重要的属性,等等,直到作为键中最不重要属性的列prev(c)(其中prev(c)是环形结构中的前一列)。本文中将该排序称作“词汇”,是因为它是用来按字母顺序对词排序的相同类型的排序,就是说,按第一字母对词排序,然后对具有相同第一字母的词按第二字母排序,如此等等。以下从标明的现有技术的表SPJmod(摘自C.J.Data的数据库选通导论(IntroductiontoDatabaseSystems)第六版,封面内,1995年)开始,解释交叉SPJmod按照上述最佳实施例,SPJmod的压缩值表和位移表是值表位移表以下显示三个各重新生成SPJmod的物理记录集合的选择性实例/出现表。实例和出现表被显示成单一的带有实例/出现的形式的条目的组合表。值表中的每个值相应于实例/出现表中单一一个连续块,它由该值的位移表中的条目定义。这些条目由以下实例/出现表中高亮指示。实例/出现(版本1)实例/出现(版本2)实例/出现(版本3)在版本3中,每个值块内的条目都是根据它们的实例和出现排定顺序的。N(这里是4)个多键定序由SPJmod自然地定义为(S号、P号、J号、数量)、(P号、J号、数量、S号)、(J号、数量、S号、P号)、和(数量、S号、P号、J号),其中各字段是从左至右按重要性的降序排序的。在现有技术的记录类型的表结构的数据库中,要以这些顺序的任意一种顺序重构记录,就要有空间-时间的折衷。如果要快速地并在线性时间内重新生成记录,则要求有四个单独的索引来规定四种不同的排序次序。为了避免这种对空间的冗余使用,每次改变所用的词汇次序时都要求进行一次费时的搜索。交叉(skewered)实例/出现消除了这种折衷。在线性时间内可以生成任何自然的词汇顺序。例如,要重新生成次序(P号、J号、数量、S号),就自上而下地处理列“P号”中的单元,重构对应于每个这种单元的记录。这些记录将是按所希望的词汇次序排好的。为解释起见,假设对应于列“P号”中的单元0000至0006的记录为列“P号”的单元0000->S5P2J2200列“P号”的单元0001->S2P3J2200列“P号”的单元0002->S2P3J5600列“P号”的单元0003->S3P4J2500列“P号”的单元0004->S2P5J2100列“P号”的单元0005->S5P5J5500列“P号”的单元0006->S5P6J2200类似地,通过自上而下线性地处理选定词汇次序的最重要列的整个单元,就能重新生成N个词汇次序的任何次序的记录。如果值表的列是如前文所述的那样排序的和压缩的,通过在任何列开始创建一个多键词汇次序就能生成一个交叉实例/出现表。其它N-1个多键词汇次序自动产生。在本发明的数据库系统内保留标准数据库格式本发明允许选择在不引起显著的额外开销的条件下维护部分传统形式的数据库。例如,对于某个不能压缩和将不查询的列来说,可能希望这样。下面展示一个示意性的实施例。为了这个解释的目的,把一个将不被转换到本发明的数据结构中的“法语”列添加到如下所示的原始的现有技术数据库现有技术数据库不是在位移表、实例表和出现表中为该“法语”列建立单独的列,而是将该“法语”列“附加”到其它列的其中一列上-这些列的位移表、实例表和出现表在前文展示过。首先,选择要在其上“附加”该“法语”列的一列;为此可以选择数据库中的任何一列。本例中,选择了“奇偶校验”列。当重构数据库的记录时,在确定该记录的“奇偶校验”值的同时检索“法语”属性的适当值。为了把“法语”列附加到“奇偶校验”列上,在“值-表压缩”之前,将值表中的“法语”单元按照与“奇偶校验”单元相同的次序排序。由于这个操作是在按照本发明的数据结构的构造期间执行的,所需的额外努力的量可以忽略。然后将排序的“法语”列附加到压缩值表中,如下所示值表在一个实施例中,位移表、实例表和出现如下所示位移表实例表出现表现在例如重构对应于查询英语=“Three”的记录。该记录在现有技术数据库中是由给出的。为了由以上的数据结构重构这个记录,首先找到值表的“英语”列中的值“Three”,然后通过跟踪搜索整个实例表,重构该记录中其余属性。在“奇偶校验”列的实例单元,对应于该记录的“法语”值,是值表中“法语”列的对应单元中的值。本例中,实例表的“奇偶校验”列的行5中的条目是与正在重构的记录关联的。所以,在值表的“法语”列的行5找到“法语”值,其值是“Trois”。另一种形式是,可以将未排序的列,加入本发明的数据结构,方法是用恒等排列作为该列的排列。(就是说,该列的值表将不作任何重新排序)。列合并压缩按照本发明另外一个实施例,可以将独立的值表列合并到单一一列-本文中称之为“联合列”,每个原始列有单独的位移列表列。这具有值表较小、预先联接的数据加快联接运算速度以及更新速度提高的潜在优点。有的原始列中不存在某值时,在位移表列中通过该值的空范围指出。例如(假设“首行号”格式的位移表),如果原始列在合并列的行“r”没有值,该列的位移表就在行“r”和行“r+1”有相同的值(即Displacement_Table(r+1,c)-Displacement_Table(r,c)=0)。如果“r”该列的末行,则将其值设置为一个大于该列的实例表中的行数的数字。另一种形式是,如果位移表是“末行号”格式的,则得出指示没有值号r的实例的空范围的公式是Displacement_Table(r,c)=Displacement_Table(r-1,c)(如果r-1是有效行号)或者,如果r等于最低有效行号,Displacement_Table(r,c)=0(对于基于1的行编号)或-1(对于基于0的行编号)。例如,考察下列现有技术数据库现有技术数据库在一个实施例中,第一名字列和第二名字列的对应值表和位移表是值表位移表应用列合并空间节省技术,为第一名字和第二名字产生一个值表列,将第一名字和第二名字的位移表列调整成指向该列中,如下所示具有联合列的值表位移表在这个实施例中,空的第一名字的缺少,由位移表的有相同值的(即差为0)的头两行指示。第一名字值“Allen”和“Edward”以及第二名字值“Alexander”、“Jackson”、“John”、“Joseph”和“Steven”的缺少也是类似地指示的。此外,拼写成“The”的第一名字没有出现,如位移表值12所指示的那样,该值大于记录个数。相反地,末行中小于或等于记录总个数的位移表值则指示该值有一个出现(诸如本例中第二名字的末行中的“The”)。本例中,如果每个第一名字和第二名字字段条目需要20字节的存储区,未压缩列就要使用440个字节来存储11记录。列合并压缩后,值表的联合列(unioncolumn)使用总共20×15个字节,考虑到位移表中的2字节的值,位移表列使用2×2×15个字节,总共360个字节,节省80个字节的空间。如果单独列的值表值有更多重叠,空间节省就会相应地更大。联合列也能有益地用于实现联接操作,如下文所述的那样。本发明的选择性实施例中使用的另一个空间节省技术是将低基数的字段组合到一个有代表各原始字段的各种组合的值的字段中。例如,在上述例子中,可以将“类型”和“奇偶校验”字段合并到一个有代表各“类型”和“奇偶校验”值的组合的值的字段TYPAR中。修改的输入表值表位移表实例表建立这些数据结构的过程如前面的完全一样,只是将“类型”和“奇偶校验”数据当作一个单位,而不是两个独立的列。尽管TYPAR的压缩小于对原始的“类型”列和“奇偶校验”列取得的压缩(由于不同值的个数更多),也因位移表和实例表中列的个数的减少而取得了总的空间节省的结果。如果组合的基数足够低,这个空间节省是能实现的。对与组合字段的第一部分(Even/Odd)匹配的值的搜索大致不变,但是对第二部分(Composite/Power2/Prime/unit)的搜索更加复杂。例如,如果要搜索“Prime”,就必须搜索“EyenPrime”和“OddPrime”两个字段。一般来说,将需要C个这样的搜索,其中C是该组合中第一列的基数。对所涉及的无论哪一列的计数也更复杂。可以对多于两个的列进行组合,其代价是类似的。散列(hashing)散列包含一种已知的、能显著优于对数性时间的二进制搜索的高速数据存储和检索机制。尽管在用关于适当大小的散列表的高效散列函数实现时能产生低系数常数时间的效能,对高效的散列参数的搜索可能是复杂、困难和与数据有关的(例如取决于值的个数和分布)。更重要的是,散列有较大的缺点-尤其在由现有技术的数据库管理系统实现时。散列函数一般不能返回有序结果,这使它们不适合于范围查询,要求有序输出的用户请求-如SQL的“sort-by”和“group-by”查询,其有效实现取决于排序,诸如联接操作。本发明通过支持对多维数据的有效、有序节省空间的表示,消除了与现有技术的数据库管理系统的无序性相关联的散列的缺陷。此外,任何已知散列技术都可以与本发明一起或作为本发明的一部分使用。应用到排序的值表的散列的一个例子是个64KB的散列表,散列表中的每个条目含有值表中头两个字节与该条目的位置匹配的第一个元素的位置。例如,如果采用基于零的编号,散列表中第一个条目含有一个指向值表中头两个字节全部含有0的第一个条目的指针。第二个条目含有一个指向值表中头两个字节含有0000000000000001的第一个条目的指针。这样,每一个相邻散列表条目的集合就这样唯一地为全部64K可能的头两个字节确定了含有相关的头两个字节位模式的值的整个范围。然后就能通过二进制搜索,搜索这个缩小了的值的范围,以寻找任何被寻找的值。两个相邻的散列表条目具有相同值时,表示没有值元素含有第一个条目的头两个字节。在按上述方式实现的散列表的基础上可以作出更多的修改。例如,通过剥离所确定的值表中值的两个字节,可以节省空间,因为那些字节可以从散列表获得。然而,这样就需要先花费额外的时间重构被剥离的头两个字节(如果查找后还不知道的话),才能将值返回给用户。这可以例如通过对散列表进行查找值表中适当行的二进制搜索来完成。对64KB散列表来说,在最坏情况下,这可能要采取多达16个步骤,但是平均效能却能例如通过插值搜索(如果因特定数据集合的正常分布而支持插值搜索的话)而得到显著降低。也可以对实例元素进行散列,以直接返回或收缩对相关值元素的搜索,起着出现表的替代作用。任何能返回与给定实例元素相关联的值元素或某个接近的(near-by)值元素的散列函数都能被用于这个目的。如果返回的是一个接近的值元素,则通过搜索位移表的有限部分寻找该特定的相关值元素。一种这样的技术是一个带有指向被映射到实例表的各可能的头两个字节的值表中的指针的64KB散列表。要搜索的位移表条目的范围由一个散列表条目及其相邻条目给出。在仍然要求大量搜索但可利用的本地化分布模式(10calizeddistributionpatterns)也存在的情况下,可以修改这个64KB散列表,使其接受两部分条目。在这种实现中,第一个散列表条目还是指向与含有由散列表中该位置确定的头两个字节的第一个实例元素相关的第一个值。第二个散列表条目然后提供一个利用这个本地分布来进一步收缩对与所确定实例元素相关联的值元素的搜索的函数的地址。对对应于两个字节的字段的64KB的选择并不意味着包括一切情况。其它字节大小选择、其它基数以及除开头字节以外的字节位置也都可以使用。此外,任何其它已知的散列方法也都可以使用。实例表的一个典型拓扑如上所述,在具体实施例中,各个记录是通过实例表按某种拓扑链接的,最简单的一个是环形链接的列表,或“环形”拓扑。到现在为止的例子都是使用这个简单的环形拓扑-实例表中的指针(即条目)将记录中的所有字段链接在一个环路中,每个字段有单一的“前一个”和单一的“下一个”字段,如图2中所示。在本发明的其它实施例中可以使用其它的拓扑。作为与本发明相联系使用的术语,拓扑是以图来定义的,其中,属性(或其它形式的相关数据)是图中的节点,节点之间存在着链接。对于简单的环形拓扑来说,显然就是这样。图3中显示拓扑的另一个例子。在这个拓扑中,把各字段分解成两个就有一个公共字段的子集,每个子集有一个简单的环形拓扑。两个环的公共字段在它们之间起着“桥”作用。完全的记录重构于是要求环绕两个环的遍历,桥字段将记录的子环连接成一个整体。如果多数查询涉及到子环的其中之一中的字段,则这个拓扑特别有用,因为这样就能遍历和检索该子环,而无需遍历和检索整个记录。如图4中所示,再另一个拓扑是星形或齿轮(spur)形,其中每个字段代表一个从中心轴伸展出的双向链接的辐条。或者,星的各个齿(分支)可以是线性的或环形的拓扑。总之,可以对任何上述拓扑(或所用的其它拓扑)进行组合,以为优化记录存储和对特定数据库的检索。任何定义的拓扑可以是单向或双向链接的,拓扑不需要像上述例子中那样是封闭的。拓扑也可以按用户的选择或者由数据库系统根据存取模式自动地在单向和双向链接之间改变。当数据的相邻性重要时,就是说,当记录中的字段的顺序被排列得使得经常被组合地访问的字段位于拓扑上彼此接近的位置时,双向链接是有用的。当整个的记录(或者它们的相当大的部分)被检索时,或者如果给定了预定的字段检索起始点和顺序时,单向链接的拓扑更为可取,因为单向链接的拓扑结构的实例列表占据的存储区是双向链接的情况的一半。桥字段例子图3具体解释的拓扑中,每个记录由以英语作为桥字段的两个单独的子环(英语->西班牙语->德语和英语->类型->奇偶校验)组成。实现这种拓扑的实例表如下所示英语列有两个外出的指针,对应每个子环。为了例如从英语列的行1开始遍历记录,首先跟踪其中一个外出指针,例如指向西班牙语列的行1的指针。西班牙语列的行1指向德语列的行3,它又指回到英语列的行1。然后跟踪另一个外出指针,它指向类型列的行5。类型列的行5又指向奇偶校验列的行6,它再次指回到英语列的行1。数据库买现下面说明的是用于向以上描述的数据结构输入数据、维护数据和从以上描述的数据结构析取数据的例程的实现。本领域的熟练人员将认识到,有许多不同的用于执行这些操作的算法,本发明并不限于这里展示的算法。基本函数(即由其它函数调用的函数)在一个实施例中被提供用来析取与给定记录相关联的数据并将它以线性形式缓存,和用来将这样的缓存的线性形式的数据写回到本发明的数据结构中。下面将按以下名称称呼按照本发明的数据结构1)VALS2具有有排序次序并且可能经过压缩的列的值表;2)DISP位移表(其列I与对应的VALS2的列I有相同数量的行);3)DELS删除表-下文作说明(其列I与对应的ALS2的列I有相同数量的行);4)INST实例表;6)OCCUR出现表。在下面的讨论中,除非另外指出,否则采用的是有环形拓扑的实施例。在该实施例中的环形拓扑中,分别返回前一个和下一个列的函数prev(c)和next(c)的定义如下prev(c)=(c+fcount-1)modfcount,next(c)=(c+1)modfcount,其中fcount是列的数目,c是范围在0至fcount-1的列号。另一种形式的实施例有范围在1至fcount的列号,prev(c)=(c-1)?(c-1)modfcount(采用C语言的记号),next(c)=c)modfcount+1。通过定义更复杂的prev(c)和next(c)函数,和/或通过将拓扑分析成简单的环形拓扑并对这些简单拓扑应用下面的函数,可以实现更一般的拓扑。未压缩值表和实例表中的行的数目,以reccount代表。压缩的VALS2列的行数较少,对应的DISP和DELS结构也一样。行是从0到reccount编号的(基于零的);其它形式的实施例可以将行从0到reccount编号(基于1的)。“V/O拆分”(splitting)指的是另一种形式的具有上述的压缩值表的实例表-如果实例表的列I中的指针有值和出现成分二者,则将第I列称为“V/O拆分”。适当时为非V/O和V/O拆分提供并行处理。实例表中每个列的描述符指示该列是否有V/O拆分。描述符也含有其它的列/属性特定的信息,诸如节点遍历的路径(即“记录拓扑”),该列是有基于零还是基于1的编号,等等。值表的每个列的列描述符含有配置信息,诸如其数据类型、字段的大小、置换/改变的类型(例如,按值分组的,排序的),压缩的类型(如果有的话)、锁闭信息、散列的类型(如果有的话),等等。其它表也有含有相关配置信息的列描述符。为方便函数变量和返回值的标记,将使用以下记号(以伪-C/C++标记法写成的)typedeflongRow;typedefintColumn;classChainVO{RowchainV[fcount];RowchainO[fcount];boolvalid;}如果一个ChainVO已经被填充以一个有效记录的数据,则ChainV[C]含有该记录在列next(c)中的VALS2条目的行号。如果实例表的列C是V/O拆分的,则ChainO[C]含有值VALS2[chainV[C],next(C)]的出现数。如果实例表的列C不是V/O拆分的,则ChainO[C]含有该记录在实例表的列next(C)中的单元的行号。记录重构给定实例表的列C中的行号R,存在VALS2中唯一的行号V,它含有与实例表的[R,C]单元相关联的实际值。图5中所示的例程Rowget_valrec(RowR,ColumnC)由R和C决定V。步骤GV1通过检查列C的列描述符判定列C是否有一个DISP表列,如果没有,步骤GV2将V设置成R。另一方面,如果出现一个DISP表列,步骤GV3(再次通过检查列描述符)确定其格式。如果该DISP表列是第一行号格式的,则在步骤GV4中,将V设置成使得DISP[V,C]<=R<DISP[V,C]为真的值,其中,如果V+1不存在(即,如果V是列C的最后DISP表行)时,不进行上限测试。否则就在步骤GV5中,将V设置成使得DISP[V-1]<R<=DISP[V,C]为真的值,其中,如果V-1不存在(即,如果V是列C的第一DISP表行)时,不进行下限测试。如果实例表的列C是V/O拆分的,就从V/O条目确定实例表的列next(C)中的行号Next_R,其方式取决于图6中R_from_VO(C,I,O)例程的流程图中的DISP和OCCUR实现。R_from_VO()被传送VALS2(和DISP)的下一列next(C)中的相关值的当前列C、行号I和该值的出现数0。步骤242将变量I’设置为I,将X设置为0。步骤243检测(例如通过描述符)DISP表的列next(C)是“第一行”格式还是“最后行”格式的。如果它是“最后行”格式的,就执行步骤244,将I’设置为I-1,将X设置为1。无论哪种情况,然后都执行步骤245,将变量0’设置为0。然后执行步骤246,检测OCCUR表的列C是否是基于1的。如果是,就执行步骤247,将0’设置为0-1。无论哪种情况,然后都执行步骤248,将下一列中行Next_R设置为DISP[I’,next(C)]+0’+X]。图7表示一个用于线性化记录的拓扑数据的函数,本文中称作get_chain(RowR0,ColumnC0)。该例程从实例表中的行R0,列C0开始,经过指针循环(pointercycle),将各指针存储在ChainVO对象中。如果指针循环关闭,就将ChainVO.valid设置为“真”;否则将其设置为“假”。在步骤G1中,将实例表单元[R0,C0]设置为记录重构的起始点。在步骤G2中,将“当前单元”初始化为起始单元[R0,C0]。在步骤G3中,检查实例表中当前列的列描述符,查看其是否有V/O拆分。如果该列没有V/O拆分,步骤G4通过把R设置为INST[R,C]而直接提取下一列的行号。步骤G5为装入chainO[]数组而设置变量0。步骤G6用get_valrec(Rnext(c))查找VALS2、DISP和DELS中(如果它们存在的话)相应的下一列行号。如果列C有V/O拆分,则在步骤G7将V(VALS2、DISP和DELS的下一列next(c)中的行号)和0(该值的出现数)分别设置为INST[R,C]和OCCUR[R,C]。步骤G8然后用如上所述的R_from_VO(C,V,O)查找实例表的列next(c)中的行号R。处理然后在步骤G9重新汇合,在此分别将chain[C]和chainO[C]设置为V和O。步骤G10然后将C替换为next(C),步骤G11查看处理是否返回到它出发时所在的列(即CO)。如果不是,处理转回到步骤G3,如上地重复。如果处理已经到达原始起始列,步骤G12就比较R的当前值与起始值R0。如果相等,则指针链构成一个封闭回路,表明一个有效的记录已经被重构并存储在ChainVO对象中,步骤G14设置一个指示这一点的标志。如果R不等于R0,步骤G13就设置一个表明重构记录的试图没有产生封闭回路的标志,在(使用环形拓扑的)本发明的该实施例中,这表明有效记录不经过单元[R0,C0]。在使用不同拓扑的本发明的其它实施例中,相关实例元素之间的指针链不必构成封闭回路。记录重构的最后步骤是将在chainV数组中存储的值表行号转换成值。记录的列C值由VALS2[chainV[prev(c)],C]给出(可能如上所述地带有散列值前缀)。广义的记录重构以上对用get_chain()重构记录的说明,根据的是一种简单环形拓扑,拓扑中的下一列只取决于当前列。可以将这种情况推广。下一列可以取决于除当前列以外的元数据,或者除当前列以外,还取决于另外的元数据。例如,下一列可以是当前列和前一列二者的函数,即C=next(C,prev(C))。此外,拓扑中的下一列可取决于数据本身,诸如值表中当前单元的值V,或取决于所有以上数据,即C=next(C,prev(C),V)。用于记录修改的基本函数现在描述用于记录删除、记录插入和记录修改的一种实现的基本函数。这里将该实现称作“交换”方法。在该方法中,值表中的值可以有被删除的以及未被删除的(“有作用的”)实例。一种在本文中被称作DELS的数据结构,为每个值存储其具有的被删除实例的数目的计数。所以,DELS具有与VALS2和DISP相同的列数,并且对于任何给定的列,该列中的行数与VALS2和DISP的相同。被删除的实例被视为实例表中的自由空间,对实例表的维护,使得对于任何给定列中的任何给定值,所有有作用实例都被相邻地分组在一起,所有被删除实例都被相邻地分组在一起,使得有作用实例位于被删除实例的前面或者相反。这便于容易地找到自由空间,向新记录或现有记录的新字段值分配,正如以下的函数中所示的那样。也可以在创建时通过在输入数据表中包含适当的被删除记录而在实例表中希望的位置设置自由空间;由此提供一个用于在删除之前进行插入的实现。图8中所示的put_chain(ColumnCO,ChainVOrec,intcount)函数执行get_chain()函数的逆。Put_chain()从列CO开始,将ChainVO对象“rec”的内容的部分或全部-共“count”个列,写入实例表和出现表。列C中被写的行号是由rec中的pev(C)条目获得的。Put_chain()不修改值表或位移表。步骤P1将当前列号C设置为CO。步骤P2检查实例表在列prev(C)的列描述符,判定前一列是否是V/O拆分的。如果prev(C)是V/O拆分的,步骤P3将V(值表和位移表中的行号)设置为chainV[prev(C)]并将0(出现表中的行号)设置为chainO[prev(C)]。步骤P4将R(实例表中的行号)设置为R_from_VO(prev(C),V,O)。如果实例表的prev(C)列不是V/O拆分的,步骤P5将R设置为chainO[prev(C)]。现在已经获得了要在此进行写操作实例表的列C中的行号,于是步骤P6判定列C是否是V/O拆分的。如果不是,步骤P7将INST[R,C]设置为chainO[C]。如果列C是V/O拆分的,步骤P8将INST[R,C]设置为chainV[C]并将OCCUR[R,C]设置为chainO[C]。处理然后在步骤9转移到下一列,在步骤10递减要处理的列的计数。如果P11判定没有其它的列要写,处理就完成,否则处理转回到步骤P2重复执行。图9是函数intswap(ColumnC,RowR1,RowR2)的流程图,该函数修改实例表和其它表,使得使经过[R1,C]的记录经过[R2,C],使经过[R2,C]的记录经过[R1,C]。步骤S1将经过INST[R1,C]的记录的记录数据提取到ChainVO对象ChainVO_1中,将经过INST[R2,C]的记录的记录数据提取到ChainVO对象ChainVO_2中。两个记录都必须是封闭的回路,不然的话,get_chain()就会引起例外。如果两个回路都是有效的,则在步骤S2中,将ChainVO_1.chainV[prev(C)]和ChainVO_2.chainV[prev(C)]中的值交换,并将ChainVO_1.chainO[prev(C)]和ChainVO_2.chainO[prev(C)]中的值交换。被交换的值在prev(C)列中,因为该列决定实例表中列C的行号。然后在步骤S3中通过调用put_chain(prev(C),ChainVO_1,2)和put_chain(prev(C),ChainVO_2,2),将修改写回到实例表中。put_chain()被调用两次,是因为一次put_chain()循环将各指针更新到被交换单元,第二次更新被交换单元的内容。然后在步骤S4返回成功代码,处理于是完成。图10是函数intdel_swap(ColumnC,RowR,RowRd)的流程图,该函数修改实例表和其它表,使经过[R,C]的记录改道经过[Rd,C]。该例程例如用于维持给定值的被删除实例与有作用实例的分离。在步骤D1中,通过调用put_chain(),将要被改道的(位于行R、列C的)记录的数据放置到ChainVO对象ChainVO_r中。如果put_chain()判定该记录不是一个封闭回路(即,它是个无效记录),就产生一个例外。步骤D2用Vd=get_valrec(Rd,C)寻找与自由单元Rd相关联的值表的行Vd。步骤D3检查实例表的列prev(C)的列描述符,判断它是否是V/O拆分的。如果它不是V/O拆分的,就执行步骤D4,将ChainVO_r.chainV[prev(C)]设置为Vd,并将ChainVO_r.chainO[prev(C)]设置为Rd。如果列prev(C)是V/O拆分的,就执行步骤D4和D6。步骤D5设置出现数Od,方式与上述的R-from_VO()密切相关;具体来说,Od=Rd-DISP[Vd’,C]-X(其中,如果DISP是“首行号”格式的,则Vd'=Vd,X=O,如果DISP是“末行号”格式的,则Vd'=Vd-1,X=1;如果OCCUR是基于1而不是基于零的,则在前面将X递减1)。步骤D6将值放入ChainVO对象-将ChainVO_r.chainV[prev(C)]设置为Vd,并将ChainVO_r.chainO[prev(C)]设置为Od。无论哪种情况,然后都执行步骤D7,通过调用put_chain(prev(C),ChainVO_r,2),将修改的记录拓扑写回到实例表中,处理然后完成。图11是函数top_undel(ColumnC,RowR)的流程图。实例表的单元[R,C]有相关的值VALS2[V,C],其中V=get_valrec(R,C)。如果该值有有作用实例,top_undel()就返回这种有作用实例(在实例表列C中)的最高行号;否则该例程就返回一个表示没有有作用实例的标志和一个小于V的第一实例的行号的数字。在步骤T1中,找到与实例表列C的行R相关的值表行V,即V=get_valrec(R,C)。步骤T2将UP设置为实例表中值V的所有实例的最高行号。如果DISP是“末行号”格式的,则如果DISP[V+1,C]存在,UP=DISP[V+1,C]-1,如果如果DISP[V+1,C]不存在,UP=reccount+X-1(其中,如果行编号是基于O的,X=0;如果行编号是基于1的,X=1)。如果列C根本没有DISP,搜索未压缩值表列,将提供值号V的第一和最后实例的行号。步骤T3将DLS设置为值号V的被删除实例的计数。如果有DELS结构,则DLS=DELS[V,C];否则通过对作过删除标志的实例计数而得到DLS。步骤T4将TU设置为与值号V的第一个被删除实例直接相邻的前一个行号(重申一遍,在“交换方法”实施例中,值号V的所有有作用实例位于该相同值的所有被删除值之前或者-在另一种形式的实施例中-之后)。步骤T5设置值号V的第一个实例的行号BOT。对于“首行号”格式的DISP,BOT=DISP[V,C];对于“末行号”格式的DISP,BOT=1+DISP[V-1,C](如果DISP[V-1,C]存在)或者BOT=X(对于基于X的行编号来说,其中X=0或X=1)。如果列C没有DISP,则通过在未压缩值表中的搜索来获得BOT。步骤T6查看是否TU>=BOT。如果不是,则行号不属于值号V,而是一个小于V的第一实例的行号的行号。紧接的步骤T7返回TU和一个表明所有实例都被删除的标志。如果TU>=BOT,则在步骤T6后执行步骤T8,返回所希望的行号。图12是函数I_move_space_uplist(ColumnC,RowV)的流程图,该函数交换实例表中的指针,以便在保持有作用实例与被删除实例的分离的同时将一个自由单元从DELS[V+1,C]移动到DELS[V,C]。步骤U1检查在VALS2的列C中的行号V+1中是否存在值。如果行号V+1中没有这种值(即下标V+1出界),就在步骤U2报告出错,函数结束。否则,步骤U3检查VALS2的列C中的值行V+1是否有被删除实例(其中之一将被本例程移动)。如果没有,步骤U4就报告出错(没有移动空间),处理结束。如果找到被删除实例,步骤U5就通过计算J=top_undel(C,K)(其中K是值号V+1的第一实例的行号,如果DISP的列C是“首行号”格式的,K=DISP[V+1,C];如果DISP的列C是“末行号”格式的,或者例如通过在值表中的线性搜索发现没有DISP的列C,则K=DISP[V+1,C]),检查值行V+1是否有任何有作用实例。如果是,步骤U6调用del-swap(C,K,J+1),交换(位于行K的)第一个有作用实例与(位于行J+1的)第一个被删除实例,由此将自由单元放到与值V相关的实例表行相邻的位置。步骤U7然后将该自由单元从值号V+1的被删除单元的计数中扣除(通过递减DELS[V+1,C]-如果DELS有列C的话),步骤U8将该单元添加到值号V的被删除单元的计数中(通过递增DELS[V,C]-如果DELS有列C的话),步骤U9调整位移表(如果它有列C的话),以反映该自由单元向值号V的被删除实例集合的转移。如果DISP的列C是“首行号”格式的,就递增DISP[V+1,C],将值号V+1的实例块的“底层”提高一个单元;如果DISP的列C是“末行号”格式的,就递增DISP[V,C],将值号V的实例块的“顶层”提高一个单元。图13是函数I_move_space_downlist(ColumnC,RowV)的流程图,该函数交换实例表中的指针,以便将一个自由单元从DELS[V,C]移动到DELS[V+1,C]。保持有作用实例与被删除实例的分离。错误由返回值指示。步骤W1在VALS2的列C的行V+1是否出界。如果是,就在步骤W2报告错误(即,没有能向其移动一个自由单元的V+1值)并返回。否则,步骤W3检查值V是否有被删除实例(其中之一将被本例程移动)。如果没有,步骤W4就报告错误(没有移动空间),处理结束。如果找到被删除实例,步骤W5就计算J=top_undel(C,K)(其中K是值号V+1的第一个实例的行号,如果DISP的列C是“首行号”格式的,K=DISP[V+1,C];如果DISP的列C是“末行号”格式的,或者例如通过在值表中的线性搜索发现没有DISP的列C,则K=DISP[V+1,C]),以确定值号行V+1是否有任何有作用实例。如果是,步骤W6调用del-swap(C,J,K-1),交换值V+1的(位于J的)顶部有作用实例与(位于K-1的)值的最后被删除实例,由此将自由单元移动到与值表行号V+1相关的实例表行。步骤W7然后将该自由单元加到值号V+1的计数中,步骤W8将该单元从值号V的计数中扣除。步骤W9移动V和V+1之间的边界,以便将被转移的自由单元容纳到值号V+1的被删除实例集合中。如果DISP的列C是“首行号”格式的,就递减DISP[V+1,C],将值号V+1的实例块的“底层”下降一个单元;如果DISP的列C是“末行号”格式的,就递减DISP[V,C],将值号V的实例块的“顶层”下降一个单元。图14是Rowinst_count(ColumnC,RowV)的流程图,该函数取得位于VALS2[V,C]的值的总的实例计数(有作用的+被删除的),其中V是VALS2数组中的一个行号,C是列号。步骤C1判断DISP的列C是否存在。如果不存在,在步骤C2中直接地计算未压缩值列中的所需值的条目,处理完成。如果DISP的列C存在,步骤C3判断该DISP列是否是“首行号”格式的,如果不是,处理在步骤C4继续。如果该DISP列是“首行号”格式的,处理在步骤C8继续。步骤C4确定如何设置变量BOT如果V是DISP最低的允许的下标,则步骤C5(对于基于零的行编号来说)设置BOT=-1或者(对于基于1的行编号来说)设置BOT=0。另一方面,如果V-1是DISP的有效下标,步骤C6就设置BOT=DISP[V-1,C]。步骤C7然后按DISP[V,C]-BOT计算出总的实例计数,于是处理完成。如果步骤C3判定DISP[C]是“首行号”格式的,处理就前进到步骤C8,该步骤确定如何设置变量TOP如果V是DISP允许的最高下标,则步骤C9(对于基于X的行编号来说,其中X=0或X=1)设置TOP=reccount+X。另一方面,如果V+1是DISP的有效下标,步骤C10就设置TOP=DISP[V+1,C]。步骤C11然后按TOP-DISP[V+1,C]计算出总的实例计数,于是处理完成。图15是一个删除实例表单元[R,C]的函数的流程图;就是说,该函数将实例表中的单元[R,C]单元放置到自由池中,并递增适当的DELS计数。如果新删除的单元被相同值的有作用单元环绕,就通过del_swap()将其移动到有作用的/被删除的边界。记录的拓扑数据在一个叫VO的ChainVO对象中。该例程用于记录删除和更新现有记录中的字段;参看下文中“更新现有记录”的步骤E6和“通过单元删除记录”的步骤DR7。在步骤DC1,从代表被处理记录的ChainVO获得列C中的VALS2/DELS/DISP行号,并递增相应的DELS计数。步骤DC2判断指向所处理的单元的指针是否是V/O拆分的。如果prev(C)不是V/O拆分的,步骤DC3直接从VO.chainO取得行号R。如果prev(C)是V/O拆分的,步骤DC4通过R=R_from_VO(prev(C),V,VO,chainO[prev(C)])从VO.chainO重构行号R。无论哪种情况,都在步骤DC5中通过调用top_undel(C,R),找到相同值的顶部未删除单元,将其设置给T(它保证存在,因为要输出的单元就是这样一个未删除单元)。步骤DC6然后测试正被删除的单元是否是所处理值的最顶部的未删除单元。如果不是,就在步骤DC7通过调用del_swap(C,T,R)来进行一次交换,以保持用作用实例与被删除实例的分离。处理然后完成。图16是insert_V(RowV,ColumnC,void*newvalptr)的流程图,在VALS2的列C中的行V插入一个以前没有出现的(由newvalptr指示的)新值,并修改有关的DELS和DISP表(如果它们存在的话),以容纳该新值。这个函数只在实例表的列prev(C)不是V/O拆分的时被使用。步骤Ⅳ1检查位于插入点(行V)的值是否有任何有作用实例;即,是否top_undel(R,C)返回一个表明没有有作用实例的标志(这里的R是值号V的任何实例的INST行号;如果DISP存在,R=DISP[V,C]就是这样一个实例;R=V就是这样一个实例。如果没有行V处的值的有作用实例,就执行步骤Ⅳ2,用新值覆盖旧值,于是处理完成。如果有有作用实例,就搜索最接近的没有有作用实例的值。步骤Ⅳ3将下标J初始化为1。步骤Ⅳ4判断V+J和V-J是否都出界。如果是,意味着不可能进行进一步的搜索,并且找不到自由的值存储片(slots),于是执行步骤Ⅳ5,在VALS2、DISP和DELS的列C为一个或多个存储片分配额外的空间。步骤Ⅳ6检查V+J是否在界限内,并且位于行V+J的值是否有任何有作用实例(通过top_undel(R’,C),其中R’是值号V+J的任何实例的INST行号;如果DISP的列C存在,R’=DISP[V+J,C]就是这样一个实例;如果DISP没有列C,R’=V+J就是这样一个实例。如果V+J在界限内并且值V+J没有有作用实例,则执行以步骤Ⅳ7起始的分支;否则执行步骤Ⅳ10。以步骤Ⅳ7起始的分支是一个循环,它将VALS2中行V至V+J-1中的值移到下一个更高的行,由此打开位于VALS2的行V的一个未使用的行。步骤Ⅳ7将值号V+J的被删除实例加到值号V+J-1,例如,如果DELS有一个列C,则DELS[V+J-1,C]被设置为DELS[V+J-1,C]+DELS[V+J,C]。步骤Ⅳ8将位于VALS2(以及DELS和DISP-如果存在的话)的行V+J-1的值分别移到VALS2、DELS和DISP的行V+J(即,VALS2[V+J,C]=VALS2[V+J-1,C],DELS[V+J,C]=DELS[V+J-1,C],DISP[V+J,C]=DISP[V+J-1,C]),然后递减J。步骤Ⅳ9循环执行步骤Ⅳ8,直到J=0。然后,步骤Ⅳ15在VALS2的行V插入新值,并更新DELS和DISP,以表明新值没有实例,即VALS2[V,C]=新值,DELS[V,C]=0,DISP[V,C]=DISP[V+1,C]。处理于是完成。步骤Ⅳ10测试V-J是否在界限内,以及位于行V-J的值是否有有作用实例。如果有有作用实例,就执行步骤Ⅳ11,该步骤递增J,然后循环回到步骤Ⅳ4。如果V-J在界限内并且值号V-J没有有作用实例,就执行步骤Ⅳ12,开始一个循环,该循环将VALS2中行V-J+1至V中的值移到下一个更低的行,由此打开位于VALS2的行V的一个未使用的行。步骤Ⅳ12将值号V-J的被删除实例加到值号V-J-1(例如,如果DELS有一个列C,则将DELS[V-J-1,C]设置为DELS[V-J-1,C]+DELS[V-J,C])。步骤Ⅳ13然后将VALS2(以及DELS和DISP-如果存在的话)的行V-J+1的值分别移到VALS2、DELS和DISP的行V-J(即,VALS2[V-J,C]=VALS2[V-J+1,C],DELS[V-J,C]=DELS[V-J+1,C],DISP[V-J,C]=DISP[V-J+1,C]),然后递减J。步骤Ⅳ14循环执行步骤Ⅳ13,直到J=0,此时,步骤Ⅳ15如上所述地插入没有实例的新值,处理于是完成。图17是insert_vov(RowV,ColumnC,void*newvalptr)的流程图,它在实例表的列prev(C)是V/O拆分的时,将(由newvalptr所指向的)新值插入VALS2的列C。这种列的列描述符的集合包含一个值h_val(VALS2列C中当前使用的最高行号)和h_ptr(实例表中当前使用的最高行号)。VALS2和实例表二者最好都被在它们的末尾分配额外的空白空间,用于容纳新的条目。在本发明的一个实施例中,插入的新值被写在VALS2表的末尾(而不是如以上的insert_v()中的那样写在按排序次序的位置)。通过将新的索引插在它们适当的排序位置而更新一个按排序次序给出增加的VALS2行号的置换列表(permutationlist)。该置换列表被用来以排序次序(例如通过二进制搜索算法)访问VALS2列的新的部分。要搜索VALS2列中的值,首先要搜索值表的原始的、排序的部分,如果找不到匹配,第二次二进制搜索就用该置换列表在新的值中搜索。可以用其它方法来避免否则对附加新值列表的毫无必要的搜索。这些方法包括-但不限于以下方法(1)可以在后台或前一天晚上将原始排序的值列表连同任何V/O拆分的实例表值一起重新组织,以将附加新值列表保持得尽可能地短;(2)一个内置在值列表或相关位移列表中的或者独立的位标志,标识新的值何时已经或者尚未附加在给定旧值与相邻的旧值之间,以避免没有新值处在该范围时对附加新值列表的毫无必要的搜索;(3)一种可能与现有散列函数或者与用于该目的的散列函数相关联的指针机构缩小需要被搜索的附加新值列表的范围。insert_vov例程被“插入新记录”和“更新现有记录”例程使用。步骤VOV1从列C的列描述符取得已经在列C中使用的最高VALS2存储片号h_val和已经使用的最高实例表行号h_ptr。在步骤VOV2中,将h_val和h_ptr递增,以分别指向VALS2和实例表的列C中第一个可用的空存储片-如果这种空存储片存在的话。步骤VOV25判断h_val是否在范围以内,如果它不在范围以内,步骤VOV26就在VALS2、DISP和DELS的列C中为一个或多个额外的存储片分配额外的空间。步骤VOV27然后判断h_ptr是否在范围以内,如果它不在范围以内,步骤VOV28就在INST的列C中为一个或多个额外的存储片分配额外的空间。在步骤VOV3中,用新值填充VALS2存储片(使得h_val再次指示最高被使用的存储片号);就是说,将VALS2[h_val,C]设置成新值。在步骤VOV4中,找出新值在新附加值集合内的合适的排序次序位置,将值h_val插入置换列表中的该位置。在步骤VOV5中,更新DISP和DELS;DISP[h_val,C]被设置成h_ptr,DELS[h_val,C]被设置成1。由于将h_ptr递增1实际上已经为一个记录分配了空间,该记录还不是一个“有作用的”记录,因此是DELS池的一部分。最后在步骤VOV6中,将等于该新值的排序位置的行V变为h_val,以准确地纳入在调用insert_voc()的例程中使用的ChainVO对象中(具体来说,ChainV[prev(c)]必须指向新值的实际位置,即h_val)。图18是insert_c(ChainVOVO,ColumnC)的流程图。该例程检查是否有由VO指定的列C值的一个被删除实例,如果没有,就从具有一个的最接近值转移一个被删除实例。然后将该值的第一个被删除实例的行号存储在VO.chainO(以偏址或行号的形式-视V/O拆分而定)中。步骤IC1将V设置为其第一个被删除实例要被写入VO.ChainO[prev(c)]的值的列C的VALS行号(即V=VO.ChainV[prev(c)])。步骤IC2判断该值是否有被删除实例(即判断是否DELS[v,c]>0,在用标志标记被删除实例的实施例中,则通过作过删除标记的单元的直接计数值来判断)。如果判断该值没有被删除实例,就执行步骤IC3,循环地搜索带被删除实例的最接近的值(类似于“invert_v()”中所进行的搜索),以确定是否有任何值的被删除实例。如果找不到被删除实例,步骤IC4就在INST的列C中为一个或多个额外的存储片分配额外的空间,并按需调整数据结构,以表明额外存储片是自由的(即被删除实例)。步骤IC5循环地应用I_move_space_uplist()或I_move_space_downlist(),一直到位于VALS2的行V的值有被删除实例。步骤IC6,也是直接在步骤IC2之后-如果值表行号V已经有其自己的被删除实例时-进行的,该步骤将J设置为一个与值表行号V相关的实例表的列C中的行号。如果DISP的列C存在,则J=DISP[V,C]就是这样一个实例。如果DISP没有列C,则J=V就是这样一个实例。步骤IC7然后寻找第一个被删除实例K,它位于top_undel(C,J)返回的行号加1的位置(即K=top_undel(C,J)+1)。步骤IC8然后前一列prev(c)是否是V/O拆分的。如果不是,步骤IC9将VO.chainO[(prev(c))]设置为K。否则,步骤IC10将VO.chainO[(prev(c))]设置为K-DSIP[V’,C]-X,其中,如果DISP是“首行号”格式的,V’=V且X=0,如果DISP是“末行号”格式的,则V’=V-1且X=1。无论哪一种情况,处理然后都结束。记录删除本实施例中进行记录删除的方法是,确定记录的指针表单元,如果DELS列存在就在DELS列中把它们标记为被删除的,或者用墓碑标志(tombstoningflag)作记号。这种自由空间然后就能在修改现有记录中数据或增加新记录时使用。在如上所述的“附加”的未排序列中,附加列中的单元的删除状态与其附加到的单元的删除状态是相同的。图19表示记录的删除。在步骤DR1中,将要被删除的记录(含有单元[RO,CO]的记录)装入ChainVO对象VO。如果从[R0,C0]开始的指针链不构成一个封闭回路,就引发一个例外,终止处理。步骤DR2判断该记录是否有任何被删除单元(例如通过反复检测是否top_undel()返回一个小于该单元的行号的行号),因为只能删除有作用的记录。如果该记录含有被删除单元,步骤DR3就报告错误,然后处理结束。如果该记录中没有单元被删除,就执行步骤DR4,将当前列初始化为列C0,将当前行R初始化为R0。步骤DR5然后删除当前单元[R,C],并通过调用上述的“删除指针单元[R,C],”将R设置为Next(c)中的行号。步骤DR6然后通过调用next(C),将C设置为下一列。如果当前列不等于起始列(C不等于C0),步骤DR7就转回到步骤DR5;否则步骤DR7终止处理。例如,如果以上例子中的记录“Five”被删除,则INST中(可能还有OCCUR中)属于该记录的所有单元都将(对于没有DISP/DELS的列来说-被墓碑,如果DEL列存在,则被DELS列)标记为“删除的”。就以上例子来说,DELS表的样子将如下所示〔如果记录“Five”是唯一被删除的记录)DELETES(删除)现在从DISP的列“类型”获得“类型”=“Prime”的记录的数目为6-3(行4条目与行3条目的差),表示有三个这种记录;然而,DELETES结构指出这些结构中有一个被删除,因此实际总数是6-3-1=2。类似地能获得“类型”=“Odd”的记录的数目。DISP显示“奇偶校验”列的行2中的值4。因此INST的行4至6(最后一行)与“Odd”关联,总共三个记录。再者,在DELETES的“奇偶校验”列的行2中有一个“1”,所以“类型”=“Odd”的未删除记录的数目是3-1=2。记录插入图20表示插入一个新记录。步骤IRl(例如从用户)获得新记录的字段的值,将它们存储在临时缓冲器中。也分配一个ChainVO对象VO,用于记录构造和插入。属于如上所述的“附加”列中的字段实际上是按它们附加到的列中的值的后缀来对待的。步骤IR2将当前列C设置为第一列。步骤IR3然后在值表VALS2中搜索被指定作为新记录的列C值的值V,并返回值的排序位置V和是否该值已经存在。注意,当Prev(c)是V/O拆分的时,在VALS2中的搜索分两部分进行;首先,搜索原始的、排序的值列表,然后-如果找不到匹配,就(如上所述地)在置换列表中搜索所增加值的附加列表。步骤IR4检测是否该值已经存在。如果存在,就执行步骤IR8;否则执行步骤IR5。步骤IR5判断是否列C是V/O拆分的(此时实例表的Prev(c)的列描述符会指出是否V/O拆分)。如果它是V/O拆分的,就执行步骤IR7,通过调用insert_vov(V,C,*newvalue),将新值插入VALS2、DISP和DELS。如果它不是V/O拆分的,就执行步骤IR6,通过调用insert_v(V,C,*newvalue),将新值插入VALS2、DISP和DELS。无论哪种情况,步骤IR8然后都在VO对象中建立chainV,设置VO.chainV[prev(c)]=V,其中V是步骤IR3中所找到的排序位置(如果列prev(c)不是V/O拆分的)或是在“insert_vov()”找到的h_val(如果实例表的列prev(c)是V/O拆分的)。步骤IR9判断是否VALS2的行V处的值有被删除实例(如果DELS列存在,通过检查DELS表列,否则通过计算墓碑)。如果没有,就执行步骤IR10,通过调用insert(c(VO,c)(更新过程中的VO.chainO[prev(c)])提供该值的一个被删除实例。如果已经有一个被删除实例,就执行从步骤IR11开始的分支。在步骤IR11中,通过调用top_undel(C,J)+1,找到实例表中第一个被删除实例的行号K,其中J代表值号V的一个实例在实例表的列C中的行号。具体来说,如果DISP的列C存在,则J=DISP[V,C]就是这样一个实例。如果不存在DISP的列C,则J=V就是这样一个实例。步骤IR12然后判断该实例表的列prev(c)是否是V/O拆分的。如果prev(c)是V/O拆分的,步骤IR13将VO.chainO[prev(c)]设置为适当的出现数,即K-DISP[v’,C]-X,其中,如果DISP是“首行号”格式的,V’=V且X=0,如果DISP是“末行号”格式的,则V’=V-1且X=1。如果prev(c)是V/O拆分的,步骤IR14将被删除实例的行号装入VO.chainO[prev(c)]。无论哪种情况,步骤IR15然后都从VALS2的行V的删除计数中扣除该被删除实例。步骤IR16然后移到下一列,即把C设置为next(c)。步骤IR17然后判断是否已经处理了所有列(即是否C等于列0),如果不是,就转回到步骤IR3。否则,步骤IR18将整个对象VO写回到实例表中(通过调用put_chainO(0,VO,fcount),其中fcount是记录中的字段数),处理于是结束。记录更新图21表示更新现有记录。在步骤E1中,用户选择要更新的记录。在步骤E2中,将该记录装入ChainVO对象VO和一个临时缓冲器。可以选择记录的任何单元作为装入VO的起点。在步骤E3中,用户可以选择修改临时缓冲器中的任何或所有字段值(除非涉及只读条件)。步骤E4初始化“当前列”C,以便在第一列即列0开始。步骤E5判断用户是否修改过字段/列C中的值。如果用户未修改过值,就无需在该列中作处理,于是执行步骤E20,通过将C设置为next(c),将C前进到下一列。如果用户修改过列C中的值,就执行步骤E6,通过调用以上所述的“删除指针单元[R,C]”,删除该记录的旧值以前有作用的实例。步骤E7然后(例如用二进制搜索)搜索值表中被指定作为该新记录的列C的值的值,然后返回该值的排序位置、是否匹配。如果prev(c)是V/O拆分的,则值表的搜索分两部分进行;首先,搜索原始的、排序的值列表,然后-如果找不到匹配,就(如上所述地)通过置换列表搜索所增加值的附加列表。步骤E8检查新值是否已经在VALS2中。如果是,就执行以步骤E12开始的分支;否则执行以步骤E9开始的分支。步骤E9判断列prev(c)是否是V/O拆分的。如果它是V/O拆分的,步骤E11通过调用insert_vov(V,C,*newvalue),将新值插入VALS2、DISP和DELS;否则,步骤E10通过调用insert_v(V,C,*newvalue),插入新值。步骤E12每次一个元素地设置VO.chainV[prev(c)]=V,建立新记录的chainV,其中V或者是-如果列prev(c)不是V/O拆分的时-在步骤E7中找到的排序位置,或者是-如果列prev(c)不是V/O拆分的时-在“insert_vov()”中找到的h_val。步骤E13在DELS表中查找,或者-如果DELS中没有相应的列-计算墓碑,判断位于行V的值是否有被删除的实例。如果该值没有被删除的实例,则执行以步骤E14为开始的分支。步骤E14通过调用insert_c(VO,C),为该值提供一个被删除实例,并在该过程中更新VO.chainO[prev(c)]。否则,就执行以步骤E15为开始的分支。步骤E15在值V第一个被删除实例的列C中寻找行号K,即K=top_undel(C,J)+1其中J是值号V在实例表的列C中的一个实例的行号。如果DISP的列C存在,J=DISP[V,C]就是这样一个实例;否则,J=V就是这样一个实例。步骤E16检查列prev(c)是否是V/O拆分的。如果它是V/O拆分的就执行步骤E18,就将K设置为出现数,即K=K-DSIP[V’,C]-X,其中,如果DISP是“首行号”格式的,V’=V且X=0,如果DISP是“末行号”格式的,则V’=V-1且X=1。无论哪一种情况,然后都执行步骤E17,将该适当数据装入VO.chainO,即VO.chainO[prev(c)]=K。步骤E19然后从删除计数中去除该被删除实例。步骤E20然后将C变为下一列(C=next(c))。步骤E21检查是否所有列都已经被处理,即是否C=0-是起始列。如果C还未返回到起始列,执行就转回到步骤E5,用新的C值重复。否则,步骤E22通过调用put_chain(O,VO,fcount),将整个对象VO写回到实例表中,然后处理结束。查询因为本发明的数据库系统中的列可以独立地排序,所以能非常迅速地进行查询。可以使用任何各种有效、标准的搜索或查找算法。例如,简单二进制搜索提供Clog2n的最坏时间性能和Clog2(n/2)的平均性能。其它搜索技术也能使用,以与具体情况和数据的特点有关的技术为佳。在二进制中点或插值搜索之外能实现并行化。这种搜索算法并行化的技术是本领域中已知的。通过将每个列中的各行排序的数据元素组合在大小n的容器(container)中(其中n等于处理器数或处理器数的整数倍),能取得进一步的并行化。系统跟踪这些容器的上和下边界点,免除了在它们内部对数据排序的必要。如果n等于处理器数,则能以在单处理器环境中对单行进行处理的相同效率搜索和处理全部容器,而这些容器内的位移则变得微不足道。作为例子,图22中表示一个查询给定字段有选定值的所有记录的流程图。在步骤221中,搜索特定字段的值表中与所选定值M相符的值。还是因为各列总体有排序次序,所以能使用二进制搜索(以及其它搜索技术)。步骤222检查是否找到相符的值。如果找不到相符的值,则在步骤223中报告。如果-例如在Value_Table(r,c)处-找到相符的值,则执行步骤224和225,确定值表中具有相符值的行号(步骤224)并重构与这些行相关联的记录(步骤225)。对于未压缩的列,按以上讨论的方法重构与具有相符值的单元相关联的记录;然后在相邻行(r=1,r+2,...r-1,...r-2,)查找相符的值,如果找到另外的相符值,则也重构与这些单元相关联的记录。相邻行的搜索能在找到非相符值时在任何方向停止。对于压缩的列来说,从位移表获得指向该相符值的实例表行号的范围。如果相符值是在Value_Table(r,c)处找到的,则Displacement_Table(r,c)的内容(如果是“首行号”格式的)是该范围的开始并且Displacement_Table(r+1,c)-1是该范围的末尾(除非r是位移表中的最后一行,在这种情况下,该范围的末尾是实例表中该列的最后一行)。步骤225然后如上所述地重构含有实例表中所确定单元的记录。用本文所述的数据结构也能有效地执行更复杂的查询,诸如(FIELD_X=M).AND.(FIELD_Y=N)、(FIELD_X=M).OR.(FIELD_Y=N)等。例如,执行AND查询的方法可以是,(如上地)查找所有符合FIELD_X=M的记录,然后在记录重构期间检查第二个条件(例如FIELD_X=N)。本发明的一个重要优点是,AND条件查询能以较少的步骤进行,这是因为,对于压缩的列来说,满足每一个条件的行的数目已经是位移表中已知的。于是,可以选择具有较少匹配的条件作为第一个要应用的条件。相比之下,现有的数据库引擎通常必须定期地进行“分析”循环才能对每列中找到的基数有个大致的观念。采用以上所述的本发明的实施例,能提前知道每个值的基数。进行OR查询的方法例如是,查找所有符合第一个条件的记录,然后查找未与第一个条件相符的所有符合第二个条件的记录。如果提前知道某个任意复杂的表达式是个频繁的查询,则可以将该表达式的一个排序列就像是普通字段那样加入值表、位移表和实例表中,就能应用相同的快速二进制搜索方法。可以用查询的结果对相应于以上讨论内容的数据结构进行初始化,由此方便子查询。SQL函数用按照本发明的数据结构加上少量的计算,就能支持许多SQL函数。例如,返回有给定属性的指定值的记录的数目的COUNT函数,是在常量时间内可用的,方法是访问位移表中该值和相邻值的条目。返回具有给定属性的最大和最小值的记录的MAX和MIN函数,可以分别通过访问给定列中的顶部和底部单元而实现。寻找具有给定属性的中间值的记录的MEDIAN函数,可以通过检索最接近记录计数一半的位移表的位置并返回相关值而实现。寻找具有最大的出现的个数的MODE函数,可以通过线性检索相邻位移表值中的最大差别然后用对应值而买现。这些函数(称作聚合函数)之所以效率高是因为位移表是与列内的值计数的直方图直接相关的。所示的INSERT(插入)、DELETE(删除)和UPDATE(更新)操作例如在以上所述的这些操作的实施例中得到支持。本发明也支持其它类型的SQL查询。例如,假设有两个标题为“PLANT”(工厂)和“EMPLOYEE”(雇员)的表,表中的各种属性如下所示PLANT:PLANT_NAME(工厂_名字)PLANT_NUMBER(工厂_号)MANAGER_ID(厂长_标识符)等等…EMPLOYEE:EMPLOYEE_NAME(雇员_名字)EMPLOYEE_ID(雇员_标识符)JOB(工作)ADDRESS(地址)等等…例如,用SQL语言如下地表达一个要查找每个工厂的每个厂长的名字的查询SELECTEMPLOYEE_NAMEFROMPLANT,EMPLOYEEWHEREMANAGER_ID=EMPLOYEE_ID如果这两个表的表示是不连接的,即它们每个有独立的值表、实例表、位移表和出现表,则可以用简单的嵌套循环来检查PLANT数据库的MANAGER_ID列中的值与EMPLOYEE数据库的EMPLOYEE_ID列中的值之间的相等性,对于每个匹配,能在EMPLOYEE数据库中找到相应的EMPLOYEE_NAME。如果PLANT数据库和EMPLOYEE数据库的实例表、位移表和出现表指向相同的、具有单一的MANAGER_ID/EMPLOYEE_ID列的值表,则对于每个有一个代表EMPLOYEE和PLANT二者的特定列的条目的位移表,能在EMPLOYEE表中找到相应的EMPLOYEE_NAME。联接联接操作将两个或更多的表组合起来,建立一个连接的表。例如,两个表每个可能有关于EMPLOYEES的信息,可以执行一个联接操作,以确定两个表中关于每个EMPLOYEE的所有信息。为了执行联接操作,通常通过其中一个表中的主键码或候选键码连接各表。主键码或候选键码是一个唯一的属性或属性组合。这个相同属性或属性组合的一个冗余表示-称作外键码,被包含在一个或多个其它表中。外键码不必有与主或候选键码的相同的基数并且不必是唯一的。联接操作被定义为两个或更多表的扩展笛卡儿积的子集。两个基于记录的表的笛卡儿积将第一个表的每行与第二个表的每行组合起来。例如,假设第一个表有M行和N列,第二个表有P行和Q列,则笛卡儿积就有M×P行和N+Q列。扩展笛卡儿积是将空值插入原始表的一个或多个中而产生的笛卡儿积。成员函数(membershipfunction)定义联接回答集(joinanswerset)(联接操作的输出)中的两个或更多个表的扩展笛卡儿积的子集。成员函数含有共同确定特定联接类型的一个比较条件和一个联接准则,该联接类型与列选择器(columnselector)一起确定被联接操作返回的回答集。比较条件规定一个逻辑运算符。逻辑运算符例如就是在SQLSELECT语句的“where”短语中的属性名之间出现的符号。最常见的比较条件是相等,相应的联接被称为相等联接(equi-join)。诸如大于或小于的其它条件也是可能的。联接准则规定给定比较条件、特定联接属性和列选择器时联接的回答集。为方便起见,在以下讨论中假设相等联接的操作对象是每个表中的一种属性。联接准则包括内联接(innerjoin)(联接回答集由在两个表中出现的那些行组成)、外联接(outerjoin)(细分为左外联接、右外联接和全外联接-联接回答集的组成分别为左表中所有的行、右表中所有的行、或任一表中所有的行与另一个表的相应行(如果不存在,则用空填充)的合并)、联合联接(unionjoin))联接回答集由只在两个表的其中之一中出现的行组成,那些行中其余的值用空填充)和交叉联接(crossjoin)(联接回答集由两个表的全非扩展笛卡儿积组成)。列选择器规定要在联接的回答集中返回哪些列。在现有技术的数据库系统中,联接往往极其耗费存储空间和/或处理时间,它们要么要求保持排序性的预先有索引的数据,要么要求很费时间的搜索-这种搜索要在全部的每个正被联接的属性上经过多个回合。在后一种情况下,对于基数相等并且否则等于记录计数的n倍积的表来说,完成一个两列联接的时间与行数的平方成比例,完成一个三列联接的时间与行数的立方成比例,等等。本发明在很大程度上消除了与联接有关的开销。所有属性都能被排序,联合列能消除对保留数据的冗余副本的需要。成员函数能通过位移表、各种另外的位移表、位图和/或n值的逻辑函数而有效地实现。另外的位移表合并列的有些特性导致对位移表列的各种修改,它们在进行联接时特别有用。“完全”位移结构-对于每个列来说-有与(压缩的)值表的对应列的行一一对应的行。在一个实施例中,完全位移表的一个单元的内容,是所有在值表中拥有对应值的实例在实例表中的第一个(或者最后一个-这依具体实施方案而定)实例的行号。如果值表中的某个值根本没有实例,位移表中对应和下一个(或者前一个)单元中的相同条目将指出这一点。因此,如果有比实例多得多的值(iftherearemanymorevalueswithoutthanwithinstances)(下文称之为“稀疏”情况),则位移表中重复的值比不同的值多得多,这导致位移表中的冗余。在一个实施例中,在完全位移表中,各条目是排序顺序的,所以对于实例表中的行号J来说,在值表中的相应行号V是满足DISP[V,I]<=J<DISP[V+1,I]的行号(对于“首行号”格式的位移列来说)或者是满足DISP[V-1,I]<J<=DISP[V,I]的行号(对于“末行号”格式的位移列来说)。在“稀疏”情况中,可以用位移表列的另外一种格式(以下称之为“压缩”位移格式)来消除冗余。在这个格式中,位移表条目有两部分1)DV,有实例的值在实例表中的行号,和2)DD,该值的实际实例在实例表中的起始(或者结尾)行号。行号条目DD是排序顺序的;DV在基础的值表是排序顺序的时将自然也是排序顺序的。对于实例表的列I中的行号J来说,如下地寻找值表中的对应行号V1)例如通过二进制搜索,使得DD[K]<=J<DD[K+1](对于“首行号”格式来说)或者DD[K-1]<J<=DD[K](对于“末行号”格式来说);2)V=DV[K]。压缩的位移列适当时同时节省存储空间和加快二进制搜索的速度。然而,采用完全位移列检查给定值的实例的存在是一种常数时间的查找,而采用压缩位移列时则是一种对数时间的二进制搜索。在没有实例的值稀少的情况下,还有一个另外的位移表格式(本文称之为“紧凑”格式)能用于快速地找到所有缺失的值。在这个另外的格式中,位移表条目有一个位标志来标识没有实例的值,对于哪些没有实例的值来说,该条目的内容是一个指向下一个没有实例的值的指针。(原始定义的没有缺失的链接列表的位移列表在以下被称作“完全”格式)。另外的位移表举例下面表示的现有技术的稀疏和紧凑位移列、记录类型、表Jmod和SPJmod(节选自C.J.Date的IntroductiontoDatabaseSystems(数据库系统导论),第六版,封面内,1995)JmodSPJmodJmod和SPJmod的值表、位移表、实例和出现表如下所示JmodVALS(值表)DISP(位移表)组合的实例/出现表SPJmod:VALS(值表)DISP(位移表)实例/出现表为了方便对例如表Jmod和SPJmod的J号属性的查询,为J号创建一个联合列并将对应于该联合列的稀疏和紧凑位移表列纳入Jmod和SPJmod的位移表中。Jmod和SPJmod的J号合并列如下所示Jmod和SPJmod的J号联合通过联合列的基数与Jmod和SPJmod表的对应列的基数的对比,确定Jmod和SPJmod的每一个的位移列的适当类型。上述的J号联合的基数是7。因为该联合列中近乎所有的值也在Jmod表中出现,所以为该属性构造一个紧凑位移列。对于SPJmod表来说,将其J号列的基数2与联合列的基数7对比。因为在这个情况中J号值是“稀疏的”,所以为该SPJmod列构造一个稀疏位移列。J号联合列、Jmod的位移列和SPJmod位移列在下面表示,为解释方便,将它们都放在一个表中。联合和位移列在Jmod的紧凑位移列中,星号(*)是位标志,表示(1)Jmod没有一个具有对应值的记录,(2)随后的值是一个指向联合列中下一个没有在Jmod中出现的值的指针。联合列中那些没有在Jmod中出现的值由此被保存在一个环形链接列表中。在SPJmod的稀疏位移列中,各条目是按DV/DD的格式表示的,其中DV是一个指向联合列中的在SPJmod表中有实例的一个值的指针,DD指针是给定值的实例的SPJmod实例/出现表中的起始行号。用位图模拟联接Jmod和SPJmod表的J号联合列也可以由位图补充。位图将指示联合列中的值是包含在Jmod还是SPJmod表中。下面解释创建这种结构的过程。本例中的位图由7个条目0000至0006组成,每个对应联合列中出现的J号的一个值。每个条目与2个位关联。如果J号的对应值出现在Jmod表中,则将第一位设置为1,否则设置为0。同样,如果J号值出现在SPJmod表中,则将第二位设置为1,否则设置为0。因为Jmod表是由一个紧凑位移列表示的,所以其位条目被初始化为“1”(因为联合列中的几乎所有值都包含在Jmod中)。同样,因为SPJmod表是由一个稀疏位移列表示的,所以其位条目被初始化为“0”(因为联合列中没有多少值出现在SPJmod中)。所以,初始的位图如下所示初始位图下一步是构造最终位图。对于Jmod列来说,在J号联合列中没有出现的值被包含在其紧凑位移列中非出现值的环中。遍历该环,将位图中的对应条目设置为“0”。为了更正SPJmod列的条目,将指向联合列中的在SPJmod表中有条目的值的指针设置为“1”。最终位图如下所示最终位图N值的逻辑函数能用对位图的函数模拟联接操作。这个技术通过以下的例子参照现有技术的表S、P和J来解释(这些表选自C.J.Date的IntroductiontoDatabaseSystems(数据库系统导论),第六版,封面内,1995)SPJ在本例中,对S、P和J表的“城市”列执行一个联合联接(unionjoin)。这必然只找到那些其“城市”值只在S、P或J表其中之一中出现的记录。第一步是为S、P和J表的“城市”列构造一个联合列-如果不存在一个联合列的化。第二步是建立该联合列的每个值与分别对应于S、P和J表的三个位的联系。如果该“城市”值在具体的表中出现,就将对应的位设置为“Y”(即“1”),否则设置为“N”(即“0”)。以下表示这样一个表联合列和位图对于“城市”属性的特定值来说,当且仅当“城市”的该值只出现在S、P和J表的其中之一,即该联合列在位图中的各位中只有一位等于“Y”时,具有该值的记录在联合联接中出现。下面描述的函数f(temp,colomn)是寻找这种行的函数的一个示意性实施例。该函数的域由两个变量“temp”和“column”组成。变量“temp”可以是三个值“Y”、“N”或“D”的其中之一。变量“column”取值“Y”或“N”。最后,函数f的返回值也由三个值“Y”、“N”或“D”组成。对于联合列中每个“城市”值,将函数f循环地应用到三个列的每个列中的位置将“column”设置成当前列的位值,将“temp”赋值为函数f的上一次应用的结果。对于第一列S来说,“temp”被初始化为“N”。在最后的循环之后,如果结果是“Y”,该值在联合联接中出现;如果结果是“N”或“D”,则该值不出现。函数f的定义如下如果将该函数应用到联合表中对应于值“Athens”的第一行,则产生以下结果f(f(f(“N”,”Y”,”N”),”Y”),它等于“D”。所以,在该行中出现两次的“Athens”,在联合联接中不出现。将函数f应用到对应于“Oslo”行则产生以下结果f(f(f(“N”,”N”,”N”),”Y”),它等于“Y”。所以,在该行中只出现一次的“Oslo”,在联合联接中出现。图23是解释联接操作的流程图。在步骤231中,用户选取要联接的表。在步骤232中,将尚未以本发明的数据结构表示的任何表转换成这种结构。然后在步骤233中,选取其值是定义作为扩展笛卡儿积的一个子集的联接的逻辑表达式的一部分的列(如果有的话)。步骤234查看是否有被选择的列。如果没有列被选择,该联接对应于完全非扩展笛卡儿积,则通过步骤238无条件约束地进行记录重构(即将每个表中的每个记录与每个另外表的每个记录组合)。否则执行步骤235,查看是否是否选择了一个以上的列。如果是,将这些组合成一个组合列(诸如上述“组合列”中的)。如果适当的值表联合列尚不存在,步骤237就连同其相关的位移表列创建联合列。步骤238然后用完全、紧凑和/稀疏位移列表、位图、多值逻辑函数或它们的任何组合,修改例程中产生联接输出的范围,以便用适当的对比条件和联接准则来匹配该类型的联接。例如,内联接的回答集被限制在与其中所涉及的表有非空记录范围的位移表行对应的实例表单元。这可以例如从它们的位移表条目确定。从每个这种位移表行(以及可能是一个相邻行-视具体实现而定)导出的对应实例单元条目提供所有相符记录的每个表的实例表单元范围。回答集只限于是那些产生适当的内联接回答集的记录。其它类型的联接的回答集可以类似地从位移表确定。采用以上讨论的查询方法的组合能实现像SQL的“SELECT…FROM…WHERE…”那样的全部系列的语句。尽管对本发明通过参照其特定示意性实施例作了特定的展示和说明,本领域的熟练人员将明白,各种形式或细节上的修改都落在由权利要求定义的本发明的范围内。权利要求1.一种计算机实现的数据库,包含a.一个或多个数据值元素集合,每个数据值元素有一个在该一个或多个数据值元素集合的其中之一中的位置和一个数据值;b.至少一个第一和一个第二实例元素集合,每个实例元素有一个在其相应实例元素集合中的位置和一个数据值,并且每个实例元素集合对应于一个属性;c.其中对于第一实例元素集合中的第一个实例元素来说,(ⅰ)该一个或多个数据值元素集合中的第一个相关数据值元素是由该第一实例元素的位置导出的,并且(ⅱ)第二实例元素集合中的、其在第二实例元素集合中位置不同于第一个实例元素在第一实例元素集合中位置的单一一个第二实例元素,是由第一实例元素的实例值导出的,并且d.另外其中(ⅰ)将该一个或多个数据值元素集合中的第二个相关数据值元素与第二实例元素和第二实例元素集合中的至少一个其它元素相关联,并且(ⅱ)第一个实例元素能独立于第一实例元素的值地由第二实例元素导出。2.权利要求1的数据库,其中,第二实例元素是下一个元素。3.权利要求1的数据库,其中,该一个或多个数据值元素集合的其中之一是排序的。4.权利要求1的数据库,其中,该一个或多个数据值元素集合的其中之一被压缩的使得该集合包含唯一性的数据值。5.权利要求1的数据库,其中,该一个或多个数据值元素集合的其中之一是压缩的-使得该集合包含唯一性的数据值-和排序的。6.权利要求1的数据库,其中,所有具有相等数据值的数据值元素在该一个或多个数据值元素集合的其中之一中有相邻的位置。7.权利要求1的数据库,其中,该一个或多个数据值元素集合的其中之一是一个算法,该算法生成一个唯一性值的序列,并且,对于序列中的每个数据值,由该值在假若所有数据值都被该算法生成时的序列中应当具有的位置给出的在该一个数据值元素集合中的位置。8.权利要求5的数据库,其中,第一个相关数据值元素在压缩的数据值元素集合中,并且该数据库进一步包含一个与该压缩的数据值元素集合相关联的位移元素的位移集合,位移集合中的每个元素有一个在位移集合中的位置和一个位移值,其中,第一个相关数据值元素进一步由位移集合导出。9.权利要求8的数据库,其中,位移集合中的每个元素都有一个由其位置导出的、在压缩的数据值元素集合中的单一一个相关元素。10.权利要求8的数据库,其中,位移集合中的每个元素都与第一实例集合中的一系列元素相关联,该系列中的每个元素都是与相同的数据值元素相关联的。11.权利要求10的数据库,其中,位移集合中的一个元素的位移值确定其相关位置范围中的第一个位置。12.权利要求10的数据库,其中,位移集合中的一个元素的位移值确定其相关位置范围中的最后一个位置。13.权利要求10的数据库,其中,位移集合中的元素的位移值确定其相关位置范围中位置的数量。14.权利要求1的数据库,其中,第二个相关数据值元素在压缩的数据值元素集合中,并且该数据库进一步包含a.一个与该压缩的数据值元素集合相关联的位移元素的位移集合,位移集合中的每个位移元素有一个在位移集合中的位置和一个位移值,b.一个与第一实例元素集合相关联的出现的出现集合,出现集合中的每个元素有一个在出现集合中的位置和一个出现值,并且c.其中(ⅰ)第二个相关数据值元素进一步由位移集合和出现集合导出,和(ⅱ)第二相关数据值元素由第一实例元素的实例值导出。15.权利要求14的数据库,其中,第二实例元素由一个其位置由第一实例元素的实例值给出的位移集合元素和一个其位置由第一实例元素的位置给出的出现集合元素导出。16.权利要求14的数据库,其中,第二实例元素由一个其位置由第一实例元素的实例值给出的位移集合元素的值与一个其位置由第一实例元素的位置给出的出现列表元素的值的和导出。17.权利要求1的数据库,其中,一组包含第二实例元素和由第二实例元素的实例值导出的所有相关实例元素的相关实例元素包括第一实例元素。18.权利要求17的数据库,其中,在该独立于第一实例元素而导出的相关元素组中的每个相关实例元素都是唯一的。19.一种计算机实现的数据库,包含a.一个或多个数据值元素集合,每个数据值元素有一个在该一个或多个数据值元素集合的其中之一中的位置和一个数据值;b.至少一个第一和一个第二实例元素集合,每个实例元素有一个在其相应实例元素集合中的位置和一个数据值,并且每个实例元素集合对应于一个属性;c.其中对于第一实例元素集合中的第一个实例元素来说,(ⅰ)将该一个或多个数据值元素集合中的、由该第一实例元素的位置导出的第一个相关数据值元素,与该第一个实例元素和第一实例元素集合中的至少一个其它元素相关联,并且(ⅱ)第二实例元素集合中的、其在第二实例元素集合中位置不同于第一个实例元素在第一实例元素集合中位置的单一一个第二实例元素,是由第一实例元素的实例值导出的,并且d.另外其中(ⅰ)将该一个或多个数据值元素集合中的第二个相关数据值元素与第二实例元素和第二实例元素集合中的至少一个其它元素相关联,并且(ⅱ)第一个实例元素能独立于第一实例元素的值地由第二实例元素导出。20.一种计算机实现的数据库,包含a.两个或更多包含数据值和实例元素的集合,每个实例元素与一个数据值关联并具有一个位置和内容;b.唯一地将每个实例元素与至少一个其它属性集合中的某特定实例元素相关联的连接信息;c.其中与第一属性集合中的第一数据值相关联的第一实例元素的连接信息将第一实例元素与是与第二属性集合中的第二数据值相关联的多个数据元素的特定一个的第二实例元素相关联;d.其中第二实例元素的位置独立于第一实例元素。21.权利要求20的数据库,其中,第一实例元素的连接信息包含第一实例元素的内容。22.权利要求21的数据库,其中,每个数据值有一个位置,第二属性集合中的数据值是唯一的和排序的。23.权利要求22的数据库,其中,第二属性集合进一步包含标识第二属性集合中的、与第二数据值相关的实例元素的位移信息。24.权利要求23的数据库,其中,第一属性集合进一步包含标识第二属性集合中的第二数据值的实例的第二实例元素的出现数的出现信息,第一实例元素的连接信息进一步包含第一属性集合的出现信息和第二属性集合的位移信息。25.一种用于存储和检索元组的系统,包含一系列的许多对应于第一属性的一个值的实例;一个对应于实例个数的基数元素;其中,基数每次在实例个数改变时被更新,并且至少一个实例指示至少一个其它的、对应于第二属性的一个值的实例,第二实例不同于第一属性。26.一种用于存储和检索元组的系统,包含一系列的许多对应于第一属性的一个值的实例;一个对应于实例个数的基数元素;其中,该值能由基数元素导出,并且至少一个实例指示至少一个其它的、对应于第二属性的一个值的实例,第二实例不同于第一属性。27.一种用于存储多个元组的系统,每个元组包含至少一个有第一属性值的第一属性和一个有第二属性值的第二属性,该系统包含对于至少两个有相同第一属性值和相同第二属性值的元组来说-一个标识第一属性值和第二属性值的实例元素、一个包含关于有相同第一和第二属性值的元组的个数的信息的基数元素。28.权利要求27的系统,其中,实例元素包含基数元素。29.一种用于存储多个元组的系统,每个元组包含至少一个有第一属性值的第一属性和一个有第二属性值的第二属性,该系统包含a.一个存储该多个元组的第一和第二属性的值的值存储区;b.一个标识每个元组的相关值存储区中的值的实例的实例存储区;c.一个存储关于实例之间的关系的信息的连接存储区;d.一个存储代表相同值的实例的出现的频率的信息的基数存储区,其中,值存储区中的与实例存储区中的特定实例相关的特定值是用基数存储区导出的。30.权利要求29的系统,其中,实例存储区与连接存储区是不同的。31.一种从压缩数据库检索记录的方法,该数据库是已经被用存储关于属性的不同值的信息和关于不同值的出现的次数的信息的方法压缩过的;该方法包含以下步骤a.检索给定值的出现的次数;b.根据关于该给定值的出现的次数的信息确定一个实例;c.根据该实例元素确定一个连接元素;d.由该连接元素确定一个记录。32.一种用于存储多个值的实例的方法,包含以下步骤a.存储关于某值的按不同值的顺序的位置的信息;b.在该值的按不同值的顺序的位置每次改变时更新关于该值的位置的信息;c.存储关于该值的实例个数的信息;d.在该值的实例个数每次改变时更新关于该值的实例的个数的信息;e.存储关于该值的一组一个或多个实例按多个值的实例的顺序的位置的信息;f.在该组的位置每次改变时更新关于该组的位置的信息。全文摘要一种计算机实现的、提供高效、有序、节省空间的多维数据的表示的数据库和方法。以一种对例如空间利用和/或访问速度有益的方式-如以压缩的形式和/或排序次序,存储每个属性的数据值。属性的每个数据值的实例由实例元素标识,其中每个实例元素与一个数据值关联。为每个实例提供将每个属性元素唯一地与另一个属性的数据值的特定实例相关联的连接信息。文档编号G06F17/00GK1317116SQ99810695公开日2001年10月10日申请日期1999年7月8日优先权日1998年7月8日发明者S·A·塔林申请人:必需技术公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1