【问题标题】:Loading a table into PostgreSQL with a foreign key produces an error使用外键将表加载到 PostgreSQL 会产生错误
【发布时间】:2013-08-31 18:11:35
【问题描述】:

我正在使用 SymmetricDS 数据库复制软件跨数据库复制表。

我已经为 PostgreSQL 创建了这个 XML 定义的表:

<table name="ServiceItem">
  <column name="ServiceItemID" type="INTEGER" required="true" primaryKey="true"/>
  <column name="ParentItemID"  type="INTEGER" />

  <foreign-key name="FK_ServiceItem_ServiceItem" foreignTable="ServiceItem">
      <reference local="ServiceItemID" foreign="ParentItemID" />
  </foreign-key>
</table>

我希望所有parentItemID 值必须存在于ServiceItemID 列中,这就是外键的意义所在。

但我在加载 SymmetricDS 时收到此错误:

[] - JdbcSqlTemplate - ERROR: there is no unique constraint matching given keys 
for referenced table "ServiceItem".  Failed to execute: ALTER TABLE "ServiceItem"
ADD CONSTRAINT "FK_ServiceItem_ServiceItem" FOREIGN KEY ("ServiceItemID") 
REFERENCES "ServiceItem" ("ParentItemID")

如果我删除外键,一切都会按预期进行。此错误消息使我感到困惑,我不确定自己做错了什么。什么意思?

【问题讨论】:

  • 对我来说,你好像把它们翻转了:ParentItemID referencing ServiceItem (ServiceItemID) 是描述层次结构的正常方式。

标签: xml postgresql foreign-keys


【解决方案1】:

我认为应该反过来:

<table name="ServiceItem">
  <column name="ServiceItemID" type="INTEGER" required="true" primaryKey="true"/>
  <column name="ParentItemID"  type="INTEGER" />

  <foreign-key name="FK_ServiceItem_ServiceItem" foreignTable="ServiceItem">
      <reference local="ParentItemID" foreign="ServiceItemID" />
  </foreign-key>
</table>

【讨论】:

    【解决方案2】:

    在 postgresql 中,如果你想创建外键,你必须遵守以下规则:

    1. FOREIGN KEY 约束必须引用 PRIMARY KEY 或 UNIQUE 约束。
    2. 两个关键字段必须具有兼容的数据类型。
    3. 必须对引用表和被引用表都具有 REFERENCES 权限。

    我碰巧违反了第一个,我指的关键不是唯一的。

    这里有一些关于如何使用外键的有用文档:http://www.postgresql.org/docs/9.1/static/ddl-constraints.html#DDL-CONSTRAINTS-FK

    所以有两种解决方案,要么强制 ParentItemID 作为唯一列,要么翻转外键,使主唯一键成为外引用。

    我翻转了 ParentItemID 和 ServiceItemID,这样唯一的就是目标,非唯一的就是被约束的列。

    <table name="ServiceItem">
      <column name="ServiceItemID" type="INTEGER" required="true" primaryKey="true"/>
      <column name="ParentItemID"  type="INTEGER" />
    
      <foreign-key name="FK_ServiceItem_ServiceItem" foreignTable="ServiceItem">
          <reference local="ParentItemID" foreign="ServiceItemID" />
      </foreign-key>
    </table>
    

    【讨论】:

      猜你喜欢
      • 2012-03-20
      • 2011-03-01
      • 2012-09-04
      • 2018-12-09
      • 1970-01-01
      • 1970-01-01
      • 2019-12-03
      • 2021-06-08
      • 1970-01-01
      相关资源
      最近更新 更多