【问题标题】:Bad practice to create a foreign key constraint on primary key of the same table?在同一张表的主键上创建外键约束的坏习惯?
【发布时间】:2012-12-17 02:19:37
【问题描述】:

我正在尝试在我的数据库中创建一个评论表,并将子 cmets 也存储在同一个表中。我会在名为“ParentId”的列上放置一个外键约束,该列将链接到 CommentId 列,该列是同一个表的主键。如果它是 Parent 评论,那么我会将 ParentId 设为 null。这是不好的做法吗?如果是这样,有什么更好的方法来解决这个问题。

【问题讨论】:

  • 这不是坏习惯。请记住,许多数据库不能进行递归查询,和/或使用单个create table 创建这样的表结构。您可能必须创建它,然后对其进行更改以添加 FK。
  • @SteveWellens 为什么会这样? ParentID 为 null 的行是层次结构中的根节点。输入 ParentID 后,FK 会确保它连接到另一行。
  • 嗯...不确定那个史蒂夫。 FK 约束还有其他用途,例如阻止您插入其他表中不存在的 id。在我的书中,一个可以为空的 Fk 就可以了。
  • @SteveWellens 看看这个SQL Fiddle
  • @MikaelEriksson - 哇,它确实可以防止伪造的父键,但它允许空值。感谢您分享这些信息。

标签: c# asp.net sql entity-framework


【解决方案1】:

这很好。您需要考虑的一件事是如果删除带有孩子的评论该怎么办。 FK 约束将阻止删除,级联删除的常见解决方案在这里似乎不合适,NULL 也不适用于父引用。因此,您可能必须保留已删除的评论,并清除内容或以其他方式将其标记为已删除。

【讨论】:

    【解决方案2】:

    这不是坏习惯,但正如评论者指出的那样,您以后可能会遇到问题。

    由于 cmets-on-cmets 相当于一棵逻辑树,因此可能值得一试 Celko 的工作:

    http://www.ibase.ru/devinfo/DBMSTrees/sqltrees.html

    非常方便!

    【讨论】:

      【解决方案3】:

      http://msdn.microsoft.com/en-us/library/ms124432(v=sql.100).aspx

      对于 SQL Server,这不是一个坏习惯,请参阅上面的 Employee 表定义链接并参考 ManagerID 列,Microsoft 已在 SQL Server 提供的示例数据库中使用此方案。

      需要注意的主要是父记录不能物理删除,您可能需要使用标志使用软删除。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-02
        • 1970-01-01
        • 2020-08-07
        • 1970-01-01
        • 2018-05-01
        • 2023-04-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多