Skip to content

工作扫盲之Postgres

约 1218 字大约 4 分钟

2025-09-23

作为一名主要使用MySQL的开发者,最近我入职了一家需要处理地理空间数据的公司,开始接触PostgreSQL(简称PG)数据库。在使用过程中,我发现PG不仅仅是一个关系型数据库,更是一个功能强大的数据平台,特别是其PostGIS扩展,为地理信息系统(GIS)应用提供了强大支持。

PostgreSQL vs MySQL:主要区别

在深入了解PostGIS之前,先简单对比一下PostgreSQL和MySQL的主要区别:

  1. 架构差异

    • MySQL:4级结构(实例、数据库、表、列)
    • PostgreSQL:5级结构(实例、数据库、模式Schema、表、列)
  2. 稳定性与性能

    • PostgreSQL在高并发读写下性能曲线更平稳,负载逼近极限时仍能维持稳定
    • MySQL在极端写入密集型工作负载方面可能有优势
  3. 数据类型与扩展性

    • PostgreSQL支持更丰富的数据类型(几何类型、数组、JSON等)
    • PostgreSQL的扩展系统更为强大,PostGIS就是其中最著名的扩展之一
  4. 事务与ACID支持

    • PostgreSQL在所有配置中都完全兼容ACID
    • MySQL只有在使用InnoDB和NDB集群存储引擎时才符合ACID标准
  5. 空间数据处理

    • PostgreSQL的PostGIS扩展在GIS领域处于优势地位
    • MySQL的空间扩展功能相对有限

PostGIS简介

PostGIS是PostgreSQL的一个扩展,为PostgreSQL增加了地理空间数据处理能力。它遵循开放地理空间联盟(OGC)的Simple Features for SQL规范,提供了丰富的地理空间数据类型、函数和索引支持。

PostGIS的主要特性

  1. 丰富的几何数据类型

    • 点(Point)、线(LineString)、多边形(Polygon)
    • 多点(MultiPoint)、多线(MultiLineString)、多多边形(MultiPolygon)
    • 几何集合(GeometryCollection)
    • 3D类型如TIN和多面体表面
  2. 球面坐标支持

    • 通过geography数据类型支持球面坐标系统
    • 直接处理经纬度坐标,无需投影转换
  3. 栅格数据支持

    • 支持各种像素类型和每个栅格超过1000个波段
    • 通过postgis_raster扩展提供
  4. 空间索引

    • 基于GiST(广义搜索树)的R树空间索引
    • 高效的空间查询性能
  5. 拓扑支持

    • 通过postgis_topology扩展提供SQL/MM拓扑支持

PostGIS核心函数

PostGIS提供了大量用于空间数据处理的函数,以下是一些常用的核心函数:

几何对象创建函数

-- 创建点
SELECT ST_MakePoint(longitude, latitude);

-- 创建线
SELECT ST_MakeLine(point1, point2);

-- 创建多边形
SELECT ST_MakePolygon(exterior_ring, ARRAY[interior_ring1, interior_ring2]);

空间关系判断函数

-- 判断两个几何对象是否相交
SELECT ST_Intersects(geometry1, geometry2);

-- 判断一个几何对象是否包含另一个
SELECT ST_Contains(geometry1, geometry2);

-- 判断两个几何对象是否相距一定距离内
SELECT ST_DWithin(geometry1, geometry2, distance);

空间测量函数

-- 计算两点间距离
SELECT ST_Distance(point1, point2);

-- 计算面积
SELECT ST_Area(polygon);

-- 计算长度
SELECT ST_Length(linestring);

空间处理函数

-- 缓冲区分析
SELECT ST_Buffer(geometry, distance);

-- 几何对象简化
SELECT ST_Simplify(geometry, tolerance);

-- 空间交集
SELECT ST_Intersection(geometry1, geometry2);

坐标系转换函数

-- 将几何对象从一个坐标系转换到另一个坐标系
SELECT ST_Transform(geometry, target_srid);

-- 设置几何对象的坐标系
SELECT ST_SetSRID(geometry, srid);

实际应用场景

PostGIS在许多领域有广泛应用,以下是几个典型场景:

1. 位置服务与导航

-- 查找距离指定位置5公里范围内的所有餐厅
SELECT name, address, ST_Distance(
    geography(location),
    geography(ST_SetSRID(ST_MakePoint(longitude, latitude), 4326))
) AS distance
FROM restaurants
WHERE ST_DWithin(
    geography(location),
    geography(ST_SetSRID(ST_MakePoint(longitude, latitude), 4326)),
    5000
)
ORDER BY distance;

2. 地理围栏(Geofencing)

-- 判断一个点是否在指定区域内
SELECT ST_Contains(
    area_polygon,
    ST_SetSRID(ST_MakePoint(longitude, latitude), 4326)
) AS is_inside
FROM geofence_areas
WHERE area_id = 123;

3. 空间分析与统计

-- 计算每个行政区内的商店数量
SELECT a.district_name, COUNT(s.id) AS shop_count
FROM administrative_areas a
JOIN shops s ON ST_Contains(a.geometry, s.location)
GROUP BY a.district_name
ORDER BY shop_count DESC;

4. 路径规划

-- 使用pgRouting扩展(基于PostGIS)进行最短路径查询
SELECT * FROM pgr_dijkstra(
    'SELECT id, source, target, cost, reverse_cost FROM road_network',
    start_node_id,
    end_node_id,
    directed := true
);

总结

PostgreSQL结合PostGIS提供了强大的空间数据处理能力,远超MySQL的空间扩展。对于需要处理地理信息的应用,特别是地图服务、位置分析、路径规划等场景,PostgreSQL+PostGIS是一个非常理想的选择。

作为一个从MySQL迁移到PostgreSQL的开发者,我发现学习曲线并不陡峭,而获得的空间数据处理能力却是质的飞跃。如果你的应用需要处理地理空间数据,强烈推荐尝试PostgreSQL和PostGIS的组合。

参考资源

————————到底啦!————————