微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

PostgreSQL 中的外键过滤

如何解决PostgreSQL 中的外键过滤

我目前正在 Postgresql 中寻找一种方法,我可以对给定的表限制有效外键的数量 可通过定义条件获得。

所以剧情是这样的

https://dbfiddle.uk/?rdbms=postgres_11&fiddle=4dbe279906dc881598b7e72093534ce7

A、B、C 都代表不同的实体,每个具体的条目都列在 x_entry 表中。

表 A、B、C 都代表给定条目的版本,以及它们在多长时间内有效。

我想确保 表 A 总是有 B 和 C 的外键 其中时间跨度 A 的条件 A.B.C == A.C

如图所示

enter image description here

2000-3000 范围内 Ainit 的条件被违反,因为时间范围 binit 中的 2100-3000一个指向 cinot 的外键 其中 ainit 将其外键从 cinit 更改为 cinat 违反了 A.B.C == A.C

的条件

但是我如何设置这样的条件限制,以防止外键不违反这样的特定条件。 ? 甚至有可能吗?

解决方法

我目前正在 PostgreSQL 中寻找一种方法 给定表,限制可用的有效外键数量 定义条件。

你不能那样做。

外键约束基于唯一性强制参照完整性,例如“table_a.id == table_b.a_id”。您不能过滤重叠的日期范围或类似的内容。

我可以从根本上想到一种方法来完成您的要求:触发器*

这并不太复杂,您在每个表上添加“BEFORE INSERT/DELETE/UPDATE”触发器,拒绝所有违反规则的插入/更新/删除。

如果你可以重组你的表格,它会变得更容易,你只需要两个表格:

entry
  id
  type ("a","b","c")
  name ("cinit",etc.)

PK entry(id,type)

entry_version
  id
  entry_id
  type ("a","c")
  valid_period (tsrange)

PK entry_version(id)
FK entry_version(entry_id,type) -> entry(id,type)

现在您只需要在 entry_version 上执行规则的插入/更新/删除触发器。

您可能想要研究的内容:

EXCLUDE 约束 例如,您可以确保不能将日期范围重叠的两行放在同一个表中。

表分区您可以为每个有效期或其他内容设置不同的分区。 (不过对你来说可能是死胡同)。

找出将日期范围转换为表格中的行并使用外键引用它们的某种方法。

*是的,也有 RULE:s 但那是专家级

,

我结束了对表 A 和表 B 的检查约束 两者都检查这个功能

CREATE OR REPLACE FUNCTION lookup_filtering_check(
    intermediate_table regclass,intermediate_table_column_name text,timespan tsrange,lookup_value uuid,entity_id uuid,OUT result boolean
)
    LANGUAGE plpgsql AS
$$
BEGIN
   EXECUTE 
        FORMAT(
            'SELECT ('
                'NOT EXISTS('
                    'SELECT FROM %1$I '
                    'WHERE %1$I.valid && %3$L '
                    'AND %1$I.id = %5$L '
                    'AND %1$I.%2$I<> %4$L '
                ')'
            ')',intermediate_table,intermediate_table_column_name,timespan,lookup_value,entity_id)
   USING intermediate_table,id
   INTO result;

END
$$;

在表 A 和表 B 中。

我确实看到了一些性能问题,因为它必须检查每一行。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。