约束用于确保数据库中的数据反映数据模型的假设。
- 外键是否与相应键匹配? (
REFERENCES
) - 是否填写了必填列? (
NOT NULL
) - 唯一值列实际上是唯一的吗? (
UNIQUE
) - 是否通过其他数据质量规则? (
CHECK
)
为什么要在数据库中而不是在应用程序层实施数据质量规则? 因为如果您在应用程序层限定所有数据,则每当添加“另一个应用程序”写入数据库时,都必须复制“所有逻辑”。
如果您有幸编写了一个成功运行了超过两年的系统,那么多个写入应用程序迅速普及的可能性将达到100%。 在数据库中强制执行核心数据质量规则是一种以可靠的数据完整性假设为基础的系统的好方法。
空间约束如何实现呢? 得益于PostgreSQL运行时扩展的神奇之处,geometry
类型只是另一种类型,并且所有约束检查机制对geometry
一样适用于任何其他类型。
这是空间数据库用户喜欢对几何数据执行的简单和复杂约束的一些示例。
检查约束
PostgreSQL列级别的约束允许我们将测试应用于数据,但只能在如下粒度级别上进行:检查只能对输入值进行操作,因此我们只能使用相对简单的测试来检查单个几何的属性。
空间函数比如:
ST_Area, ST_Union, ST_Intersection 所有这些都依赖于“有效几何图形”输入以产生正确的答案,因此许多用户只希望在表格中允许有效几何图形。
这是一张包裹表的检查例子:检查约束 通过 ST_IsValid 强制几何对象有效性检查.
CREATE TABLE parcels (
pk bigint PRIMARY KEY,
geom geometry(Polygon, 3005)
NOT NULL CHECK (ST_IsValid(geom)),
pid text NOT NULL UNIQUE
)
“无效”多边形是具有以下内容的多边形:
- 自相交的环;
- 与外圈共享边界的内圈;
- 外圈外的内圈。
这是一些无效的多边形。
使用我们的检查约束后,有效多边形的插入成功。
INSERT INTO parcels (pk, pid, geom)
VALUES (1, '12345',
'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))'
);
无效多边形的插入失败。
INSERT INTO parcels (pk, pid, geom)
VALUES (2, '23456',
'POLYGON((
160 170, 160 280, 213
315, 310 280, 300 140,
210 220,280 190, 160 170))' );
NOTICE: Self-intersection at or near
point 249.47368421052633 184.91228070175438
ERROR: new row for relation "parcels"
violates check constraint "parcels_geom_check"
DETAIL: Failing row contains (2, 0103000020BD0B00
000100000008000000000000000000644000000000004065...,
23456).
与非空间约束一样,空间约束也可以用于执行常识性业务规则。 例如:
CHECK ST_Area(geom)> 10
强制最小多边形面积。 被调查的包裹可能具有最小允许的大小。CHECK ST_Length(geom)> 1
强制最小行长。 精度为1米的路网的任何路段均不得短于1米。检查ST_IsSimple(geom)
以确保线条不会自相交。节点网络不应具有自相交元素。
检查约束看起来简单易懂,但空间数据要求进行更强大的质量约束,其中涉及查看表中的几何图形之间以及表之间的结构关系。
为此,我们将需要表级约束和触发器,我们将在本系列的下一部分中进行讨论。