PostgreSQL EXCLUDE USING 错误:数据类型整数没有默认操作符类

Ian*_*thy 47 postgresql constraint installation exclusion-constraint gist-index

在 PostgreSQL 9.2.3 我试图创建这个简化的表:

CREATE TABLE test (
    user_id INTEGER,
    startend TSTZRANGE,
    EXCLUDE USING gist (user_id WITH =, startend WITH &&)
);
Run Code Online (Sandbox Code Playgroud)

但我收到此错误:

ERROR:  data type integer 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.
Run Code Online (Sandbox Code Playgroud)

PostgreSQL的文档使用这个例子不为我工作:

CREATE TABLE room_reservation (
    room text,
    during tsrange,
    EXCLUDE USING gist (room WITH =, during WITH &&)
);
Run Code Online (Sandbox Code Playgroud)

同样的错误信息。

而这个对我来说也不起作用:

CREATE TABLE zoo (
    cage   INTEGER,
    animal TEXT,
    EXCLUDE USING gist (cage WITH =, animal WITH <>)
);
Run Code Online (Sandbox Code Playgroud)

同样的错误信息。

我可以毫无问题地创建它:

CREATE TABLE test (
    user_id INTEGER,
    startend TSTZRANGE,
    EXCLUDE USING gist (startend WITH &&)
);
Run Code Online (Sandbox Code Playgroud)

和这个:

CREATE TABLE test (
    user_id INTEGER,
    startend TSTZRANGE,
    EXCLUDE USING btree (user_id WITH =)
);
Run Code Online (Sandbox Code Playgroud)

我花了相当多的时间来寻找有关弄清楚如何使这项工作起作用的提示,或者弄清楚为什么它不起作用。有任何想法吗?

Erw*_*ter 37

在您链接到的位置安装btree_gist手册提到的附加模块:

您可以使用btree_gist扩展来定义纯标量数据类型的排除约束,然后可以将其与范围排除结合以获得最大的灵活性。例如,btree_gist安装后,仅当会议室编号相等时,以下约束才会拒绝重叠范围:

在现代 PostgreSQL 中,您只需要运行(每个数据库一次):

CREATE EXTENSION btree_gist;
Run Code Online (Sandbox Code Playgroud)

您需要先在您的操作系统中安装“contrib”包。详细信息取决于您的操作系统和使用的软件存储库。对于 Debian 系列,它通常是postgresql-contrib-9.2(对于 Postgres 9.2)。或者仅postgresql-contrib适用于 Red Hat 家族。考虑这个关于 SO 的相关答案:

  • @DenverTimothy:我想我也可以提供帮助。您可能需要先在您的操作系统中安装 contrib 包 `postgresql-contrib-9.2`。取决于您的操作系统。[在 SO 上考虑这个相关答案。](http://stackoverflow.com/questions/12100638/error-when-creating-unaccent-extension-on-postgresql/12101055#12101055) (3认同)

小智 5

如果有人不能或不想使用这个:

CREATE EXTENSION btree_gist;
Run Code Online (Sandbox Code Playgroud)

就像我的情况一样,因为 Django 1.11 ORM 不支持这个索引,而且我不想在 Django 之外编写 SQL。我使用了类似的东西:

EXCLUDE USING gist (
    int4range(userid, userid, '[]') WITH =,
    startend WITH && 
)
Run Code Online (Sandbox Code Playgroud)

'[]' 用于确保两个边界都包含在内。使用 Postgres 9.6 和 10.5 进行测试。