【问题标题】:Recursive Foreign Key Issue递归外键问题
【发布时间】:2011-12-12 23:07:17
【问题描述】:

在我的数据库设计中,我需要一个具有递归外键关系的表,即外键引用同一个表。当我用一列尝试它时效果很好,但是当我使用两列时它会出错。下面是示例代码和产生的错误。我们将非常感谢您的帮助。

CREATE TABLE categories (
categoryID integer ,
parentID integer ,
setID integer REFERENCES categories(categoryID,parentID),
name char(255) NOT NULL,
PRIMARY KEY(categoryID,parentID)
);

错误:外键的引用列数和被引用列数不一致

当我使用时

setID integer REFERENCES categories(categoryID) and 
PRIMARY KEY(categoryID) 

那么它不会出错,但这不是我想要的。

【问题讨论】:

    标签: postgresql foreign-keys primary-key


    【解决方案1】:

    你可能想要这个:

    CREATE TABLE categories (
        categoryID integer,
        parentID integer,
        setID integer,
        name char(255) NOT NULL,
        PRIMARY KEY (categoryID, parentID),
        FOREIGN KEY (categoryID, parentID) REFERENCES categories(categoryID, parentID)
    );
    

    咨询manual about the syntax

    在评论中回答后续问题:

    CREATE TABLE categories (
        categoryID integer,
        parentID integer,
        setID integer,
        name char(255) NOT NULL,
        PRIMARY KEY (categoryID, parentID),
        UNIQUE (setID, parentID) 
        FOREIGN KEY (setID, parentID) REFERENCES categories(setID, parentID)
    );
    

    外键的目标需要某种唯一性约束。我引用manual

    引用的列必须是不可延迟的唯一列 或引用表中的主键约束。

    【讨论】:

    • 如果我希望 setID 成为外键的一部分,那是否意味着我必须将其添加为主键?
    • @Shehroz:不一定。列的组合必须是唯一的,因此它必须是主键您需要在这些列上创建唯一约束(或唯一索引)。我在答案中添加了一个示例。
    【解决方案2】:

    是的,不幸的是,您想说一个数字字段应该等同于两个数字字段。不会真的发生。

    考虑一下您对 SetID 的使用。你真的需要吗?

    相反,请确保 parentID 是 categoryID 的外键(即表示 parentID 的任何值都必须作为 parentID 中对应的现有值存在)。

    【讨论】:

      猜你喜欢
      • 2021-07-13
      • 1970-01-01
      • 1970-01-01
      • 2016-02-01
      • 2011-12-10
      • 2011-08-01
      • 2023-04-10
      • 1970-01-01
      相关资源
      最近更新 更多