refer to Incremental computation and maintenance of temporal aggregates ,Jun Yang1, JenniferWidom2 ,VLDBJ 2003
SB树是用来实现 时间聚集 的一种数据结构,不同于Size Balanced Tree。
接下来将以一个例子来讲述SB树的插入、删除、查找,以及其他一些操作。
![](https://img-blog.csdn.net/20150517145726161?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGN5MTk5NDEyMjk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![]()
![](https://img-blog.csdn.net/20150517150753781?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGN5MTk5NDEyMjk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
Table1 表示了 病人的药剂用量,元组属性分别为 病人名字,药剂用量,有效时间(时间粒度为 1天) ,Fig.1 是Table1的坐标表示。
![](https://img-blog.csdn.net/20150517151107678)
Table 2 表示 在某一时间段中,使用药剂的总量,这实际上是一个 SUM 的集函数操作。
SB-tree的数据结构介绍:
每一颗SB-tree都有两个参数:最大分支系数 b 和 最大叶子容量 l
每个中间节点最多能够容纳b个连续的时间区间,以Fig.2为例,节点N能够表示 j 个 时间区间,分别为N.I1, N.I2,……,N.Ij.而节点N中存放的是j-1个不同的瞬时时间点(按升序排列),第i个时间点用N.ti表示。第i个时间区间从 N,t(i-1)开始,到N.ti结束。N.vi表示 N.Ii的某一时间聚集函数的值,N.ci表示指向下一子节点的指针。
![](https://img-blog.csdn.net/20150517151840734)
每个叶子节点与中间节点类似吗,除了没有指向下一节点的指针,最多能够表示l个时间区间,如Fig.3所示。
![](https://img-blog.csdn.net/20150517153105650)
对于根节点的描述不是很懂,所以就不提出来了- -
对于任何非叶子节点N,其N.ci的子树中的时间一定小于N.ti,N.ci+1的子树的时间一定大于N,ti
![](https://img-blog.csdn.net/20150517160232037?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGN5MTk5NDEyMjk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
Fig.4就是针对于Table2建立的一棵SB-tree
![]()
考虑 i-th 时间区间,N.Ii的开始时间是这样子定义的:
![](https://img-blog.csdn.net/20150517154253673)
结束时间是这样定义的:
![](https://img-blog.csdn.net/20150517154324963)
SB-tree 的具体操作
查找: lookup(N,t)表示搜索节点N以及节点N为根的子树,具体是:
其中
在SUM 函数中就是 “+”
举个例子,假设我们要查找瞬时时间为19时的药剂总用量,那么我们从根节点开始,lookup(N0,19),N0的第二个区间[15,30)包含19,而其值为1,所以接下来查找N2子树,lookup(N0,19)=1+lookup(N2,19). N2的第一个区间[15,20)包括19,其值为5,并且N2是叶子节点了,所以lookup(N0,19)=1+5=6
范围查询:结果返回与要查询的时间区间I重叠的元组,range(N,I,v)I表示要查询的时间区间,v表示当前查询到的aggregate value,用来递归调用
比如要查询[14.28),最终会返回 <8,[14,15)>,<6,[15,20)>,<7,[20,28)>
插入:假设插入时间t,t是在区间I中的,aggregated attribute是 Vbase,那么可以记为<V,I>。Insert(N,<V,I>) 的具体操作为:
比如向Table1中插入一个元组<"Ida",1,[17,47)>,我们首先执行
Insert(N0,<1,[17,47)>)
,N0.I2 ,N0.I3,N0.I4都与[14,47)相交,而只有N0.I3=[30,45)完全被 [17,47)包含,所以直接令N0,v3加1,其他继续执行insert(N2,<1,[17,47)>)和insert(N4,<1,[17,47)>),结果如Fig.5
删除:插入的反操作,比如删除元组<"Ida",1,[17,47)>,相当于插入<"Ida",-1,[17,47)>,在Fig.5的基础上进行删除,结果如Fig.6所示
节点分裂:当向SB-tree插入一个元组时,可能会导致某一个节点溢出,溢出是指该节点的时间区间超过它能表示的最多区间数量,此时应该进行节点分裂。
分裂算法如下:
比如向Fig.4中执行
Insert(N0,<1,[7,12)>),
结果如Fig.7所示
此时N1溢出,所以将N1分裂成N11和N12,结果如Fig.8所示
此时N0溢出,所以将N0分裂成N01和N02,并生成一个新的根节点N0',结果如Fig.9所示
区间合并:当完成插入或者删除操作后,可能存在两个相邻的区间的value是相同的(如Fig.6),这个时候就要进行区间的合并。
合并算法如下: