怎么查你附近的餐厅

最近在看Martin大神的一本书,叫《Designing Data-Intensive Application》(《设计数据密集型应用》)。里面提到一个概念,叫做多维索引。

书中给了一个例子:餐厅搜索网站可能有一个数据库,其中包含每个餐厅的精度和维度。当用户在地图上查看餐厅时,网站需要搜索用户查看的矩形地图区域内的所有餐厅。这就需要一个二维的查询,如下:

SELECT * FROM restaurants WHERE latitude > 51.4946 AND latitude < 51.5079
AND longitude > -0.1162 AND longitude < -0.1004;

我们常用的索引结构,比如B树、B+树、LSM树,对于这种查询不是很高效:它只能返回一个经度范围内的所有餐厅,或者一个维度范围内的所有餐厅,但是不能同时满足。比较普遍的做法,采用一种特殊化的空间索引,书中给出了R树的概念。

R树是一棵平衡树,可以理解为B树在K维空间上的扩展。利用空间对象的MBR(Minimal Bounding Rectangle,最小边界矩形)的方法,来构建R树。R树的核心思想是聚合距离相近的节点并在树结构的上一层将其表示为这些节点的最小外接矩形,这个最小外接矩形就成为上一层的一个节点。因为所有节点肯定在外接矩形内部,所以如果和某个矩形不相交的查询一定跟这个矩形的所有节点都不相交。利用这个原理,可以过滤大范围不符合条件的数据,只需要查找相交矩阵,缩小了查询范围。

我们先看一个R树的基本表示图:(图片来源于网络)

R树中叶子结点保存了实际的数据,非叶子节点表示其所有孩子节点矩形的最小外接矩形。所以越靠近根节点,表示的矩形越大,代表的范围越广。

我们先从二维空间举例,比较容易想象。比如我们我们所有的数据都是二维空间下的坐标,那我们把相邻的坐标连接到一起,形成一个不规则形状,然后我们用最小外接矩形框住这个不规则形状,就形成了R树的叶子结点。如图中,我们就形成了R8-R19,共12个最小外接矩形,每个外接矩形内都是若干的数据节点。

接着我们再把这12个外接矩形中相邻的聚集到一起,比如R8、R9、R10离得比较近,我们把他们三个聚集到一起,再用一个更高层次的最小外接矩形框住,形成了R3,R3就作为了R8、R9、R10的父节点,保存到了R树中的更高一层。以此类推,一直到根节点,根节点是两个矩形,包含了咱们左右的低层次的矩形。这就形成了一棵R树。

比如我们前面中说的餐厅例子,我们就可以把相邻的餐厅聚集到一起,形成外接矩形。再把这些矩形聚集到一起,形成更大的外接矩形。直到剩下两个矩形为止,就构建成了一个可以范围查找餐厅的R树。

同理,可以扩展到n维空间,比如天气查询,有时间、湿度、温度三个维度,这个外接矩形就演变为了三维空间的外接矩形。

R树的搜索过程是什么样的呢?

如上图,比如我们搜索的条件矩形为黑色矩形所示,我们从根节点开始,判断是否和搜索矩形相交。如果相交则遍历其子节点。如果子节点为叶子结点,则遍历叶子节点中数据是否满足条件。

R1与搜索矩形相交,则继续查找子节点。子节点R3、R4与搜索矩形相交,则继续查找子节点。R3的子节点R9、R10,R4的子节点R11都与搜索矩形相交,并且时叶子结点,则搜索R9、R10、R11的所有数据节点,判断是否满足条件即可。

插入和删除过程不再重复说了,百科中有非常详细的介绍了。如果理解了R树的原理,把每个矩形可以看成普通B树中的一个节点,对于R树的插入、删除过程与B树类似,但是R树较为关键的在于如何分裂矩形和如何合并矩形。

R树搜索我们会发现一个问题,即矩形之间会有重叠,会导致搜索时,会产生多路搜索才能找到符合条件的数据,极端情况下会退化为线性搜索,覆盖重叠的程度,极大地影响了搜索效率。所以又产生了R+树,每个矩形之间是不覆盖重叠的,这样搜索的效率会大大提高,但是也同样会带来问题,当进行合并、分裂时,需要重新构建矩阵,防止覆盖,也就是插入和删除效率会较低。

以上是简单记录一下R树的概念,原谅我孤陋寡闻,对于多维度索引还有这种结构。并且关于R树的介绍文章都翻译于R树论文,配图、错字都完全一样,抄过来也没有什么意义,所以感兴趣的可以随便搜一篇看看,不过关于删除操作还是没有理解,准备看一下原论文是怎么写的,感觉可能是第一个翻译的作者自身也没有理解,导致后面抄过来的更让人没法理解了,就像是考试,能把数学填空题13抄成了B一样。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值