文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:
1. 背景
在上一篇博客中提到了用ES来做搜索和统计,多个同行留言提醒用PG效率也可以很不错。自己查了些资料和文章,尤其是博友“遥想公瑾当年”一些列关于PG的文章,受益匪浅。综合公司目前的实际情况,总结几点想法。
由于公司项目太广(每年大于500个项目现场在实施、维护),对于数据库和地理服务器根据甲方现场环境很难统一要求,按地理服务器主要分为:ArcGIS、SuperMap、Geoserver;按数据库主要分为:Oracle、Mysql、Postgresql。介于此,我们之前将空间分析等逻辑通过适配三大地理服务器(OGC标准)来完成各项目的兼容,缺少直接对数据库层面的操作。通过开发一些维护工具来进行统计类业务的预处理。
考虑到实时(或伪实时)空间统计的需求越来越多,将目标转向数据库层面是一个必然的趋势。尤其是现在数据库对于空间索引、各类坐标系的广泛支持,其稳定性、规避传输层问题、效率等都有明显优势。
2. 采用PG进行统计
a.首先要解决PG能通用于所有项目,可以提出项目实施规范,基于docker快速搭建PG环境。在甲方采购用Oracle等数据库时,依然基于规范要求必须部署PG以存储空间数据(业务数据可依然存放于Oracle)。
b.基于区划信息统计一般分为网格、社区、街道、区、市等等。按照GIST索引的特性(类R树索引),其要素的四角范围对索引性能影响特别大。对于大范围查询,将大范围切分为小范围可以非常明显的优化查询效率。这里,我们直接采用网格作为查询单元,通过网格查询结果构造社区、街道、区的查询结果,则会效率更好。
c.空间数据来源于多种SHP数据,为了便于数据检索、查询、和效率的优化,设计空间信息目录表(资源关键信息整合表),基于该表进行统一的空间查询。
以2300个网格和260000个部件点要素进行效率验证,获取各网格中各类部件的数目,一共耗时5.6S:
3. 统计与数据更新如何同步的方案讨论
空间数据并不是一成不变的。由于统计数据来源于空间数据汇总表,而所有更新并不是针对汇总表的更新,而是针对具体空间表(如井盖表)等的更新。如何能将更新数据实时同步至汇总表,统计表如何同步更新,是一个值得讨论的问题。
真实项目中,数据统计的准确性并没有要求完全实时,这块可以作伪实时理解。所以问题可以简化为,每天(或几小时)空间统计表数据更新至最新统计结果。
对应,这里给出四种方案:
3.1定时重新生成汇总表,重新统计
这是思维上最简单的一种方案,即用定时任务每次重新生成汇总表(将空间数据采集汇总),然后再重新生成统计表。此方案虽然简单,但是代价太大,尤其是所有数据的重新采集是一个比统计本身耗时太多的工作。
3.2利用触发器
给每一个空间数据表建立一个触发器,当数据表变更时,同步触发对汇总表的操作。对于空间统计表定时更新。
此方案也比较简单,但是考虑到对所有空间表建立触发器,当更新频繁时对数据库性能有一定影响,还需慎重。
3.3利用中间件cannal进行数据库操作监听
通过部署cannal监听数据库的操作,对符合定义的操作进行日志记录,定时更新至汇总表中。统计表定时更新。
该方案的优点是不需要对所有表创建触发器,更为简洁优美,并且通过定时更新的方案,也能避免高频度操作时同步更新对数据库造成的压力。但是由于需要部署cannal,增加了项目的部署难度。
3.4系统操作日志记录
在系统层面对数据库的操作进行单独日志记录。定时解析该日志文件,并更新汇总表。统计表定时更新。
该方案无需特殊配置,只需通过代码完成日志写入和解析即可,部署简单,开发难度也不高。
其中日志记录可以借用Log4j来快速完成,其支持对指定代码类生成独立日志。可以对数据库操作类进行独立设置,即可:
-----欢迎转载,但保留版权,请于明显处标明出处:
如果您觉得本文确实帮助了您,可以微信扫一扫,进行小额的打赏和鼓励,谢谢 ^_^