【问题标题】:Best way to merge and unmerge objects without losing data在不丢失数据的情况下合并和取消合并对象的最佳方法
【发布时间】:2011-12-20 16:38:27
【问题描述】:

假设我有两个表(我使用的是 Django,但这个问题主要与语言无关):

Organization(models.Model):
    name = models.CharField(max_length=100)

Event(models.Model):
    organization = models.ForeignKey(Organization)
    name = models.CharField(max_length=100)  

允许用户创建活动和组织。两个不同的用户有可能创建应该类似于同一个现实世界组织的组织对象。当有人注意到这个问题时,他们应该能够合并这两个对象,这样就只有一个组织了。

我的问题是:如何合并这两个组织,以确保如果用户错误地合并它们,我可以“取消合并”它们?因此,删除一个组织对象并将所有事件指向另一个的简单解决方案不是一种选择。我在这里寻找有关最佳实践的高级指南。

一些可能的解决方案:

  • 添加另一个表,将已“合并”的组织连接在一起并以这种方式跟踪合并
  • 在组织上添加外键字段以指向与其合并的组织
  • 保留合并前所有原始对象的副本,使用类似django-reversion

【问题讨论】:

  • 不属于你的世界,但 OWL 和 FOAF 本体正是为此而设计的……它们基于规则定义,两个对象之间的等价声明随后可能被撤销或争议。在数据库世界中,这相当于在两个组织之间添加另一个链接表 - 很容易填充,但是您很难查询到正确的问题。
  • 看起来 OWL 和 FOAF 可能不适用于我正在做的事情,但感谢您提出这个问题!学习新事物很有趣。
  • 至于您对在不同组织之间添加链接的评论,我同意这绝对是一种现实的方法,尽管在实践中有点烦人,因为查询会更复杂。
  • 是的 - 我想我会为你扔掉那个通配符,但如此完全地切换齿轮并不实际。这些查询可能会有点烦人 - 这些问题会很棘手,您需要将它们融入到您所问的几乎所有问题中......
  • 同意。我越想如何处理对链接模型的查询,我发现的问题就越多。我倾向于一种更接近 django-reversion 的解决方案,我只需跟踪所有以前的数据,然后根据这些数据找出如何取消合并。

标签: python database django django-models schema


【解决方案1】:

我的建议是类似 diff 的界面。对于每个字段,您提供来自被合并对象的所有可能值。合并它们的人为每个字段选择适当的值。您可能只想显示在此视图中检测到冲突的字段。

在所有冲突的字段都为它们选择了一个“好”的值之后。您创建一个新对象,将旧版本的关系分配给该对象,然后删除旧版本。

如果您正在寻找某种自动方法,我认为您很难找到一种方法,即使您找到了,这也不是一个好主意。任何时候你合并任何你需要一个人在中间的东西。即使是同步联系人等的应用也不会尝试自行处理冲突。

【讨论】:

  • hmm,我同意做一个好的合并工具很重要,但是这个解决方案并不能解决出现问题时“取消合并”数据的问题。我们会因为删除旧版本而丢失信息,我的应用必须能够在必要时恢复到原始状态。
【解决方案2】:

就个人而言,我会选择使用django-reversion 之类的解决方案。但是,如果您想创建更强大且更少依赖第三方逻辑的东西,请将 merged_into 字段添加到 Organization 并将 merged_from 字段添加到 Event:

Organization(models.Model):
    name = models.CharField(max_length=100)
    merged_into = models.ForeignKey('self', null=True, blank=True)

Event(models.Model):
    organization = models.ForeignKey(Organization)
    name = models.CharField(max_length=100)  
    merged_from = models.ForeignKey(Organization null=True, blank=True)

在合并时,您也可以选择更新事件。从现在开始,请务必将“merged_into”组织的所有引用重定向到新组织中。

如果要允许多次合并(例如:A+B 合并为 C,A+C 合并为 D,E+F 合并为 G,D+G 合并为 H),可以每次创建一个新的组织实例并合并两个“父母”都进入其中,复制事件而不是更新它们。这使原始事件保持不变,等待回滚。这也允许一步将两个以上的组织合并为一个新的组织。

【讨论】:

  • 我倾向于推出与此类似的自己的东西,所以我很高兴阅读您的推荐。谢谢!
【解决方案3】:

我认为有一个关键黑客。

组织将具有通常的 id 字段和另一个“别名”字段。 “别名”字段将是逗号分隔的 ID。在该字段中,您将跟踪在现实世界中可能指向相同的组织。假设有一个名为 organization_1, organization_2 的 2 组织,id 为 1, 2。

organization_1           organization_2
_id = 1                  _id = 2
aliases = '1, 2'         aliases = '2, 1'

如果您想查询仅属于组织_1 的事件,您可以这样做。如果要查询组织_1、组织_2的所有事件,请检查别名字段是否包含键。也许分隔符不应该只是“,”,它还应该包围整个别名字段。像',1,2,'这样的东西。这样我们就可以确定是否包含',id,'

【讨论】:

    猜你喜欢
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-26
    • 1970-01-01
    • 1970-01-01
    • 2016-07-06
    • 1970-01-01
    相关资源
    最近更新 更多