永远不要练习删除所有并插入所有。
原因:
- 太费钱了。主要是用户执行编辑。因此,对于只是几次更新,您进行了一次删除和一百次插入。
- 对删除级联外键造成严重破坏。
- 即使它们显然没有被触摸,也会扰乱自动增量字段。
你需要实现unit-of-work。我不知道您正在使用哪种语言,但有些语言对此具有内置支持。在 dot-net 中,我们有数据集。
基础知识:
- 跟踪您从数据库中获取的每条记录。秘密地为每条记录维护一个标志,以记录哪些是从数据库加载的(即未触及),哪些有修改(需要更新查询),哪些是新添加的。对于已删除的记录,维护一个单独的列表(可能是它们的 ID)。如何实现这一壮举是单独讨论的问题。
- 当用户单击保存时,启动数据库事务。这不是当前讨论的严格部分,但几乎总是在类似的条件下进行。
- 在事务中,首先循环删除的项目数组。为每个人触发一个删除查询。
- 然后遍历修改过的项目数组。对于每个修改过的项目,您可以简单地将其所有列更新为最新值。如果列数太大(> 30),那么情况会有所改变。
- 然后是新创建的项目。为他们每个人发射一个插入物。
- 最后提交事务。
如果您正在编程的语言支持 try/catch 块,则在 try/catch 中执行上述所有步骤(在开始事务之后)。在 catch 块中回滚事务。
这种方法看起来比简单的删除/插入/全部方法更复杂,并且似乎触发了更多查询,但相信我,我们曾经去过那里,完成了这些,然后花了很多不眠之夜来撤消所做的一切。除非你真的能证明它是合理的,否则永远不要去删除/插入方式。
关于如何进行更改跟踪,这在很大程度上取决于您使用的应用程序的语言和类型。即使对于 dot-net,桌面应用程序和 Web 应用程序的方法也不同。跟踪删除很容易。以便跟踪新的插入。通过在该字段的任何列上捕获编辑事件来应用更新标记。
编辑
数据跨越大约五个表。因此三个循环(删除/更新/插入)必须执行五次,每个表一个。首先绘制表之间的关系。先处理顶层表。然后处理直接连接到顶级表的表,依此类推。如果表之间存在循环关系,则必须特别小心。
针对 Save 操作的代码将变得相当长。5x3=15 次操作,每个操作都有自己的 sql。这些操作都不应该被重用,因此将它们放在单独的方法中是徒劳的。一切都将在一个大的程序块中进行。因此虔诚地评论代码。标记表边界和操作。