空间数据对象(spatial data objects)通常是一个在多维空间中区域,不能仅用坐标点位置很好的表示。
例如,在地图应用中,代表一个国家的空间数据对象,就是一个在二维空间中的区域。
对于空间数据的常用操作就是查找一个区域中的所有对象,所以根据空间数据对象所表示的区域范围,高效的获取该区域中的空间数据对象,是很重要的。
传统的一维数据库索引并不适合多维的空间搜索。如基于hash的索引结构适用于精确匹配查找值的搜索,而空间数据搜索通常是范围查找,而B-Tress这样的一维排序键值所以又难以满足对多维数据索引。
一个空间数据库由一系列对应空间对象的tuple组成,而每一个tuple具有一个唯一标示(tuple identifier,简称tupleID
吧),数据库可以通过这个唯一标示获取到该tuple。
R-Tree所做的就是将这些tupleID索引起来。
每一个叶子节点包含一组索引记录(index record,后文称之为entry)。
每个entry的格式如下:
(MBR,tupleID)
其中,MBR(Minimum Bounding Region)表示可以框住tupleID所对应的空间数据对象的最小N维矩形。
[a,b]
。
tupleID
为一个指向数据对象的指针。
非叶子节点的包含的entry格式如下:
(MBR,child-pointer)
其中,child-pointer
为指向其子节点的指针。而MBR
则是一个可以框住其child-pointer
对应的子节点上所有entry包含的MBR
的最小N维矩形。
对于一个基于磁盘存储的R-Tree索引,其每一个节点对应一个磁盘页(page)。为了节省磁盘IO,同时尽可能高效的利用磁盘空间,
令M
为一个节点所能包含的entry的最大值,m
为一个节点包含entry的最小值,有 m≤M2 。
R-Tree具有以下属性:
1. 每个节点的包含的entry的个数范围[m,M]
,除非该节点是根节点
2. 对于叶子节点中每一条entry(MBR,tupleID)
,其中MBR
表示能框住其tupleID
所对应的空间对象的最小N维矩形。
3. 对于非叶子节点中的每一条entry(MBR,child-pointer)
,其中MBR
表示能框住其子节点中所有entry对应的空间对象的MBR
的最小N维矩形。
4. 根节点由至少两个子节点,除非该节点同时也是叶子节点
5. 所有叶子节点出现在同一层。
包含N条索引记录的R-Tree:
Search 在根节点为T的R-Tree中搜索一个MBR为S的空间数据对象
Insert 为新的空间数据对象(tuple)插入索引记录(index record)
ChooseLeaf
过程,查找将要插入entry的叶子节点SplitNode
过程进行节点分裂AjustTree
过程,向上层传播节点的变化,包括可能产生的节点分裂与新entry加入引起的EI的变化ChooseLeaf 选择一个叶子节点放置索引记录F
AdjustTree 从叶子节点L向上传播MBR值的变化,以及可能发生的节点分裂
SplitNode
过程,产生节点P与PPDelete 删除索引记录E
FindLeaf
以定位包含索引记录E的叶子节点L,如果没有没有找到则停止CondenseTree
从L向上传播节点的变化FindLeaf 在R-Tree T中查找包含entry F的叶子节点L
FindLeaf
过程,直到F被找到或者所有的entry都检查过但仍为找到FCondenseTree 给定一个被删除了一个entry的叶节点L,如果剩下的entry少于m,则要进行节点合并,同时向上传播EI的变化。
insert
过程即可,而来自非叶子结点的entry需要被插入对应高度层的节点中。当一个节点上包含的entry数量超过M时,就会触发节点的分裂。节点分裂后,应当尽量避免一个查询需要访问多个节点的情况,而决定一个节点在查询中是否被访问的原因是该节点上的entry的MBR是否与查询区域向重合,所以应当是分裂后节点其对应的MBR尽可能的小。
将M+1个entry分为两组的所有情况穷举,并计算出所有情况的MBR值。显然这一方法复杂度过高。
PickSeeds
过程,选取两个组中的第一个entry。PickNext
过程,在剩下的尚未分组的entry中选择一个entry进行分组;将其加入包含该entry后,MBR扩展最小的组PickSeeds 在所有entry中,选择最不应该分为一组的两个entry,作为两个组的第一个entry
PickNext 首先选择归为不同组差别最大的entry进行分组(因为最后的entry很可能会根据补偿m的原则,不考虑分组造成的MBR扩展而直接进行分组)