PostgreSQL:表仅引用复合主键的一部分

Han*_*man 6 sql database postgresql unique-constraint composite-primary-key

我正在使用 Postgres 9.6.2 创建电影和电视节目流媒体服务数据库(用于学校项目)。我遇到以下错误:

没有与引用表“watchedepisodes”的给定键匹配的唯一约束

只要用户观看了至少一集(显示在 WatchedEpisodes 表中),下面的电视收视率表就会接受电视节目并允许用户对其进行评分。由于 WatchedEpisodes 具有用户 id、电视节目 id、季节和剧集的复合主键,因此它不允许我仅从该表中引用仅包含 uid 和 tid 的复合键。

CREATE TABLE WatchedEpisodes (
  uid int unique references Users(uid),
  tid int,
  season int,
  episode int,
  FOREIGN KEY(tid, season, episode) REFERENCES Episodes(tid, season, episode),
  PRIMARY KEY (uid, tid, season, episode)
);

CREATE TABLE TVRatings (
  uid int,
  tid int,
  rating int check (rating > 0 and rating < 6),
  FOREIGN KEY(uid, tid) REFERENCES WatchedEpisodes(uid,tid),
  PRIMARY KEY(uid, tid)
);
Run Code Online (Sandbox Code Playgroud)

想知道是否有办法只引用该组合键的一部分。这些只是我的两个表格,因此如果需要更多信息,我可以添加更多信息。

Eva*_*oll 1

这实际上在规范中,但尚未实现。它被称为MATCH PARTIAL

CREATE TABLE foo (
  a int,
  b int,
  c int,
  PRIMARY KEY (a,b,c)
);
CREATE TABLE bar (
  a int,
  b int,
  FOREIGN KEY (a,b) REFERENCES foo (a,b) MATCH PARTIAL
);
Run Code Online (Sandbox Code Playgroud)

您可以在文档中阅读相关内容

插入到引用列中的值将使用给定的匹配类型与引用表和引用列的值进行匹配。共有三种匹配类型:MATCH FULL、MATCH PARTIAL 和 MATCH SIMPLE(默认)。MATCH FULL 不允许多列外键的一列为空,除非所有外键列都为空;如果它们全部为空,则该行不需要在引用的表中具有匹配项。MATCH SIMPLE 允许任何外键列为空;如果其中任何一个为空,则该行不需要在引用的表中具有匹配项。MATCH PARTIAL 尚未实现。(当然,可以将 NOT NULL 约束应用于引用列以防止出现这些情况。)

我认为目前它被视为一个反功能,所以它不太可能很快落地。

作为解决方法,您可以创建另一个表,其中包含(a,b)

CREATE TABLE baz (
  a int,
  b int,
  PRIMARY KEY (a,b)
);
Run Code Online (Sandbox Code Playgroud)

从这里您可以将两个表链接到它......

CREATE TABLE foo (
  a int,
  b int,
  c int,
  PRIMARY KEY (a,b,c),
  FOREIGN KEY (a,b) REFERENCES baz
);
CREATE TABLE bar (
  a int,
  b int,
  FOREIGN KEY (a,b) REFERENCES baz
);
Run Code Online (Sandbox Code Playgroud)