PostgreSQL PostGIS 空间数据约束使用

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
简介: 标签PostgreSQL , PostGIS , 空间数据约束背景空间数据有一定的规范,例如SRID的规范。空间类型geometry包罗万象,除了能存储POINT,还能存储多边形,线段等。这就带来一个有意思的烦恼,当我们业务不够规范时,你可以往GEOMETRY里面存储任意SRID的数据,存储任意的空间对象。

标签

PostgreSQL , PostGIS , 空间数据约束


背景

空间数据有一定的规范,例如SRID的规范。空间类型geometry包罗万象,除了能存储POINT,还能存储多边形,线段等。

这就带来一个有意思的烦恼,当我们业务不够规范时,你可以往GEOMETRY里面存储任意SRID的数据,存储任意的空间对象。

1、SRID错乱,可能导致一些查询,索引问题。

2、本身应该存POINT的,你存了一堆线段进去也可能带来一些不必要的查询麻烦。

3、本身应该是2维数据,存入了3维时,查询可能带来麻烦。

空间数据本身的净化(约束)是一项业务需求。

结合PostgreSQL提供的check约束功能,以及PostGIS提供的一些对象描述函数,可以实现空间约束。

原文

http://spatialdbadvisor.com/postgis_tips_tricks/127/how-to-apply-spatial-constraints-to-postgis-tables

例子1

/* Note that the table now has the following structure.  
  
CREATE TABLE simon.parcel  
(  
  gid  serial NOT NULL,  
  geom geometry,  
  CONSTRAINT parcel_pkey PRIMARY KEY (gid),  
  CONSTRAINT enforce_dims_geom    CHECK (st_ndims(geom) = 2),  
  CONSTRAINT enforce_geotype_geom CHECK (geometrytype(geom) = 'POLYGON'::text OR geom IS NULL),  
  CONSTRAINT enforce_srid_geom    CHECK (st_srid(geom) = 28355)  
)  
*/  
-- 3. try and insert a POLYGON with wrong dimensionality  
INSERT INTO simon.parcel(gid,geom) VALUES (1,ST_GeomFromEWKT('POLYGON ((100 0 -9,120 0 -9,120 20 -9,100 20 -9,100 0 -9))'));  
ERROR:  NEW ROW FOR relation "parcel" violates CHECK CONSTRAINT "enforce_dims_geom"  
--  
-- 4. Try and insert POLYGON with right dimensionality  
INSERT INTO simon.parcel(gid,geom) VALUES (1,ST_PolygonFromText('POLYGON ((100 0,120 0,120 20,100 20,100 0))'));  
ERROR:  NEW ROW FOR relation "parcel" violates CHECK CONSTRAINT "enforce_srid_geom"  
--  
-- 5. Try and insert geometry with right SRID  
INSERT INTO simon.parcel(gid,geom) VALUES (1,ST_PolygonFromText('POLYGON ((100 0,120 0,120 20,100 20,100 0))',28355));  
 Query returned successfully: 1 ROWS affected, 16 ms execution TIME.  
--  
-- 6. Insert Another POLYGON  
INSERT INTO simon.parcel(gid,geom) VALUES (2,ST_PolygonFromText('POLYGON ((0 0,20 0,20 20,0 20,0 0),(10 10,10 11,11 11,11 10,10 10),(5 5,5 7,7 7,7 5,5 5))',28355));  
Query returned successfully: 1 ROWS affected, 16 ms execution TIME.  
--  
-- 7. Now try and insert a MULTIPOLYGON  
INSERT INTO simon.parcel(gid,geom) VALUES (3,ST_MultiPolygonFromText('MULTIPOLYGON (((0 0,20 0,20 20,0 20,0 0),(10 10,10 11,11 11,11 10,10 10),(5 5,5 7,7 7,7 5,5 5)),((50 5,50 7,70 7,70 5,50 5)))',28355));  
ERROR:  NEW ROW FOR relation "parcel" violates CHECK CONSTRAINT "enforce_geotype_geom"  
--  
-- How do we fix this if we want both POLYGON and MULTIPOLYGONS in our table?  
-- We could do this back at the original call to AddGeometryColumn but here we will show how to do it post-factum.  
--  
-- 8. Modify the constraint directly  
ALTER TABLE simon.parcel DROP CONSTRAINT enforce_geotype_geom;  
Query returned successfully WITH no RESULT IN 15 ms.  
--  
ALTER TABLE simon.parcel  
  ADD CONSTRAINT enforce_geotype_geom  
  CHECK ((geometrytype(geom) = ANY (ARRAY['MULTIPOLYGON'::text, 'POLYGON'::text])) OR geom IS NULL);  
Query returned successfully WITH no RESULT IN 31 ms.  
--  
-- 9. Try again  
INSERT INTO simon.parcel(gid,geom) VALUES (3,ST_MultiPolygonFromText('MULTIPOLYGON (((0 0,20 0,20 20,0 20,0 0), (10 10,10 11,11 11,11 10,10 10), (5 5,5 7,7 7,7 5,5 5)), ((50 5,50 7,70 7,70 5,50 5)))',28355));  
Query returned successfully: 1 ROWS affected, 32 ms execution TIME.  
--  
SELECT gid, ST_AsText(geom)  
  FROM simon.parcel;  

例子2

CREATE TABLE simon.parcel  
(  
  gid      serial NOT NULL,  
  geom     geometry,  
  centroid geometry,  
  CONSTRAINT parcel_pkey              PRIMARY KEY (gid),  
  CONSTRAINT enforce_dims_centroid    CHECK (st_ndims(centroid) = 2),  
  CONSTRAINT enforce_dims_geom        CHECK (st_ndims(geom) = 2),  
  CONSTRAINT enforce_geotype_centroid CHECK (geometrytype(centroid) = 'POINT'::text OR centroid IS NULL),  
  CONSTRAINT enforce_geotype_geom     CHECK ((geometrytype(geom) = ANY (ARRAY['MULTIPOLYGON'::text, 'POLYGON'::text])) OR geom IS NULL),  
  CONSTRAINT enforce_srid_centroid    CHECK (st_srid(centroid) = 28355),  
  CONSTRAINT enforce_srid_geom        CHECK (st_srid(geom) = 28355)  
)  
WITH (  
  OIDS=FALSE  
);  
-- 1 Add centroids to existing polygons  
UPDATE simon.parcel SET centroid = ST_Centroid(geom);  
Query returned successfully: 3 ROWS affected, 62 ms execution TIME.  
--  
-- 2. Now, apply centroid constraint  
ALTER TABLE simon.parcel  
  ADD CONSTRAINT centroid_in_parcel  
  CHECK (centroid IS NOT NULL AND ST_Covers(geom,centroid) = TRUE);  
ERROR:  CHECK CONSTRAINT "centroid_in_parcel" IS violated BY SOME ROW  
--  
-- 3. Find which rows fail  
SELECT gid, ST_Covers(geom,centroid)  
  FROM simon.parcel;  

排他约束

排他约束也是空间约束之一,比如要求一个表里面,不允许空间对象相交。

https://www.postgresql.org/docs/10/static/sql-createtable.html#SQL-CREATETABLE-EXCLUDE

《会议室预定系统实践(解放开发) - PostgreSQL tsrange(时间范围类型) + 排他约束》

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
7月前
|
SQL Oracle 关系型数据库
实时计算 Flink版操作报错之往GREENPLUM 6 写数据,用postgresql-42.2.9.jar 报 ON CONFLICT (uuid) DO UPDATE SET 语法有问题。怎么解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
7月前
|
关系型数据库 PostgreSQL
PostgreSQL排序字段不唯一导致分页查询结果出现重复数据
PostgreSQL排序字段不唯一导致分页查询结果出现重复数据
150 0
|
关系型数据库 MySQL Linux
TiDB实时同步数据到PostgreSQL(三) ---- 使用pgloader迁移数据
使用PostgreSQL数据迁移神器pgloader从TiDB迁移数据到PostgreSQL,同时说明如何在最新的Rocky Linux 9(CentOS 9 stream也适用)上通过源码编译安装pgloader。
|
6月前
|
消息中间件 Java 关系型数据库
实时计算 Flink版操作报错合集之从 PostgreSQL 读取数据并写入 Kafka 时,遇到 "initial slot snapshot too large" 的错误,该怎么办
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
1015 0
|
6月前
|
DataWorks 安全 关系型数据库
DataWorks产品使用合集之使用Flink CDC读取PostgreSQL数据时如何指定编码格式
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
103 0
|
2月前
|
关系型数据库 PostgreSQL Docker
PostgreSQL - 01 PostgreSQL + PostGIS + Docker 空间计算!判断坐标点是否在某个区域中 POINT MULTIPOLYGON ST_Contains
PostgreSQL - 01 PostgreSQL + PostGIS + Docker 空间计算!判断坐标点是否在某个区域中 POINT MULTIPOLYGON ST_Contains
36 0
|
4月前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
429 0
|
4月前
|
SQL 关系型数据库 HIVE
实时计算 Flink版产品使用问题之如何将PostgreSQL数据实时入库Hive并实现断点续传
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
4月前
|
开发框架 关系型数据库 数据库
在 PostgreSQL 中,解决图片二进制数据,由于bytea_output参数问题导致显示不正常的问题。
在 PostgreSQL 中,解决图片二进制数据,由于bytea_output参数问题导致显示不正常的问题。
|
6月前
|
关系型数据库 5G PostgreSQL
postgreSQL 导出数据、导入
postgreSQL 导出数据、导入
57 1

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版