`
daogangtang
  • 浏览: 61121 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Bamboo存储抽象层与外键关系的讨论

阅读更多
Bamboo的存储抽象层主要在model.lua中实现。本文仅从使用的角度来说明Bamboo中的存储抽象层的内容。

建立模型时,bamboo的域的属性由域属性表描述。根据是否是外链到其它对象的角度,可以把域分为两种:普通域和外键域。而这两者,是由如下两个属性名称来区分的。

foreign

外链模型名称,如果这个属性不存在。则表明是普通字段。如果存在,表明是外链字段。是外链字段的话,foreign只能取如下几个值中的一个。
  • 'Model_name',即模型的名字,具体使用的时候,要用具体的模型名称来替换Model_name,比如:'User';
  • 'UNFIXED',不定模型。它的意思是,同一个外键域中可以存储多个不同的模型的实例。比如:'User:1', 'ZDUser:5' ...;
  • 'ANYSTRING',任意字符串。它的意思是,存入外键队列的不是一个实例对象的索引了,而是被压成字符串的对象。

st

存储类型(store type)。如果这个属性不存在,就默认存储类型为'ONE',如果存在,只能取如下列表中的一个(目前来讲有4个):
  • 'ONE'。对单外键。在内部,以字符串形式存储在对象实例的中的此域的key对应的value中;
  • 'MANY'。对多外键。在内部,以zset的形式存储。其中,score就为添加时的index(添加一个自动加1),存储的内容由foreign的类型确定,可以保证的是单个元素都为字符串;
  • 'FIFO'。对多外键,但与MANY不同的是,FIFO是固定长度的,默认是100,可由fifolen属性重新定义。在内部,是以list的形式存储,当数据填满的时候,就会执行先进先出的操作。
  • 'ZFIFO'。对多外键。与FIFO相同的地方在于,两者长度都是确定的,默认是100,可由fifolen属性重新定义。不同的地方在于,在内部,是以zset的形式存储,score为内部根据目前最大的score值得到,value为对象字符串,由foreign属性决定。

foreign与st组合,(目前)可以产生3*4=12种情形(以后可能更多)。

index cache

除了外键的存储用到了redis的高级结构,在Model实例保存的时候,还会生成一个index cache,用的是zset。存储的时候,以每个实例的id为score,以name为member存入。这个index cache在整个模型的高速API设计中起到了相当重要的作用。

模型外键的完整解决方案

外键分为一对一,一对多,多对多三种,同时又有正向、反向两个方向。
  • 一对一关系,正向反向都是单个指向。
  • 一对多关系,正向是多个指向,反向是单个指向。
  • 多对多关系,正向是多个指向,反向是单个指向。

在Bamboo的模型实现中,对上面情况的处理方式是在域描述表里面写属性:
  • 一对一正向:foreign=’model B’, st=’ONE’
  • 一对一反向:foreign=’model A’, st=’ONE’
  • 一对多正向:foreign=’model B’, st=’MANY’
  • 一对多反向:foreign=’model A’, st=’ONE’
  • 多对多正向:foreign=’model B’, st=’MANY’
  • 多对多反向:foreign=’model A’, st=’MANY’

在域描述表里面写明后,还得需要相应的方法来操作它们,Bamboo提供了一套完整的API:

● instance:addForeign(field_name, obj)

向本对象的某一个外键域中添加新对象的连
接(实际就是存储这个新对象的id值)。可以看出,要先获得new_obj才行;

● instance:getForeign(field_name [, start [, stop [, is_rev]]])

获得本对象的外键对象。对于单外键的情况,返回的是那个外键对象;对于多外键的,返回的是那些外键对象的列表。可以用start和stop参数来决定获取多外键的某一个切片。

● instance:delForeign(field_name, obj)

删除一个外键。可以看出,要先获得待删除的外键对象才行。

在外键的定义的时候,一个完整的外键关系实际是需要正反双方共同完成,即正向反向都要定义。但正向反向都定义的话,会导致增加域。所以,很多时候,只用得到一半关系,有可能是正向的一半,也有可能是反向的一半。由于有一半关系的存在,因此,当删除一个模型的对象的时候,引用这个外键对象的另一个模型的那个对象,可能根本无法知道。于是自动化的删除管理就是一件非常困难的事情,这也是数据库系统中历来最头痛的一件事情。

鉴于这种困难,Bamboo把外键删除的工作交由用户自己来管理。用户根据自己的业务逻辑小心地处理一个对象删除后,其它相关引用对象外键去留的问题。不过,Bamboo还是做了一小点事情来帮助用户稍微释放一下紧绷的神经,当使用getForeign()函数的时候,如果发现,要获取的外键对象不存在时,会自己将此条外键记录清除掉。这个方式仍然有局限,那就是,只有当调用getForeign()函数时,这种清除工作才会发生。想要像垃圾回收器那样自动进行外键回收清理,目前是不可能的。
1
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics