假设我有Item
和Tag
,每个都只有id
和name
列,而Item_Tag_Map
表有一个复合{ {1}}主键。
如果我想为Item.id, Tag.id
和Item
实现历史记录表,这似乎相对简单 - 我可以添加第三列Tag
和触发器复制到{{1带有revision
的{{1}}表作为主键和ItemHistory
(“INSERT”,“UPDATE”等)。由于我可能想要“删除”项目,我可以采用以下两种方式之一:
TagHistory
或id, revision
上为operation
添加另一列,并且实际上不删除任何行Item
操作,并在Tag
或is_active
插页上,确保获取最新的delete
包含该项目的Item
或Tag
表中的数字,并将其设置为第二种选择在我的嘴里留下了不好的味道,所以我使用第一种方法很好。毕竟,当我可以修改项目或更改其活动状态时,为什么我真的需要 删除项目?
现在,我在revision
表上的历史表遇到了同样的问题,但这一次,这两个选项似乎都不具吸引力。如果我选择为ItemHistory
添加TagHistory
,则找出标记是否映射到项目的逻辑会改变:
为这些项目获取所有tag_mapping
到
为这些项目获取所有tag_mapping WHERE is_active
存在映射意味着映射存在的隐含思想消失了。未映射的item-tags集不仅包括表中不存在的所有项,还包括Item_Tag_Map
为false的那些。
另一方面,如果我选择第二个选项,它仍然相当难看。
我相信人们之前已经多次遇到过这个问题,我有兴趣了解你是如何处理它的。
答案 0 :(得分:2)
我的回答取决于一些事情,所以我会试着陈述我的假设。
无论我认为is_active对Item和Tag都没问题。如果记录大小在这两个实体上增长得非常快,那么考虑运行夜间作业以将非活动记录移动到表的存档版本。这可以用于以后报告或审核事物。如果需要,您还可以编写脚本来恢复记录,但我们的想法是您的实时表快速且没有删除数据。
如果您允许用户添加/更新/删除映射,那么我会认为该表与Item和Tag相同。添加标志并在查询中使用它。这对我来说似乎并不难看 - 我以前见过它。
如果映射表不在用户控制之下,那么我猜你会在Item或Tag上使用is_active标志来确定是否可以运行查询。
只要知道一旦添加该标志,人们就会忘记使用它。我知道我已经做过很多次了,(“为什么我会得到这么多记录,我错过了什么?哦,是啊,is_active ......)