【问题标题】:recommended techniques for merging database records合并数据库记录的推荐技术
【发布时间】:2012-05-30 11:45:25
【问题描述】:

我正在开发一个基于数据输入流定期创建数据库记录的系统。偶尔会出现一些输入,证明两个独立创建的记录应该合并为一个。我正在寻找有关如何在数据库中进行合并的建议。

主表(此时只是一个设计)包含由唯一 ID(称为主 ID,由数据库分配,我的系统中的 MySQL)和一些数据字段组成的记录。还有一些其他表使用主 ID 将其记录链接到主表中的记录。

MainTable:
int   mainID
blob  data
...

OtherTable:
int   otherID
int   mainID
blob  otherData
...

现在,如果从未将每条记录共享给任何外部进程或系统,则可以直接以某种方式将一条记录中的数据字段混合到另一条记录中并删除该记录的记录。将其他表中的主 ID 字段更新为我们保留的主 ID 值也很简单(如果繁琐和/或效率低下)。

当每条记录的 ID 在系统外共享时,事情会变得复杂。在这种情况下,我认为使用这些已删除 ID 的查询完全失败应该是不合理的,尽管我可以相信否则。

我正在考虑的一个想法是引入一个包含两个关键字段的合并表:原始主 ID 和当前主 ID。其目的是将一个主 ID 别名为另一个主 ID。在创建每个主表记录时,我们向合并表添加一条记录,将新创建的主表记录的主 ID 映射到自身。如果发生合并,我们只需将合并表中记录的当前主 ID 字段更新为正在合并的主记录的原始主 ID。然后,对于基于主 ID 的每个查询,我们通过合并表映射该 ID 以找到我们真正应该使用的有效主 ID。

MergeTable:
int   mergeID
int   originalMainID
int   currentMainID

这是一个好的技术吗?映射能否在 SQL 查询中无缝完成?有没有我应该考虑的标准或更好的技术?

在对这个主题进行研究时,我发现很少有这样的例子。 This question 很接近,但合并场景与我的不同,或者在我看来是这样。我对数据库有所了解,但绝不是专家,所以我可能不知道要搜索的正确术语。

【问题讨论】:

    标签: mysql database design-patterns database-design merge


    【解决方案1】:

    我喜欢您的设计理念,但请考虑在合并表中仅存储替换记录的一种,而不是全部存储。给定以下查询,这会减少存储空间并提高速度:

    SELECT *
      FROM MainTable
      WHERE mainID = 1
    UNION ALL
    SELECT MainTable.*
      FROM MergeTable
      INNER JOIN MainTable
        ON MainTable.mainID = MergeTable.currentMainID
      WHERE MergeTable.originalMainID = 1
    LIMIT 1
    

    这个想法是,在大多数情况下,第一个查询将成功并返回一个结果,而 MySQL 将在满足 LIMIT 后中止第二个查询。如果第一个查询没有返回结果,那么它将继续进行第二个查询并在合并表上执行连接以查看它是否已合并。

    根据 MySQL,关于 LIMIT:

    一旦 MySQL 向客户端发送了所需的行数, 除非您使用 SQL_CALC_FOUND_ROWS,否则它将中止查询。

    如果合并的记录是例外,而不是规则,那么这将节省很多很多的连接。

    如果 UNION 查询太吓人,您也可以使用两个查询来执行此操作。您可以简单地检查记录是否存在,如果不存在,则检查合并表。

    【讨论】:

    • 很好的答案,马库斯。 +1。我希望得到社区的更多回应。您愿意推测一下为什么我的问题没有引起人们的兴趣吗?是太难了还是太少了(如果是,为什么?)?谢谢。
    • @RandallCook,我一直在我们的一个特定系统中执行这样的查询。我运行一个查询,如果没有得到任何结果,我将对另一个表运行另一个查询。我不认为这太不寻常了。这里的问题是命中或错过。有时一个冗长的问题会让人们望而却步,有时这只是一天中的糟糕时间。
    • @RandallCook,我忘了提到你可以随时不接受我的回答并发布赏金以获得更好的答案。
    猜你喜欢
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    • 2010-09-25
    • 2010-10-02
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    • 2016-11-07
    相关资源
    最近更新 更多