新闻详情

新闻详情

首页 / 资讯中心 / 详情

System Design 101:四叉树(Quadtree)——用递归四分区解决“查找附近商家“的空间索引问题

发布时间:2026/10/2 8:04:27来源:尧图网络
System Design 101:四叉树(Quadtree)——用递归四分区解决“查找附近商家“的空间索引问题
后端文档教程【免费下载链接】system-design-101Explain complex systems using visuals and simple terms. Help you prepare for system design interviews.项目地址https://gitcode.com/GitHub_Trending/sy/system-design-101点击查看免费下载在 Yelp、Google Maps 这类位置服务中找出我附近的餐馆是最常见也最具挑战性的查询之一。本指南以 data/guides/quadtree.md 为核心完整讲解四叉树Quadtree这一用于二维空间数据分区的经典内存数据结构它的定义、构建流程、邻近查询的三步走策略以及 LBSLocation-Based Service基于位置的服务服务器上线与重建时的工程注意事项。读完你不仅能在系统设计面试中讲清四叉树的来龙去脉还能理解它为什么是内存结构、何时该用它、以及它和 geohash 等其他空间索引方案的取舍。什么是四叉树递归细分的空间分区结构四叉树是一种常用于划分二维空间的数据结构。它的核心思想是通过递归地把二维空间细分为四个象限quadrants即四个网格直到每个网格中的内容满足设定的条件为止。在查找附近商家的场景里四叉树的构造逻辑非常直观**根节点root node**代表整个世界地图根节点被递归地拆分成 4 个象限持续拆分直到没有任何一个节点里包含超过 100 家商家为止。也就是说四叉树不会机械地把地图切成等大的格子而是根据商家分布的疏密程度自适应地决定划分粒度商家密集的城区会被切得更细商家稀少的海洋区域则保持较大的网格。这正是它在空间查询场景中高效的根本原因。四叉树的构建过程从根节点到满足阈值四叉树的构建是自顶向下的递归过程可概括为以整个世界地图作为根节点判断当前节点包含的商家数量若商家数量超过阈值本例为 100 家则把该节点一分为四得到四个子象限对每个子象限重复步骤 23直到所有叶子节点的商家数都不超过阈值。这套规则保证了构建出来的树形结构总是平衡于数据分布无论地图上商家的分布多么不均匀例如市中心极度密集、海洋几乎为空叶子节点的负载都被约束在可控范围内。如何用四叉树查询附近商家三步走构建完成后的查询流程原文档给出了清晰的三个步骤在内存中构建好四叉树从根节点开始遍历沿着树向下寻找直到找到查询起点search origin所在的那个叶子节点判定叶子节点的数据量如果该叶子节点恰好包含 100 家商家直接返回这 100 家否则少于 100 家例如起点落在稀疏区域从它的邻居节点中补充商家直到返回足够数量的结果。可以看到四叉树把查附近从遍历全量商家算距离即原文档 data/guides/proximity-service.md 中提到的低效做法变成了一次沿树下行的定位 局部邻居补足查询代价与树的深度相关而不是与商家总量相关。为什么四叉树是内存数据结构而不是数据库原文档特别强调了一个容易被忽略的关键定位四叉树是一种内存数据结构in-memory data structure它不是数据库解决方案。这意味着四叉树运行在每一台 LBSLocation-Based Service服务器上数据结构在服务器启动start-up时构建常驻内存服务查询数据库如商家信息库仍然是商家的事实来源四叉树只是每台服务器为加速本地查询而准备的一份内存副本索引。这种设计的优点是查询延迟极低纯内存遍历、无网络与磁盘 IO代价则是每个服务器实例都需要独立构建一份树构建成本会在服务器扩容、发布、重启时反复出现——这正是下文工程问题的来源。更新 LBS 服务器与重建四叉树滚动发布避免服务棕降由于四叉树是启动时在内存中构建的更新服务器版本会带来一个显著的运维挑战原文档给出了三点关键事实构建耗时可观当商家规模达到2 亿200 million级别时在服务器启动时构建一棵内存四叉树可能需要几分钟构建期间无法服务树还没建好这台服务器无法对外提供流量必须增量滚动发布因此发布新版本时应该一次只把一小部分服务器a small subset灰度上线而不是同时重启整个集群。为什么要滚动发布因为如果一次性把大范围的服务器集群a large swathe of the server cluster同时下线去重建四叉树就会造成服务棕降service brownout——即服务虽然没有完全宕机但整体容量骤降、响应变慢、用户体验明显劣化。分批灰度发布可以保证集群中始终有足够多的已完成构建的服务器在承接流量把重建代价控制在极小比例内。发布时的实际操作要点综合原文档一次安全发布可拆解为步骤动作目的1挑选一小批服务器如 5%10%从负载均衡中摘除让这批实例不再接收新流量2在新代码中重启这批实例等待四叉树在内存中构建完成用几分钟的构建时间换取后续的低延迟查询3健康检查通过后把这批实例重新接入流量池恢复服务容量4重复上述过程逐批推进到全部服务器避免大范围离线导致服务棕降四叉树与 geohash两种空间索引方案的取舍在阅读四叉树时很容易联想到同仓库 data/guides/proximity-service.md 中讲解的另一种空间索引方案geohash。两者解决的是同一类问题思路却截然不同geohash先把地球按经、纬度切成固定层级的网格纬度区间[-90,0]、[0,90]与经度区间[-180,0]、[0,180]各用 0/1 编码再用交替拼接经纬位的方式生成网格编码最后用SELECT * FROM geohash_index WHERE geohash LIKE 01%这类前缀查询在数据库里检索附近商家四叉树则完全在内存中按商家密度自适应分区不依赖数据库 SQL直接把查询压缩为树上的遍历与邻居补充。两者的局限性也互为映照原文档指出geohash 的问题在于一个网格里可能挤满商家如纽约市中心另一个网格却空无一人如海洋而四叉树正是通过超过阈值就继续细分的规则天然缓解了这种密度不均问题。当然四叉树也并非万能——它只存在于单个服务器内存中2 亿级数据重建耗时数分钟、构建期间不可服务这些约束决定了它适合查询密集、更新低频、可容忍启动预热的场景而在需要跨服务器共享索引、增量更新时则要考虑其他方案。从本指南继续深入本指南主体data/guides/quadtree.mdgeohash 空间索引方案与 LBS 整体设计data/guides/proximity-service.md地理编码、路线规划与地图分块渲染data/guides/design-google-maps.md空间数据与数据库选型的关系Geospatial 类数据库data/guides/how-to-choose-the-right-database.md全仓库目录与更多系统设计主题README.md。一句话总结四叉树用递归四分 密度自适应把海量空间数据组织成内存中的层级索引用定位叶子节点 邻居补足完成低延迟邻近查询再配合滚动发布规避重建期间的服务棕降——这三件事串起来就是位置服务中最经典的空间索引实战模型。赞分享后端文档教程【免费下载链接】system-design-101Explain complex systems using visuals and simple terms. Help you prepare for system design interviews.项目地址https://gitcode.com/GitHub_Trending/sy/system-design-101点击查看免费下载相关推荐d3-quadtree 深度指南d3 v7 中的四叉树空间分区、最近邻查找与遍历d3 quadtree 深度指南d3 v7 中的四叉树空间分区、最近邻查找与遍历 本篇技术指南以 d3 官方文档 docs/d3 quadtree.md ht前端数据可视化图表库Swift 四叉树QuadTree实现指南二维空间点存储与矩形区域查询Swift 四叉树QuadTree实现指南二维空间点存储与矩形区域查询 导读 本指南基于 Swift Algorithm Club 仓库中的 QuadTr示例工程教程CANN/driverUB端口链路状态查询dcmiv2\_get\_ub\_port\_link\_statusa nameZH CN_TOPIC_0000002524828419 /a 函数驱动开发人工智能CANN上一篇Roshi架构深度解析从Redis到LWW-element-set的完整实现下一篇RIOT 平台 SenseBox MCUSAMD21开发板支持指南烧录、UART、I2C 与 XBEE 外设详解创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Claude Code 高效编程实践:用 git diff 审查未提交代码并生成 commit 信息 2026/10/2 20:35:40

Claude Code 高效编程实践:用 git diff 审查未提交代码并生成 commit 信息

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
国产电源AC工具新突破:频域阻抗与电热多物理场融合 2026/10/2 20:35:40

国产电源AC工具新突破:频域阻抗与电热多物理场融合

1. 国产电源AC工具,为什么值得专门来聊这几年,电源圈子里聊国产工具的人明显多了起来。上个月和一位做服务器电源的工程师吃饭,他吐槽说以前环路增益都是排队借实验室那台老外网分仪来测,现在手里那台国产阻抗分析仪居然也能把幅相…

阅读更多 →
UART通信详解:从物理层电平到STM32 HAL库配置与调试实战 2026/10/2 20:35:40

UART通信详解:从物理层电平到STM32 HAL库配置与调试实战

UART在我眼里一直是通信协议里最“亲民”的那个。它只有两根数据线,没有时钟线,协议帧结构简单到看一眼就能记住,可它承载了无数嵌入式设备从调试到量产的全过程。我最早接触单片机就是从点亮LED和printf重定向开始的,而那个print…

阅读更多 →
彻底卸载Windows上的Google Chrome:注册表残留清理的两种方法,绝对有效 2026/10/2 20:35:39

彻底卸载Windows上的Google Chrome:注册表残留清理的两种方法,绝对有效

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
EMC整改实战:从辐射超标频点反推源头,在Layout阶段消灭EMI 2026/10/2 20:35:33

EMC整改实战:从辐射超标频点反推源头,在Layout阶段消灭EMI

做EMC整改这些年,我最怕的不是标准严,而是连超标频点都说不清楚来源。不少工程师一听到辐射超标就急着加屏蔽、换磁珠、补电容,结果钱花了、板子改了、效果却往往只在某个频段上稍微降了一点,换个测试环境又重新冒头。真正靠谱的做…

阅读更多 →
I2C从机设计进阶:时钟延展与死锁恢复的鲁棒性实战 2026/10/2 20:35:33

I2C从机设计进阶:时钟延展与死锁恢复的鲁棒性实战

1. 从模式设计与总线鲁棒性:为什么时钟延展和死锁恢复是I2C从机的必修课做嵌入式开发的朋友对I2C总线肯定不陌生,两根线(SDA、SCL)挂一堆设备,布线简单、协议成熟,几乎是传感器、EEPROM、OLED屏的标配接口。…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉