【问题标题】:No unique constraint matching given keys for referenced table with multiple primary keys没有唯一约束匹配具有多个主键的引用表的给定键
【发布时间】:2015-11-13 13:30:04
【问题描述】:

我正在尝试链接这两个表,但收到错误消息:

没有唯一约束匹配被引用表“accomplices”的给定键。

注意Robberies 是另一个表。
我用它来创建 Accomplices 表(这是发生错误的时候):

CREATE TABLE info.Accomplices (
RobberID    INTEGER,
BankName    VARCHAR,
City        VARCHAR,
RobberyDate DATE,
Share       DECIMAL NOT NULL,
PRIMARY KEY(RobberID, BankName, City, RobberyDate),
FOREIGN KEY(BankName, City, RobberyDate)
   REFERENCES info.Robberies(BankName, City, RobberyDate)
);

然后创建 Robbers 表:

CREATE TABLE info.Robbers (
RobberID    INTEGER,
Nickname    VARCHAR,
Age     INTEGER,
NoYears INTEGER,
PRIMARY KEY(RobberID),
FOREIGN KEY(RobberID) REFERENCES info.Accomplices(RobberID),
CONSTRAINT AgeCheck CHECK (Age > NoYears)
);

Robbers 表中的外键是否需要匹配构成Accomplices 表中主键的所有组件?

【问题讨论】:

  • 确保您首先创建的表没有引用。如果都有引用,则需要创建一个没有引用的引用,然后添加。有时此问题与缺少表有关
  • 您好,我一直在按顺序创建表,除非它们已经创建了父表,否则不会使用外键创建表,所以我认为这不是问题
  • 太棒了!好的,接下来检查postgresql.org/docs/8.3/static/… ...您的同谋表包含所有 RobberID 的正确吗?我的意思是,如果您在 robbers 表中提供了一个并且它不存在于非法的共犯中
  • 是的,他们应该这样做,因为 RobberID 是 Accomplices 表中的主键
  • 了解,但请注意。从 Robbers 中删除您的外键约束。应该管用。这是因为 Robbers ID 可能会尝试使用不在 Accomplices 中的 ID

标签: sql postgresql database-design foreign-keys


【解决方案1】:

Robbers 表中的外键是否需要匹配构成 Accomplices 表中主键的所有组件?

不完全是。它不一定是PK。 FK 约束要求对引用表中的(组)列进行 any UNIQUEPRIMARY KEY 约束。如果它不是唯一的,则 FK 无法引用它。从理论上讲,您可以将UNIQUE 约束添加到accomplices

CREATE TABLE info.Accomplices (
   robberid    integer,
   bankname    varchar,
   city        varchar,
   robberydate date,
   share       decimal not null,
   PRIMARY KEY(robberid, bankname, city, robberydate),
   UNIQUE(robberid),
   FOREIGN KEY ...
);

.. 从设计的角度来看,这毫无意义,但会在 robbers 中显示给定 FK 约束的要求。

我怀疑您的数据库设计存在逻辑问题。

相关:

【讨论】:

  • 是的,我们讨论了一个小时。设计是错误的,但这可能是一个糟糕的问题。他明白了,哇哦
【解决方案2】:
CREATE TABLE info.Robberies ( 
BankName    VARCHAR, 
City     VARCHAR, 
RobberyDate DATE, 
Amount  DECIMAL NOT NULL, 
PRIMARY KEY(BankName, City, RobberyDate), 
FOREIGN KEY(BankName, City) REFERENCES info.Banks(BankName, City) 
);

 CREATE TABLE info.Robbers (
 RobberID    INTEGER,
 Nickname    VARCHAR,
 Age     INTEGER,
 NoYears INTEGER,
 PRIMARY KEY(RobberID),
 --FOREIGN KEY(RobberID) REFERENCES info.Accomplices(RobberID),
 CONSTRAINT AgeCheck CHECK (Age > NoYears)
  );

 CREATE TABLE info.Accomplices (
 RobberID    INTEGER,
 BankName    VARCHAR,
 City        VARCHAR,
 RobberyDate DATE,
 Share       DECIMAL NOT NULL,
 PRIMARY KEY(RobberID, BankName, City, RobberyDate),
 FOREIGN KEY(RobberID) references info.Robbers(RobberID),
 FOREIGN KEY(BankName, City, RobberyDate) REFERENCES             
 info.Robberies(BankName, City, RobberyDate)
 );

【讨论】:

  • 查看我们的聊天记录,了解我们是如何得出这个答案的
  • 好话 user22blah l8r
  • @user2256772:干得好。是的,这种设计更有意义。您的表banks 可能应该有一个代理PK(使用serial 列),只需将其用作robberiesaccomplices 中的FK。跨多个表重复(BankName, City) 效率非常低。
猜你喜欢
  • 2017-08-11
  • 1970-01-01
  • 2016-04-13
  • 2022-09-27
  • 2012-01-09
  • 2021-03-06
  • 2014-02-17
  • 1970-01-01
相关资源
最近更新 更多