【问题标题】:Many to many relations and history tables多对多关系和历史表
【发布时间】:2013-01-10 17:40:34
【问题描述】:

假设我有ItemTag,每个都有一个idname 列,还有一个Item_Tag_Map 表有一个复合Item.id, Tag.id 主键。

如果我想为ItemTag 实现一个历史表,这似乎相对简单——我可以添加第三列revision 和一个触发器以复制到ItemHistoryTagHistory 表中id, revision 作为主键,operation(“INSERT”、“UPDATE”等)。由于我可能想“删除”项目,我可以采用以下两种方式之一:

  • ItemTag 上为is_active 添加另一列,并且实际上永远不要删除任何行
  • 删除行,但在历史表中将删除记录为delete 操作,并在ItemTag 插入时,确保从ItemHistory 或@ 中获取最新的revision 编号987654342@ table 与该项目,并将其设置为那个

第二个选项在我的嘴里留下了不好的味道,所以我可以使用第一个。毕竟,当我可以修改或更改其活动状态时,为什么我真的需要删除它?

现在,我在Item_Tag_Map 表上的历史表中遇到了同样的问题,但这一次,这两个选项似乎都没有那么吸引人。如果我选择为Item_Tag_Map 添加is_active,则查找标签是否映射到项目的逻辑从:

获取这些项目的所有 tag_mapping

获取这些项目的所有 tag_mapping WHERE is_active

映射的存在意味着映射存在的隐含想法消失了。未映射的 item-tags 集合不仅包括表中不存在的所有标签,还包括 is_active 为 false 的标签。

另一方面,如果我选择第二个选项,它仍然相当难看。

我相信人们之前已经多次遇到过这个问题,我有兴趣了解您是如何处理它的。

【问题讨论】:

    标签: database database-design model many-to-many relational-database


    【解决方案1】:

    我的答案取决于几件事,所以我会尝试陈述我的假设。

    无论我认为 Item 和 Tag 上的 is_active 是什么都可以。如果这两个实体上的记录大小增长非常快,则考虑运行夜间作业以将非活动记录移动到表的存档版本。这可用于以后报告或审计事情。如果需要,您还可以编写一个脚本来恢复记录,但这样做的目的是您的实时表速度很快且不会删除数据。

    如果您允许用户添加/更新/删除映射,那么我会认为该表与 Item 和 Tag 相同。添加标志并在您的查询中使用它。它对我来说并不难看 - 我以前见过。

    如果映射表不受用户控制,那么我猜你会在 Item 或 Tag 上使用 is_active 标志来确定是否可以运行查询。

    只要知道一旦你添加了那个标志,人们就会忘记使用它。我知道我已经做过很多次了,(“为什么我得到了这么多记录,我错过了什么?哦,是的,is_active...)

    【讨论】:

      猜你喜欢
      • 2021-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-12
      • 2014-02-02
      • 2020-09-15
      • 1970-01-01
      相关资源
      最近更新 更多