1

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

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

这些方法中哪一种最好,或者有更好的方法吗?感谢您的任何建议。我很感激。

4

2 回答 2

9

永远不要练习删除所有并插入所有。

原因

  1. 太费钱了。主要是用户执行编辑。因此,对于只是几次更新,您进行了一次删除和一百次插入。
  2. 对删除级联外键造成严重破坏。
  3. 即使它们显然没有被触摸,也会扰乱自动增量字段。

你需要实现unit-of-work。我不知道您正在使用哪种语言,但有些语言对此具有内置支持。在 dot-net 中,我们有数据集。

基础知识

  1. 跟踪您从数据库中获取的每条记录。秘密地为每条记录维护一个标志,以记录哪些是从数据库加载的(即未触及),哪些有修改(需要更新查询),哪些是新添加的。对于已删除的记录,维护一个单独的列表(可能是它们的 ID)。如何实现这一壮举是单独讨论的问题。
  2. 当用户单击保存时,启动数据库事务。这不是当前讨论的严格部分,但几乎总是在类似的条件下进行。
  3. 在事务中,首先循环删除的项目数组。为每个人触发一个删除查询。
  4. 然后遍历修改过的项目数组。对于每个修改过的项目,您可以简单地将其所有列更新为最新值。如果列数太大(> 30),那么情况会有所改变。
  5. 然后是新创建的项目。为他们每个人发射一个插入物。
  6. 最后提交事务。

如果您正在编程的语言支持 try/catch 块,则在 try/catch 中执行上述所有步骤(在开始事务之后)。在 catch 块中回滚事务。

这种方法看起来比简单的删除/插入/全部方法更复杂,并且似乎触发了更多查询,但相信我,我们曾经去过那里,完成了这些,然后花了很多不眠之夜来撤消所做的一切。除非你真的能证明它是合理的,否则永远不要去删除/插入方式。

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

编辑

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

针对 Save 操作的代码将变得相当长。5x3=15 次操作,每个操作都有自己的 sql。这些操作都不应该被重用,因此将它们放在单独的方法中是徒劳的。一切都将在一个大的程序块中进行。因此虔诚地评论代码。标记表边界和操作。

于 2013-06-05T18:29:43.083 回答
1

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

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

在这样的数据库中,审计和数据恢复很容易执行。

于 2013-06-05T18:45:35.337 回答