一种按需索引的数据库系统的设计与实现之一: adoSpace初步设想

这是adosSpace系列的第一篇,相当于个人工作的笔记。错误在所难免,若有有高人批评指正,不胜感激。

1 懒索引的设想:

把索引的创建,维护交给后台自动,并发地完成,而不是由人来完成,索引的数量完全是按需决定,不用人去考虑建立索引的成本

索引的建立是懒的,直到一次查询请求触发了对索引的需求后,才会边进行全表扫描取数据边建立索引,既然要进行全表扫描取数据,何不顺手把索引也建立了呢?

不用担心索引多了会增加维护的成本,因为索引的维护也是很懒的,修改数据后,并不会立即去维护索引,而是当有查询实际需要这个索引时,才会触发维护动作,也就是说如果以后再也没有引起触发的查询,索引就会一直保持原状态不变

如果把索引的创建也看做一次特殊的维护,则以上的两个功能可以合并成一个概念:按需维护的自动索引机制

 

2 虚拟表的设想:

有了按需索引的概念,我们再来审视一下表的概念。其实表是一个数据集合,也就是说把某个属性相同的对象聚集在一起就成了表。表名就是表中对象隐含的共同属性。可以认为表名是设计者预先设置的一种属性分类。关系数据库中建表的工作是由人来完成的,可不可以改成按需由系统自动完成呢,也就是说一开始只是在空间中有一堆对象,按需地增加各种属性,当查找某些共同属性的对象时,这个查找动作将触发一个自动过程,将某些属性相同的对象聚集在一起就形成了一个逻辑上的虚拟表。

按前面的懒索引的设想,这会触发建立一个索引,下次再做同样的查询时,虚拟表即对应的索引已经存在了,通过索引就可以快速找到需要的数据。这样一来,表就被索引替代。

 

不管是表的数量还是索引的数量不再有理论上的限制,关系数据库建立索引往往陷入两难,不建索引查询效率太低,建太多的索引,更新数据的效率真太低,而采用按需索引的机制后建再多的索引也不会使插入和更新操作变慢。

 

Ados树空间采用以上虚拟表存储数据后,ados空间中的数据索引将不再受mysql数据表索引数目的最大个数限制。

 

3 插入对象的初步设想

对象的产生总是先克隆最相似的对象,然后修改某些属性得到。这与自然界中的细胞分裂相似。

 

4,表做为一级实体的存在性要进行考虑,如果不设置表,那么每个索引中都要存放空间中所有对象的id,这样索引太大,不便于维护。对以后数据的分区,分布式存储也不方便处理。

     现在的想法是,空间中的对象都是平行的,通过索引文件的层次结构形成虚拟表的概念,也就是说一个文件夹就是一个表名,文件夹中可以有子文件夹,子文件夹就是子表名。文件夹中的索引文件只保存表中所有记录,不会保存空间中所有对象的记录。这样一来,索引的体积就可以缩减许多。更重要的是建立起子表的概念。而且这种子表是虚拟的,只是因为索引而建立起来,并不影响实际数据的存放。

 

例如:

空间中有如下几条记录

学校:交大

学院:计科

职业:学生

姓名:张三

性别:男

电话:12345

学校:交大

学院:电信

职业:老师

姓名:李四

性别:女

电话:23456

学校:民大

学院:经管

职业:学生

姓名:王五

性别:男

电话:34565

学校:民大

学院:艺术

职业:老师

姓名:赵六

性别:发

电话:45678

 

那么可以根据学校分成两张表:交大-学校表与民大-学校表

 

交大-学校表的索引中就只需要存放两条索引记录,而不是整个空间的四条记录。

         而交大-学校表下又可以有两个子表:计科-学院表与电信-学院表

 

另外也可以根据职业分成两张表:学生-职业表与教师-职业表

         而学生-职业表表下又可以有两个子表:交大-学校表与民大-学校表

 

这些表只是索引文件的组织形式,而不是像关系数据库中的表实体。当然,对外仍然可以提供sql的支持。对外部访问者来说,就仿佛表存在一样,这种表的组合是很灵活的,这样一来,传统关系数据库中的很多视图就没有必要了,因为对象本来就包含了所需要的属性,没有必要将两个或多个表连接起来再得到复杂的数据,这样可以带来查询效率的提高。

在关系数据库中由于层层嵌套的视图,使得数据查询的效率很低,而要优化复杂的查询,往往需要重写或增加新的视图,这种大量的复杂视图的优化工作简直就是一场噩梦,既需要有丰富的的sql经验,又要掌握复杂的业务逻辑。这样的人在开发团队中太少了,而且往往没有替代者。

 

5 在现有条件下实现adoSpace的技术路线

 

  1. 用redis存放数据对象,每个对象有唯一的地址id(整形),结合redis数据库的特性,一个对象的完整地址形式是 ip:port:db:id 。在redis中的键值就是id,在索引中存放完整地址。考虑到ip地址在不同的机器上可能发生变化,但索引数据拷贝后要能继续使用。因此ip要用虚拟ip,然后建立一个虚拟ip与实际ip的映射关系表。
  2. 用sqlite 存放索引,一个索引占用一个sqlite库文件,库文件要在操作系统中组成层次结构。索引表中存放 对象完整地址与索引用到的列。索引可以并发读,但只有唯一的线程进行维护(写)操作。
  3. 在实现系统时建立数据访问层与索引访问层,屏敝对redis与sqlite的具体操作,也以后根据需要,也可以换用其它的存储系统与索引系统。
  4. 对数据可以按地址或完整的路径名进行访问,这种访问只用到了redis,所以效率很高。如果要按属性进行查找,则需要先查找索引,通过索引找到满足要求的地址列表,然后由地址列表从redis中取回完整的数据。
  5. 对数据对象的修改,需做两步操作。
  1. 写操作日志,每条日志记录包含:自增长的id ,操作类型,操作对象的地址
  2. 写redis数据。

6  每次按索引进行查找时,会比较索引文件中保存的操作日志id是不是最新的操作日志id,如果发现有操作还未更新到索引,则先取出未更新的操作日志记录,更新索引,然后根据索引查找数据。

猜你喜欢

转载自blog.csdn.net/littlezhuhui/article/details/85253812