【问题标题】:How to make sure redundant data is deleted in a many-to-many relationship如何确保在多对多关系中删除冗余数据
【发布时间】:2009-01-11 01:55:48
【问题描述】:

我正在尝试确保在没有更多使用级联删除的引用时自动删除某些数据。我会用一个基于 Stack Overflow 的 fake 数据库来解释。

我有一个Post 表。每个帖子都有零到多个标签。

所以它应该是这样的:

发布 PostTags 标签

例如。

帖子 1 有标签 'A'、'B'、'C' 帖子 2 有标签“C”、“D”。

现在,我正在做的是,当我删除帖子 2 的所有标签(例如DELETE FROM PostTags WHERE PostId = 2)时,我希望标签“D”也被删除,因为如果没有其他人引用它。我认为级联删除会处理这个问题,但当然只有当你从Tag->PostTagsPost->PostTags 级联下来。

我不知道如何处理。

恐怕人们会建议使用触发器 :((系统的额外复杂性)。

想法?

注意:数据库是 MS Sql2008。

【问题讨论】:

    标签: sql-server sql-server-2008 many-to-many


    【解决方案1】:

    很遗憾,您将无法在此处使用级联。当您具有多对多关系时,级联不起作用,因为您不会有一个引用子节点的单一父节点(在这种情况下,您有多个可以引用标签表的 PostTags 条目)。

    触发器是一种方法,但我不推荐它。相反,我建议在您的数据层中,删除 PostTags 表中的条目后,删除不再引用的标签。如果您有一个删除条目的存储过程,您可能需要考虑在那里执行此操作(这样做也相对简单)。

    【讨论】:

    • 类似以下内容: DELETE Tags WHERE TagId NOT IN (SELECT TagId FROM PostTags) ? (也不确定这是否非常高效)
    • 这基本上就是你会做的。我会将其封装在一个存储过程中,这样您就可以节省多次访问服务器(如果您的架构允许的话)。
    【解决方案2】:

    我认为您必须在您的 Posts 表上使用 on delete 触发器,该触发器检查被删除帖子的标签,如果它们未被引用(在 PostTags 表中)则将其删除。

    在删除您的帖子之前,请保存此记录集:

    SELECT tagID, count(*) from PostsTags WHERE postId = 2 group by tagID;
    

    然后,在你删除它之后,循环遍历这个记录,如果 count(*) = 1,则删除标签。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多