1

我正在使用 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")

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

4

2 回答 2

3

我认为应该反过来:

<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>
于 2013-08-31T18:22:07.400 回答
1

在 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>
于 2013-08-31T18:22:16.007 回答