删除所有然后插入所有,或根据需要更新,删除和插入?

时间:2013-06-05 18:03:58

标签: mysql database

我有一个用于创建和更新个人信息的Web表单。在保存时,我收集大型多维JSON数组中的所有信息。更新数据库时,信息可能包含三个部分。要创建的新行,需要更新的行和需要删除的行。这些行也将跨越约5个表。

我的问题是,我该如何处理MySQL查询?我最初的想法是DELETE来自所有表格的所有信息,并一次性清除INSERT所有新信息。我想另一种方法是做3个查询:UPDATE所有具有现有ID的查询; DELETE所有标记为删除的内容和INSERT所有新创建的数据(没有现有ID的数据)。

哪种方法最好,还是有更好的方法?谢谢你的建议。我很感激。

2 个答案:

答案 0 :(得分:7)

删除所有并插入所有从不进行练习。

<强>原因

  1. 太贵了。大多数用户执行编辑。所以对于只是一些更新,你做了一次删除和一百次插入。
  2. 使用on-delete-cascade外键破坏。
  3. 即使显然没有触及也会自动增加字段。
  4. 您需要实施unit-of-work。我不知道你正在使用哪种语言,但有些语言有内置的支持。在dot-net中我们有DataSet。

    <强>基本

    1. 跟踪从数据库中提取的每条记录。秘密地为每条记录保留一个标记,以记录哪些是从db(即未触及)加载的,它具有修改(需要更新查询)并且添加了新的。对于已删除的记录,请维护一个单独的列表(可能是其ID)。如何实现这一壮举是单独讨论的问题。
    2. 当用户单击“保存”时,启动数据库事务。这不是当前讨论的严格内容,但几乎总是在类似的条件下完成。
    3. 在事务中,首先遍历已删除的items数组。为每个人发起删除查询。
    4. 然后循环修改的items数组。对于每个修改过的项目,您只需将其所有列更新为最新值即可。如果列的数量太大(> 30),那么事情会发生一些变化。
    5. 然后是新创建的项目。为每个人开一个插件。
    6. 最后提交交易。
    7. 如果您编程的语言支持try / catch块,则在try / catch中执行上述所有步骤(在开始事务之后)。在catch块中回滚了transcation。

      这种方法看起来更复杂,似乎比简单的删除/插入/所有方法引发了更多的查询,但相信我,我们一直在那里,做到了这一点,然后花了几个晚上的时间来解开所有已经完成的工作。永远不要去删除/插入方式,除非你能证明它是正确的。

      关于如何进行更改跟踪的事情,它在很大程度上取决于您使用的语言和应用程序类型。即使对于dot-net,这种方法也因桌面应用程序和Web应用程序而异。跟踪删除很容易。以便跟踪新插入。通过在该字段的任何列上捕获edit事件来应用更新标记。

      修改

      数据跨越五个表。因此,三个循环(删除/更新/插入)必须完成五次,每个表一个。首先绘制表格之间的关系。首先处理顶级表格。然后处理直接连接到顶级表的表,依此类推。如果表之间存在循环关系,则必须特别小心。

      针对Save操作的代码即将增长很长时间。 5x3 = 15个操作,每个操作都有自己的sql。预计这些操作都不可重复使用,因此将它们放在单独的方法中是徒劳的。一切都将在一个大的程序块中进行。因此虔诚地评论代码。标记表边界和操作。

答案 1 :(得分:1)

您可能不想删除任何内容。只需将过时的条目标记为“非活动”,或者将它们加时间戳为具有结束有效性。

在使用这种理念时,所有编辑实际上都是插入。没有修改(除了更改“过期”字段)和没有删除。要更新名称,请将记录标记为已过期,并同时插入带有开始有效时间戳的新记录。

在这样的数据库中,可以轻松执行审计和数据恢复。