1

假设我有Itemand Tag,其中每个只有一个idandname列,以及一个Item_Tag_Map具有复合Item.id, Tag.id主键的表。

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

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

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

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

获取这些项目的所有 tag_mapping

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

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

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

我敢肯定人们以前曾多次遇到过这个问题,我有兴趣了解您是如何处理它的。

4

1 回答 1

2

我的答案取决于一些事情,所以我会尝试陈述我的假设。

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

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

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

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

于 2013-01-27T16:57:33.610 回答