最初的目标:创建一个约束,以确保特定Postgres表中只存在不重叠的子网。
通过仔细阅读文档,我可以做到以下几点:
create table subnets (
subnet cidr,
exclude (subnet with &&)
);但这不管用。它产生了无法理解的消息:
ERROR: operator &&(inet,inet) is not a member of operator family "network_ops"
DETAIL: The exclusion operator must be related to the index operator class for the constraint.尽管阅读了关于操作符类、索引和索引类型的doc部分,但我仍然有一种感觉,那就是我遗漏了一个被视为理所当然的解释部分。我仍然不知道什么是运算符类,真的,也不知道什么是运算符家族。
我确实找到了张贴在邮寄名单上,这是一个导致以下工作代码的代码片段:
create table subnets (
subnet cidr,
exclude using gist (subnet inet_ops with &&)
);但我不能真正理解“使用gist”是为了什么,也不明白“inet_ops”是什么。
我知道“使用gist”与索引的类型有关。我知道索引是为“唯一”约束自动创建的,我猜索引也可能是为“排除”约束自动创建的。关于“运算器类”的唯一文档全部涉及索引,而不是约束。
如果需要排除约束,那么如何确定应该指定哪些操作符类和访问方法才能使约束工作?
请注意,即使手头有工作代码,我也无法找到为什么它是"gist“而不是其他东西,以及为什么它是"inet_ops”而不是"network_ops“或什么都没有。\doS和操作符类文档中列出的查询都没有启发性。
我所犯的另一个错误也没有启发性:
vagrant=# create table subnets (
subnet cidr,
exclude using gist (subnet with &&)
);
ERROR: data type cidr has no default operator class for access method "gist"
HINT: You must specify an operator class for the index or define a default operator class for the data type.(这一问题所依据的前提是,我不应使用抄袭和粘贴咒语;对文件进行彻底审查,加上仔细阅读错误信息,应能使我解决问题。对于Postgres来说,这一点以前一直是正确的。
发布于 2018-05-04 04:14:49
PostgreSQL索引由两个部分组成,分别来自于索引接口扩展上的文档
\dA+可以看到这一点)。GIST是索引方法。关于为什么需要GIST或SP,onEXCLUSION CONSTRAINTSsee这篇文章。您需要的操作符类是inet_ops。您遇到的问题是提供了cidr和inet two GIST运算符类,而错误的是默认的,
gist_cidr_ops是默认的。它是“额外提供的模块”的一部分,大多数发行版都将其打包为-contrib。它由btree_gist扩展 (来源)提供。inet_ops是核心,而不是默认的。你怎么会知道这个?你可能不会。就访问类型而言,祝你好运。虽然文档本身与PostgreSQL一起分发,但在这里非常缺乏,尽管它们确实触及到了这一点,
由于历史原因,
inet_ops运算符类不是inet和cidr类型的默认类。要使用它,请在CREATE INDEX中提到类名,例如使用GIST (my_inet_column Inet_ops)在my_table上创建索引;
您所能做的最好是向btree_gist提交一个文档修补程序,其中可能还应该记录<#>以及。
https://dba.stackexchange.com/questions/205773
复制相似问题