在 PostGIS“栅格”类型列上创建唯一约束

Zia*_*Zia 2 postgresql constraint postgis raster

我正在使用以下命令向 PostGIS-2.1.3 (PostgreSQL-9.1.14) 中的光栅图像之一添加约束。

ALTER TABLE schema1.table1 ADD CONSTRAINT enforce_scalex_rast unique (rast);
Run Code Online (Sandbox Code Playgroud)

但得到以下错误:

ERROR:  data type raster has no default operator class for access method "btree"
HINT:  You must specify an operator class for the index or define a default operator class for the data type.
Run Code Online (Sandbox Code Playgroud)

请有人帮我解决这个错误。我对运算符类没有基本的了解。谢谢。

齐亚。

Cra*_*ger 5

唯一约束创建唯一索引来实现约束。PostgreSQL 中唯一支持唯一索引的索引类型是默认的 b-tree 索引类型;您不能创建唯一的 GIN 或 GiST 索引,例如:

regress=> create unique index indexname on test USING GiST(id) ;
ERROR:  access method "gist" does not support unique indexes
Run Code Online (Sandbox Code Playgroud)

数据类型必须专门支持不同种类的索引,而这种数据类型似乎不支持 b-tree 索引。所以你不能对这种类型进行唯一约束。


细节:

PostgreSQL 使用了几种索引类型。类型必须为它们支持的每个索引类型提供一个操作符类。为了您的目的,实际上有两个感兴趣的群体:

  • b-tree - 默认值,当你不说索引类型时你会得到什么。支持相等、小于和大于操作。支持创建唯一索引。

  • GiST 和 GIN - 流行的灵活索引类型,被 PostGIS、全文搜索等大量使用。支持创建唯一索引。支持比b-tree更多种类的比较。

大多数数据类型通过提供 b-tree 运算符类来支持 b-tree 索引,这是默认设置。

某些数据类型,尤其是 GIS 中使用的数据类型,不提供 b-tree opclass,要么是因为没有人想要,要么是因为它没有多大意义。

这种类型似乎是其中之一。没有人为该raster类型添加 b-tree 支持,因此您无法在其上创建 b-tree 索引。由于唯一索引仅支持 b 树,并且唯一约束会创建唯一索引来实现该约束,这意味着您不能对raster类型进行唯一约束。

您可能会发现较新的 PostgreSQL/PostGIS 版本具有所需的 opclass。或者可能不会。我没查过。无论哪种方式,您在 9.1 中都不走运。


让我们尝试为该类型的b-tree 支持创建一个运算符类raster。该运营商类和家庭的文档显示了B树索引策略策略号,显示出我们需要支持=<<=>>=raster。我们有吗?

regress=# select oprname from pg_operator where oprname IN ('=', '<=', '<', '>', '>=') and oprleft = 'raster'::regtype and oprright = 'raster'::regtype;
 oprname 
---------
 =
(1 row)
Run Code Online (Sandbox Code Playgroud)

不。因此,raster如果没有首先为其实现排序运算符并确保这些运算符遵循有关传递性、可交换性等所需的规则,我们就无法创建 b 树运算符类。

这并不过分令人惊讶,因为目前还不清楚究竟是什么raster < raster意思。但是,这确实意味着您无法轻松地为raster.


另一种可能性是对输入进行散列md5或类似的散列,然后在散列上创建唯一索引。这解决了索引运算符类型问题和最大 b 树条目大小的问题。

在散列值上创建索引在其他地方有很好的记录。