AnalyticDB for PostgreSQL 空间数据分析实战

简介: 数字经济时代,数据是其关键的生产资料,而空间信息作为一重要属性集和模型特征集在业界形成广泛共识。政府层面,美国911之后,通信运营商为政府相关部门(如公安、交通、应急指挥等)提供手机定位信息受法律保护;社会部分行业,尤其涉及GIS、交通、物流、吃住行游、自动驾驶等,无不与空间信息强相关。由此,空间数据的存储、空间查询与分析等特性成为数据库的标配。本文主要介绍如何利用AnalyticDB for PostgreSQL对空间数据进行管理和分析应用。

数字经济时代,数据是其关键的生产资料,而空间信息作为一重要属性集和模型特征集在业界形成广泛共识。政府层面,美国911之后,通信运营商为政府相关部门(如公安、交通、应急指挥等)提供手机定位信息受法律保护;社会部分行业,尤其涉及GIS、交通、物流、吃住行游、自动驾驶等,无不与空间信息强相关。由此,空间数据的存储、空间查询与分析等特性成为数据库的标配,比如NOSQL的Redis/MongoDB、RDBMS的MySQL/SQLServer/Oracle等都有相应模块对其提供支持,PostgreSQL内核支持Geometric几何类型,提供点、线、面、矩形、圆等几何的存储、几何变换、空间关系判定(相交、包含、相等等)功能,模块功能相对单一,缺失坐标系转换特性且用法不太优雅(不符合OGC规范),PostgreSQL开源界为弥补内核Geometric特性缺陷,衍生出PostGIS扩展模块予以完善。
AnalyticDB PG版同样支持空间数据存储、简单/复杂空间查询、空间分析等功能。有所区别的是,公有云产品默认包含PostGIS扩展模块包,但生产实例不默认装载该扩展;专有云产品不包含PostGIS扩展模块包,但为用户提供PostGIS模块整合到专有云AnalyticDB PG版的解决方案。下面介绍如何利用AnalyticDB PG版对空间数据进行管理和应用?

通用操作

1)客户端连接实例
可参考连接实例

2)初次装载PostGIS扩展模块

-- 创建扩展
create extension postgis;

-- 查看版本
select postgis_version();
select postgis_full_version();

3)空间数据写入数据库表
首先创建带Geometry字段的表,SQL参考:

create table testg ( id int, geom geometry ) 
distributed by (id);

该SQL表示插入的空间数据不区分几何类型,几何类型包括Point / MultiPoint / Linestring / MultiLinestring / Polygon / MultiPolygon等。
如果在创建表时已知Geometry类型和SRID(有关SRID可参考 SRID),也可以参考如下SQL创建表:

create table test ( id int, geom geometry(point, 4326) ) 
distributed by (id);

Geometry类型指定Point类型,SRID为4326,SRID不指定默认为0。
写入SQL参考:

-- without srid
insert into testg values (1, ST_GeomFromText('point(116 39)'));

-- with srid
insert into test values (1, ST_GeomFromText('point(116 39)', 4326));

JDBC Java程序参考:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class PGJDBC {
    public static void main(String args[]) {
        Connection conn = null;
        Statement stmt = null;
        try{
            Class.forName("org.postgresql.Driver");
            //conn = DriverManager.getConnection("jdbc:postgresql://<host>:3432/<database>","<user>", "<password>");
            conn.setAutoCommit(false);
            stmt = conn.createStatement();
            
            String sql = "INSERT INTO test VALUES (1001, ST_GeomFromText('point(116 39)', 4326) )";
            stmt.executeUpdate(sql);
       
            stmt.close();
            conn.commit();
            conn.close();
        } catch (Exception e) {
            System.err.println(e.getClass().getName() + " : " + e.getMessage());
            System.exit(0);
        }
        System.out.println("insert successfully");
    }
}

如果是OSM格式数据,不用提前创建表,可以借助osm2pgsql工具导入,参考 openstreetmap数据导入
如果是SHP格式数据,不用提前创建表,可以借助shp2pgsql工具导入,参考 shp数据导入,也可以借助一些GIS客户端如ArcGIS Desktop等导入。

4)空间索引管理
创建空间索引SQL参考:

create index idx_test_geom on test using gist(geom);

idx_test_geom为自定义索引名,test为表名,geom为Geometry列名。
查看表有哪些索引SQL参考:

select * from pg_stat_user_indexes 
where relname='test';

查看索引大小SQL参考:

select pg_indexes_size('idx_test_geom');

索引重建SQL参考:

reindex index idx_test_geom;

删除索引SQL参考:

drop index idx_test_geom;

5)典型空间查询SQL
• BBOX范围查询

-- without srid
select st_astext(geom) from testg
where ST_Contains(ST_MakeBox2D(ST_Point(116, 39),ST_Point(117, 40)), geom);

-- with srid
select st_astext(geom) from test 
where ST_Contains(ST_SetSRID(ST_MakeBox2D(ST_Point(116, 39),ST_Point(117, 40)), 4326), geom);

ST_MakeBox2D算子生成一个Envelope。
• 几何缓冲范围查询

-- without srid
select st_astext(geom) from testg
where ST_DWithin(ST_GeomFromText('POINT(116 39)'), geom, 0.01);

-- with srid
select st_astext(geom) from test 
where ST_DWithin(ST_GeomFromText('POINT(116 39)', 4326), geom, 0.01);

ST_DWithin用法参考:ST_DWithin
• 多边形相交判定(在内部或在边界上)

-- without srid
select st_astext(geom) from testg
where ST_Intersects(ST_GeomFromText('POLYGON((116 39, 116.1 39, 116.1 39.1, 116 39.1, 116 39))'), geom);

-- with srid
select st_astext(geom) from test 
where ST_Intersects(ST_GeomFromText('POLYGON((116 39, 116.1 39, 116.1 39.1, 116 39.1, 116 39))', 4326), geom);

ST_*算子对大小写不敏感,更多用法可参考 PostGIS官方资料

注意:AnalyticDB PG 6.0不完全兼容PostGIS功能集,例如不支持 create extension postgis_topology,不推荐用Geography类型创建表(非要用,SRID默认为0或4326)。

典型案例

电子围栏场景
某客运监控服务运营商,通过安装在客车上的GPS定位终端收集定位数据,常见的业务有偏航报警、常去的服务区频次、驶入特定区域提醒(例如易发事故地段、积水结冰地段)等,这类业务是比较典型的电子围栏应用场景。
以驶入特定区域提醒业务为例,特定区域不会频繁变更且数据量偏少,可以一次采集定期更新,考虑区域表采用复制表,SQL参考:

CREATE TABLE ky_region (
  rid       serial,
  name      varchar(256),
  geom      geometry)
DISTRIBUTED REPLICATED;

插入Polygon / MultiPolygon类型的特定区域数据后,进行统计数据收集(Analyze 表名)并构建GIST索引。
判定驶入区域,可以分为两种情况:一种完全在区域内,一种是到达边界就要提醒。两种情况用到的空间算子有所区别,SQL参考:

-- 完全在区划内
select rid, name from ky_region
where ST_Contains(geom, ST_GeomFromText('POINT(116 39)'));

-- 考虑边界情况
select rid, name from ky_region
where ST_Intersects(geom, ST_GeomFromText('POINT(116 39)'));

SQL解释:输入变化的经纬度,查询区域表geom字段包含或相交与输入点的记录,如果为0条记录表示未驶入任何区域,如果为1条记录表示驶入某个区域,如果大于1条记录表示驶入多个区域(说明区域表有空间重叠的区域,需要从业务上验证空间重叠的合理性)。

智慧交通场景
某智慧交通场景,数据库包含线型轨迹表和其他业务表,一业务功能为查找历史轨迹表中曾经驶入过某一区域的轨迹ID,相关轨迹表结构:

create table vhc_trace_d (
 stat_date        text, 
 trace_id         text, 
 vhc_id           text, 
 rid_wkt          geometry) 
Distributed by (vhc_id) partition by LIST(stat_date)
(
 PARTITION p20191008 VALUES('20191008'),
 PARTITION p20191009 VALUES('20191009'),
 ......
);

轨迹按照天创建Partition表,每天导入数据后做统计数据收集,并对Partition表创建GIST空间索引。
业务SQL参考:

SELECT trace_id FROM vhc_trace_d
WHERE ST_Intersects(
  ST_GeomFromText('Polygon((118.732461  29.207363,118.732366  29.207198,118.732511  29.205951,118.732296  29.205644,
                  118.73226  29.205469,118.732350  29.20470,118.731708  29.203399,118.731701  29.202401, 118.754689 29.213488,
                  118.750827 29.21316,118.750272 29.213337,118.749677 29.213257,118.748699 29.213388,118.747715 29.213206,
                  118.746580 29.213831,118.74639 29.213872,118.744989 29.213858,118.743442 29.213795,118.74174 29.213002,
                  118.735633 29.208167,118.734422 29.207699,118.733045 29.207450,118.732803 29.207342,118.732461  29.207363))'), rid_wkt);

亿级轨迹表做空间查询RT在80ms内,完全满足业务对性能需求。

商业客流分析
某互联网生活服务运营商,基于AnalyticDB PG版做店铺客流量分析,数据库有两张业务表:User签到表和Shop店铺区域表,表结构参考:

-- user
create table user_label (
  ghash7        int, 
  uid           int, 
  workday_geo   geometry, 
  weekend_geo   geometry) 
distributed by (ghash7);

-- shop
create table user_shop (
  ghash7        int, 
  sid           int, 
  shop_poly     geometry) 
distributed by (ghash7);

业务表比较巧的设计是用Geohash或ZOrder编码等方式将地理空间几何降维作为分布键,而不用构建空间索引。
客流统计的SQL参考:

SELECT COUNT(1)
FROM (
    SELECT DISTINCT T0.uid FROM user_label T0 JOIN user_shop T1 
    ON T1.ghash7 = T0.ghash7
    WHERE T1.sid IN (1,2,3)
    AND (ST_Intersects(T0.workday_geo, T1.shop_poly) 
         OR ST_Intersects(T0.weekend_geo, T1.shop_poly))
) c;

与开源方案对标

开源领域,比较典型的能够支撑空间大数据管理与应用的方案有HBase+GeoMesa和Elasticsearch,我们简单做一下对标介绍。
截屏2020-03-10下午12.39.32.png

应用常见问题

1)对表Geometry字段创建了空间索引,空间查询为什么不走空间索引?
具体问题具体分析。通过Explain查看SQL执行计划,如果走的是SeqScan,可以尝试:

set enable_seqscan = off;

--或者调低random_page_cost
set random_page_cost = 10;

2)表数据量很大,为什么对表Geometry字段创建空间索引会失败?
这种情况是存在的,一方面是内存不够触发,另一方面创建索引需要足够耐心。PSQL客户端连接数据库,检查 maintenance_work_mem 参数配置项,根据实例规格可适当调整参数配置,SQL参考:

-- 参看参数配置
show maintenance_work_mem;

-- 修改参数配置
set maintenance_work_mem = '1GB';

另外如果是简单查询场景可以考虑Partition表结合空间索引方式,如果是复杂分析场景,建议考虑典型案例中的商业客流分析案例。

相关实践学习
阿里云云原生数据仓库AnalyticDB MySQL版 使用教程
云原生数据仓库AnalyticDB MySQL版是一种支持高并发低延时查询的新一代云原生数据仓库,高度兼容MySQL协议以及SQL:92、SQL:99、SQL:2003标准,可以对海量数据进行即时的多维分析透视和业务探索,快速构建企业云上数据仓库。 了解产品 https://www.aliyun.com/product/ApsaraDB/ads
目录
相关文章
|
8月前
|
存储 SQL 监控
数据中台架构解析:湖仓一体的实战设计
在数据量激增的数字化时代,企业面临数据分散、使用效率低等问题。数据中台作为统一管理与应用数据的核心平台,结合湖仓一体架构,打通数据壁垒,实现高效流转与分析。本文详解湖仓一体的设计与落地实践,助力企业构建统一、灵活的数据底座,驱动业务决策与创新。
|
12月前
|
分布式计算 运维 监控
Dataphin离线数仓搭建深度测评:数据工程师的实战视角
作为一名金融行业数据工程师,我参与了阿里云Dataphin智能研发版的评测。通过《离线数仓搭建》实践,体验了其在数据治理中的核心能力。Dataphin在环境搭建、管道开发和任务管理上显著提效,如测试环境搭建从3天缩短至2小时,复杂表映射效率提升50%。产品支持全链路治理、智能提效和架构兼容,帮助企业降低40%建设成本,缩短60%需求响应周期。建议加强行业模板库和移动适配功能,进一步提升使用体验。
|
8月前
|
数据采集 数据可视化 搜索推荐
Python数据分析全流程指南:从数据采集到可视化呈现的实战解析
在数字化转型中,数据分析成为企业决策核心,而Python凭借其强大生态和简洁语法成为首选工具。本文通过实战案例详解数据分析全流程,涵盖数据采集、清洗、探索、建模、可视化及自动化部署,帮助读者掌握从数据到业务价值的完整技能链。
988 0
|
9月前
|
SQL 存储 关系型数据库
PostgreSQL窗口函数避坑指南:如何让复杂分析查询提速300%?
本文基于真实企业级案例,深入剖析PostgreSQL窗口函数的执行原理与性能陷阱,提供8大优化策略。通过定制索引、分区裁剪、内存调优及并行处理等手段,将分钟级查询压缩至秒级响应。结合CTE分阶段计算与物化视图技术,解决海量数据分析中的瓶颈问题。某金融客户实践表明,风险分析查询从47秒降至0.8秒,效率提升5800%。文章附带代码均在PostgreSQL 15中验证,助您高效优化SQL性能。
433 0
|
6月前
|
存储 人工智能 关系型数据库
阿里云AnalyticDB for PostgreSQL 入选VLDB 2025:统一架构破局HTAP,Beam+Laser引擎赋能Data+AI融合新范式
在数据驱动与人工智能深度融合的时代,企业对数据仓库的需求早已超越“查得快”这一基础能力。面对传统数仓挑战,阿里云瑶池数据库AnalyticDB for PostgreSQL(简称ADB-PG)创新性地构建了统一架构下的Shared-Nothing与Shared-Storage双模融合体系,并自主研发Beam混合存储引擎与Laser向量化执行引擎,全面解决HTAP场景下性能、弹性、成本与实时性的矛盾。 近日,相关研究成果发表于在英国伦敦召开的数据库领域顶级会议 VLDB 2025,标志着中国自研云数仓技术再次登上国际舞台。
686 0
|
10月前
|
存储 关系型数据库 MySQL
大数据新视界 --面向数据分析师的大数据大厂之 MySQL 基础秘籍:轻松创建数据库与表,踏入大数据殿堂
本文详细介绍了在 MySQL 中创建数据库和表的方法。包括安装 MySQL、用命令行和图形化工具创建数据库、选择数据库、创建表(含数据类型介绍与选择建议、案例分析、最佳实践与注意事项)以及查看数据库和表的内容。文章专业、严谨且具可操作性,对数据管理有实际帮助。
大数据新视界 --面向数据分析师的大数据大厂之 MySQL 基础秘籍:轻松创建数据库与表,踏入大数据殿堂
|
消息中间件 数据挖掘 Kafka
Apache Kafka流处理实战:构建实时数据分析应用
【10月更文挑战第24天】在当今这个数据爆炸的时代,能够快速准确地处理实时数据变得尤为重要。无论是金融交易监控、网络行为分析还是物联网设备的数据收集,实时数据处理技术都是不可或缺的一部分。Apache Kafka作为一款高性能的消息队列系统,不仅支持传统的消息传递模式,还提供了强大的流处理能力,能够帮助开发者构建高效、可扩展的实时数据分析应用。
966 5
|
数据采集 数据可视化 数据挖掘
基于Python的数据分析与可视化实战
本文将引导读者通过Python进行数据分析和可视化,从基础的数据操作到高级的数据可视化技巧。我们将使用Pandas库处理数据,并利用Matplotlib和Seaborn库创建直观的图表。文章不仅提供代码示例,还将解释每个步骤的重要性和目的,帮助读者理解背后的逻辑。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供有价值的见解和技能。
647 0
|
SQL JSON 数据可视化
基于 DIFY 的自动化数据分析实战
本文介绍如何使用DIFY搭建数据分析自动化流程,实现从输入需求到查询数据库、LLM分析再到可视化输出的全流程。基于经典的employees数据集和DIFY云端环境,通过LLM-SQL解析、SQL执行、LLM数据分析及ECharts可视化等模块,高效完成数据分析任务。此方案适用于人力资源分析、薪酬管理等数据密集型业务,显著提升效率并降低成本。
15555 16
|
SQL 缓存 数据处理
数据无界、湖仓无界,Apache Doris 湖仓一体典型场景实战指南(下篇)
Apache Doris 提出“数据无界”和“湖仓无界”理念,提供高效的数据管理方案。本文聚焦三个典型应用场景:湖仓分析加速、多源联邦分析、湖仓数据处理,深入介绍 Apache Doris 的最佳实践,帮助企业快速响应业务需求,提升数据处理和分析效率
773 3
数据无界、湖仓无界,Apache Doris 湖仓一体典型场景实战指南(下篇)

相关产品

  • 云数据库 RDS PostgreSQL 版
  • 推荐镜像

    更多