【问题标题】:PostgreSQL array of elements that each are a foreign keyPostgreSQL 元素数组,每个元素都是外键
【发布时间】:2017-04-24 13:59:54
【问题描述】:

我正在尝试为我的应用程序创建一个数据库,我想找到最好的方法是在我的 Users 和 Items 表之间创建一对多关系。

我知道我可以创建第三个表 ReviewedItems,并让列分别为 User id 和 Item id,但我想知道是否可以在 @987654328 中创建列@,比如说reviewedItems,它是一个整数数组,其中包含Items 的外键,User 已经审查过。

如果 PostgreSQL 可以做到这一点,请告诉我!如果没有,我会沿着我的第三桌路线走。

【问题讨论】:

标签: postgresql foreign-keys foreign-collection


【解决方案1】:

不,这是不可能的。

PostgreSQL 是一个关系 DBMS,在正确规范化的数据模型上运行效率最高。数组——根据定义,它们是有序集合——不是关系数据结构,因此 SQL 标准不支持在数组元素上定义外键,PostgreSQL 也不支持。

但是,您可以构建一个完美的数据库,其中数组元素链接到其他表中的主键。但是,这些数组元素不能声明为外键,因此 DBMS 将无法保持引用完整性。

【讨论】:

  • 您可以定义一个约束触发器来检查它。但我不确定它是否在所有情况下都能可靠地工作。
  • @LuanHuynh:我不记得(技术)细节,但上次在邮件列表中讨论这个问题时,有人提到相应的约束触发器可能无法捕获所有情况 - 但这可能不会不再是真的
  • @a_horse_with_no_name 你能用这种约束的例子发布答案吗?
  • 解决方法/重新设计:有一个单独的多对多表
  • 显然,sql:2016 确实支持这种行为。不幸的是,该标准并非免费提供,但您可以在 Microsoft's documentation 和 PostgreSQL's list of unsupported standard features 中看到它的引用。
【解决方案2】:

很快就有可能做到这一点:https://commitfest.postgresql.org/17/1252/ - Mark Rofail 在这个补丁上做了一些出色的工作!

补丁将(一旦完成)允许

CREATE TABLE PKTABLEFORARRAY (
    ptest1 float8 PRIMARY KEY,
    ptest2 text
);
CREATE TABLE FKTABLEFORARRAY (
    ftest1 int[],
    FOREIGN KEY (EACH ELEMENT OF ftest1) REFERENCES PKTABLEFORARRAY,
    ftest2 int
);

但是,作者目前需要帮助来重新定位补丁(超出我自己的能力),所以任何阅读本文的人如果知道 Postgres 内部结构,请尽可能提供帮助。

【讨论】:

  • 确实很热...CREATE TABLE FKTABLEFORARRAY ( ftest1 int[], FOREIGN KEY (EACH ELEMENT OF ftest1) REFERENCES PKTABLEFORARRAY, ftest2 int )
  • 不好意思,好像没有被收录 :(
  • 这真的很有用。
  • 根据patch email thread,截至 2021 年 7 月,这似乎“仍需要一些大手术”。所以我们还有一段时间。
猜你喜欢
  • 1970-01-01
  • 2019-02-04
  • 1970-01-01
  • 2020-12-04
  • 1970-01-01
  • 1970-01-01
  • 2013-12-27
  • 2023-04-07
  • 2012-03-15
相关资源
最近更新 更多