一篇文章带你玩转PostGIS空间数据库 1

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
简介: 一篇文章带你玩转PostGIS空间数据库

一、空间数据库介绍

1.什么是空间数据库

人类理解世界其实是按照三维的角度,而传统的关系型数据库是二维的,要想描述空间地理位置,点、线、面,我们就需要一个三维数据库,即所谓空间数据库。



b345576152b04c54b0e90d07693bbbee.jpg

postGIS就是一个空间数据库。

2.空间数据库是怎么存储的

除了普通数据库所具备的字符串、数值、日期等,空间数据库增加了空间数据类型。

这些空间数据类型抽象并封装了诸如边界(boundary)和维度(dimension)等空间结构。

可以这么理解,空间数据库内置了许多属性,这些属性用于描述空间结构信息。


以点(Point)数据类型为例,一个点可以由它在某一坐标参考系下的X、Y坐标值来表示,如“POINT(116.4074 39.9042)”表示了一个位于北京市中心的点。


并且,空间数据类型按类型层次结构组织。每个子类型继承其父类型的结构(属性)和行为(方法或函数)。

562bbcc0d3304fdf826320521dde7336.png


3.空间数据库有索引吗

普通数据库有索引。空间数据库也有空间索引,它有什么作用呢?

举个应用的栗子帮助理解。查找你附近100m以内的所有商场。如果没有空间索引,你需要苦逼的按照坐标取平方根穷举计算,然后保留所有距离小于100的商场数据。


image.png

但是空间数据库的索引设计有难点:如何组织数据的结构。普通数据库用B+树等就可以。空间索引有很多种,网格索引、四叉树索引、金字塔索引…

其原理:过于先进,暂不展示

dc8a7b5f556f476296f2b7b3c3db034a.png

4.空间函数是什么东东

二维的虫子可想不到三维的世界有多复杂:分析几何信息、确定空间关系…

空间数据库当然需要专业的解决这些问题,因此,它内置空间函数。

空间函数主要分为五类:


转换 —— 在geometry(PostGIS中存储空间信息的格式)和外部数据格式之间进行转换的函数

管理 —— 管理关于空间表和PostGIS组织的信息的函数

检索 —— 检索几何图形的属性和空间信息测量的函数

比较 —— 比较两种几何图形的空间关系的函数

生成 —— 基于其他几何图形生成新图形的函数

二、PostGIS快速入门

1.postGIS是什么

其实您应该猜到了,他就是在postgreSQL上的一个插件,但是因为有它,postgreSQL摇身一变,成了一个强大的空间数据库。

20799bc3696b43fea7fae9e478bcf9ae.jpg

这就意味着,这哥们儿开源啊。

2.postGIS怎么用啊

这个教程主要是帮助快速理解什么是postGIS,因此不会太细致。

自行下载安装postGreSQL、postGIS

导入数据文件shape file

一个shapfile必须有的文件:

.shp —— 存储地理要素的几何信息

.shx —— 存储要素几何图形的索引信息

.dbf —— 存储地理要素的属性信息(非几何信息)

可选文件包括:

.prj —— 存储空间参考信息,即地理坐标系统信息和投影坐标系统信息。使用well-known文本格式进行描述。

image.png

Soga!原来就是导文件给你可视化展示啊。这题咱会!

操作数据,用SQL

哦,原来还是熟悉的配方,还是原来的味道。

SELECT name
FROM nyc_neighborhoods
WHERE boroname = 'Brooklyn';

元数据管理

PostGIS提供了两张表用于追踪和报告数据库中的几何图形(这两张表中的内容相当于元数据)

第一张表spatial_ref_sys —— 定义了数据库已知的所有空间参照系统,稍后将对其进行更详细的说明。

第二张表(实际上是视图-view)geometry_columns —— 提供了数据库中所有空间数据表的描述信息


通过查询该表,GIS客户端和数据库可以确定检索数据时的预期内容,并可以执行任何必要的投影、处理、渲染而无需检查每个几何图形(geometry)—— 这些就是元数据所带来的作用。

表示真实世界的对象

Simple Features for SQL(SFSQL)规范是PostGIS开发的原始指导标准,它定义了如何表示真实世界的对象。但是这个哥们只表示了二维,而PostGIS扩展了3维、4维的表示。

说人话,就是可以表示:点、线串、多边形、图形集合(Collection)。

举一个图形集合的例子。

SELECT name, ST_AsText(geom)
FROM geometries
WHERE name = 'Collection';

返回结果就是一个点和一个多边形的集合。

e4abcd8067d64f34908dfc3245bfe1bd.png

基本操作而已,你是不是也学会了。

几何图形的存储

PostGIS支持以多种格式进行几何图形的输入和输出:


Well-known text(WKT)

Well-known binary(WKB)

Geographic Mark-up Language(GML)

Keyhole Mark-up Language(KML)

GeoJson

Scalable Vector Graphics(SVG)

使用方法就是调用encode函数,以下SQL查询展示了一个WKB表示形式的示例

SELECT encode(
  ST_AsBinary(ST_GeometryFromText('LINESTRING(0 0,1 0)')),
  'hex');

由于WKT和WKB是在SFSQL规范中定义的,因此它们不能处理3维或4维的几何图形。对于这些情况,PostGIS定义了Extended Well Known Text(EWKT)和Extended Well Known Binary(EWKB)格式以用于处理3维或4维的几何图形。

数据类型转换

PostgreSQL包含一个简短形式的语法,允许数据从一种类型转换到另一种类型,即类型转换语法:

olddata::newtype

例如,将double类型转换为文本字符串类型:

SELECT 0.9::text;

搞半天,原来这玩意有手(册)就行,不用太费劲学。



e61b428ec8b244b2bc9c2cb7143d5fce.jpg内置函数

这里介绍下它有哪些功能函数,同志们心里有个底,需要时查查手册。

sum(expression) aggregate to return a sum for a set of records
count(expression) aggregate to return the size of a set of records
ST_GeometryType(geometry) returns the type of the geometry
ST_NDims(geometry) returns the number of dimensions of the geometry
ST_SRID(geometry) returns the spatial reference identifier number of the geometry
ST_X(point) returns the X ordinate
ST_Y(point) returns the Y ordinate
ST_Length(linestring) returns the length of the linestring
ST_StartPoint(geometry) returns the first coordinate as a point
ST_EndPoint(geometry) returns the last coordinate as a point
ST_NPoints(geometry) returns the number of coordinates in the linestring
ST_Area(geometry) returns the area of the polygons
ST_NRings(geometry) returns the number of rings (usually 1, more if there are holes)
ST_ExteriorRing(polygon) returns the outer ring as a linestring
ST_InteriorRingN(polygon, integer) returns a specified interior ring as a linestring
ST_Perimeter(geometry) returns the length of all the rings
ST_NumGeometries(multi/geomcollection) returns the number of parts in the collection
ST_GeometryN(geometry, integer) returns the specified part of the collection
ST_GeomFromText(text) returns geometry
ST_AsText(geometry) returns WKT text
ST_AsEWKT(geometry) returns EWKT text
ST_GeomFromWKB(bytea) returns geometry
ST_AsBinary(geometry) returns WKB bytea
ST_AsEWKB(geometry) returns EWKB bytea
ST_GeomFromGML(text) returns geometry
ST_AsGML(geometry) returns GML text
ST_GeomFromKML(text) returns geometry
ST_AsKML(geometry) returns KML text
ST_AsGeoJSON(geometry) returns JSON text
ST_AsSVG(geometry) returns SVG text

总的来说,就是可以:求面积、求边界、求大边形里有多少小多边形…在多维的世界里为所欲为。

空间关系

目前为止,我们一次只能处理一个几何图形。

空间数据库之所以强大,是因为它们不仅能存储几何图形,而且还能够分析几何图形之间的关系。


诸如"哪一个是离公园最近的自行车位?"或者"地铁线路和街道的交叉路口在哪里?"这样的问题,只能通过比较、分析表示自行车位、街道和地铁线路的几何图形来回答。


OGC标准定义了以下一组用于比较几何图形的方法。


ST_Equals(geometry A, geometry B)用于测试两个图形的空间相等性。

ST_Intersects、ST_Crosses和ST_Overlaps都用于测试几何图形内部是否相交。

ST_Touches()测试两个几何图形是否在它们的边界上接触,但在它们的内部不相交

ST_Within()和ST_Contains()测试一个几何图形是否完全包含于另一个几何图形内

ST_Distance(geometry A, geometry B)计算两个几何图形之间的最短距离

空间连接

空间连接(spatial joins)是空间数据库的主要组成部分,它们允许你使用空间关系作为连接键(join key)来连接来自不同数据表的信息


还支持汇总。JOIN和GROUP BY的组合支持通常在GIS系统中的某些分析。这个和普通的关系型数据库几乎一样。不多介绍了。


随便举个栗子,感受下。

SELECT
  n.name,
  Sum(c.popn_total) / (ST_Area(n.geom) / 1000000.0) AS popn_per_sqkm
FROM nyc_census_blocks AS c
JOIN nyc_neighborhoods AS n
ON ST_Intersects(c.geom, n.geom)
WHERE n.name = 'Upper West Side'
OR n.name = 'Upper East Side'
GROUP BY n.name, n.geom;

上面sql计算了:"'Upper West Side’和’Upper East Side’的人口密度(人/平方千米 )是多少?

三、PostGIS进阶玩法

到目前为止,都平平无奇,接下来介绍进阶玩法。


image.jpeg


1.空间索引

空间索引是PostGIS的最大价值之一。在前面的示例中,构建空间连接需要对整个表进行相互比较。这样做的代价很高:连接两个各包含10000条记录的表(每个表都没有索引)将需要进行100000000次比较;如果使用空间索引,则比较次数可能低至20000次


创建索引、删除索引就不多BB了。你们都会。

CREATE INDEX nyc_census_blocks_geom_idx
ON nyc_census_blocks
USING GIST (geom);

注意:USING GIST子句告诉PostgreSQL在构建索引时使用generic index structure(GIST-通用索引结构)。


原理

先回答一个问题,空间索引干了啥?

提高查询效率。

那空间索引是怎么做到提高查询效率的?

标准的数据库索引,是根据被索引的列的值去创建树结构的。空间索引略不同,因为数据库并不能索引几何字段的值 —— 也就是几何对象本身,我们改索引要素的范围边界框。


4bfee23e946a431dbbb3ac774de9b4e9.png

上图中,和黄色星星相交的线的数量是 1,即红色那条线。但是与黄色框相交的范围框有红色和蓝色,共 2 个。


数据库求解 “什么线与黄色星相交” 这个问题,是先用空间索引求解 “什么范围框与黄色范围框相交” 这个问题的(速度非常快),然后才是 “什么线与黄色的星星相交”。上述过程仅对于第一次测试的空间要素而言。


对于数量庞大的数据表,这种索引先行,然后局部精确计算的 “两遍法” 可以在根本上减少查询计算量。


简单来说就是,规则的几何图形的计算比不规则的图形计算简单,利用这一点做为优化的基本思想。


PostGIS中最常用的函数(ST_Contains、ST_Intersects、ST_DWithin等)都包含自动索引过滤器。但有些函数(如ST_Relate)不包括索引过滤器。


要使用索引执行边界框搜索(即纯索引查询-Index only Query-没有过滤器),需要使用"&&"运算符


查询规划器:用不用索引?

PostgreSQL查询规划器(query planner)智能地选择何时使用或不使用空间索引来计算查询。与直觉相反,执行空间索引搜索并不总是更快。


默认情况下,PostgreSQL定期收集数据统计信息,共查询规划器使用。但是,如果你在短时间内更改了表的构成,则统计数据将不会是最新的。因此,为确保统计信息与表内容匹配,明智的做法是在表中加载和删除大容量数据后手动运行ANALYZE命令。

ANALYZE nyc_census_blocks;

清理:回收空间

每当创建新索引或对表大量更新、插入或删除后,都必须执行清理(VACUUMing)。VACUUM命令要求PostgreSQL回收表页面中因记录的更新或删除而留下的任何未使用的空间。

VACUUM ANALYZE nyc_census_blocks;
相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
7月前
|
SQL Java 数据库连接
一篇文章彻底理解数据库的各种 JDBC 超时参数 1
一篇文章彻底理解数据库的各种 JDBC 超时参数
|
5月前
|
druid 网络协议 Java
再有人问你数据库连接池的原理,这篇文章甩给他!
在 Spring Boot 项目中,数据库连接池已经成为标配,然而,我曾经遇到过不少连接池异常导致业务错误的事故。很多经验丰富的工程师也可能不小心在这方面出现问题。 在这篇文章中,我们将探讨数据库连接池,深入解析其实现机制,以便更好地理解和规避潜在的风险。
|
2月前
|
存储 NoSQL 关系型数据库
一篇文章带你搞懂非关系型数据库MongoDB
一篇文章带你搞懂非关系型数据库MongoDB
65 0
|
2月前
|
存储 SQL 关系型数据库
【MySQL 数据库】6、一篇文章学习【索引知识】,提高大数据量的查询效率【文末送书】
【MySQL 数据库】6、一篇文章学习【索引知识】,提高大数据量的查询效率【文末送书】
61 0
|
7月前
|
网络协议 Java 关系型数据库
一篇文章彻底理解数据库的各种 JDBC 超时参数 2
一篇文章彻底理解数据库的各种 JDBC 超时参数
|
5月前
|
关系型数据库 数据库 PostgreSQL
Docker【应用 03】给Docker部署的PostgreSQL数据库安装PostGIS插件(安装流程及问题说明)
Docker【应用 03】给Docker部署的PostgreSQL数据库安装PostGIS插件(安装流程及问题说明)
162 0
|
7月前
|
SQL 存储 关系型数据库
MySQL的第一篇文章——了解数据库、简单的SQL语句
MySQL的第一篇文章——了解数据库、简单的SQL语句
|
7月前
|
Java 数据库连接 数据库
一篇文章学会学会c3p0数据库连接池~
一篇文章学会学会c3p0数据库连接池~
|
9月前
|
存储 数据库 Android开发
Android 使用Room操作SQLite数据库让其变得无比高效和简洁(前一篇文章的完善)
Android 使用Room操作SQLite数据库让其变得无比高效和简洁(前一篇文章的完善)
124 0
|
9月前
|
运维 监控 小程序
【运维知识进阶篇】一篇文章带你搞懂Jumperserver(保姆级教程:安装+用户与用户组+创建资产+授权资产+创建数据库+sudo提权+命令过滤+多因子认证+网域功能+审计台)(四)
【运维知识进阶篇】一篇文章带你搞懂Jumperserver(保姆级教程:安装+用户与用户组+创建资产+授权资产+创建数据库+sudo提权+命令过滤+多因子认证+网域功能+审计台)(四)
450 0