如果主键有多于一列,如何引用 SQL table?

How to reference a SQL table if primary key has more than one column?

我正在学习 postgresql 并且我创建了 2 个 table:goalsresults。每个 table 都有一个由 3 列组成的主键:

我这样做是为了让每一行不仅在其 id 上而且在 goalresult 是唯一的还是有效。这是我的 sql 代码:

CREATE TABLE goals (
  goal_id INT,
  goal_title VARCHAR(80),
  goal_description VARCHAR(300),
  goal_valid_from_date TIMESTAMP,
  goal_valid_until_date TIMESTAMP,
  goal_deleted_flag BOOLEAN,
  PRIMARY KEY (goal_id, goal_valid_from_date, goal_valid_until_date)
);

CREATE TABLE results (
  result_id INT,
  goal_id INT,
  result_description VARCHAR(300),
  result_target FLOAT,
  result_timestamp DATE,
  result_valid_from_date TIMESTAMP,
  result_valid_until_date TIMESTAMP,
  result_deleted_flag BOOLEAN,
  PRIMARY KEY (result_id, result_valid_from_date, result_valid_until_date)
);

我现在的目标是创建一个 外键 以便我能够仅基于 goal_id 列连接 2 table 并且不是 valid_from/until_date 列,否则它们永远不会匹配。

我尝试使用以下代码行来实现此目的:

ALTER TABLE results
ADD FOREIGN KEY(goal_id)
REFERENCES goals(goal_id) on delete set null;

但是我得到一个错误:

SQL Error [42830]: ERROR: there is no unique constraint matching given keys for referenced table "goal"

你能提出一个聪明而优雅的方法来实现我的目标吗?

... so that I am able to connect the 2 tables based on the goal_id column only ...

正如错误消息所暗示的那样,您需要添加一个匹配的 UNIQUE CONSTRAINT:

ALTER TABLE goals
ADD CONSTRAINT u_goals_goal_id
UNIQUE (goal_id)

但是,如果您当前的设计是有意而非偶然的,则此约束比您的实际主键更具限制性,这可能不是您想要的(请参阅@MikeOrganek 和@ErwinBrandstetter 的评论)。

如果这是您想要的,那么您应该考虑将其作为您的主键。

对于你的排除问题(没有两个目标可能有重叠的时间段)看看the example in the manual,它从字面上描述了你的情况。

the documentation

中很清楚
FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]

你需要把 column_name

的列表