1

所以公平地说,我在这里这里看到了一些类似的问题,但我相信这些问题主要是关于单行更新以及假设实际数据没有改变。

就我而言,我有一组销售代表可以提供的产品。这些整体产品由定义它们的主表维护:

主表

ID  | Name  | status
---------------------
1   | prod1 |  1
2   | prod2 |  1
3   | prod3 |  0
4   | prod4 |  1

其中 status 表示活动 (1) 或非活动 (0)。无论代表表中的设置如何,任何代表都无法销售非活动产品。

代表表

ID |  repID  |  status
------------------------
1  |   rep1  |   1
2  |   rep1  |   1
3  |   rep1  |   1
1  |   rep2  |   0
2  |   rep2  |   1
3  |   rep3  |   0

此表中的状态为活动 (1) 或非活动 (0)。同样,在决定销售代表可以提供哪些产品方面,主表的状态始终会覆盖 rep_table 状态。

我遇到的主要问题是当我们推出新产品供销售代表销售时。在代表的管理门户中,他能够激活或停用他们希望提供的任何产品集。当用户选择(表单复选框)他/她希望销售的所有产品并点击提交一系列检查时:

  1. 代表是否选择了一组产品?
  2. 选择的产品格式是否正确?
  3. 所选产品列表是否与他们登录时已设置的列表不同(如果没有,则提醒不会发生更新)?
  4. 表格中选择的所有产品是否都存在并在 master_table 中设置为“活动”?

此时,对于每个选定的产品,逻辑(当前)切换到以下内容:

  1. 将 rep_table 中的所有产品更新为非活动状态(针对该特定代表)
  2. 如果产品在登录时存在于当前产品集中,并且当前状态设置为非活动,则将该产品 ID 排队等待活动。
  3. 如果登录时当前产品集中不存在传递的产品,则将新产品插入rep_table并设置为活动。

在“更新”语句开始时将特定代表的所有产品更新为非活动状态的主要原因是发现登录时设置为“活动”的哪些产品在登录时更改为“非活动”的复杂性。产品选择表。

我想知道是否不是试图找出当前产品选择的状态相对于代表登录时的状态,而是首先删除 rep_table 中特定 repID 的所有产品 ID 然后全部插入一次。我知道在这种情况下我正在运行 2 个查询,但是在我在同一命令中进行更新和插入的情况下,我每次至少运行 2 个以上的查询。

以这种方式删除和插入是否有“技术”含义?

注意:我的表是 InnoDB,我正在运行 MySQL

4

3 回答 3

2

根据您的索引方式,从技术上讲,删除和插入可能是您提高性能的最佳选择。不过,如果您有良好的索引,使用该索引的 UPDATE 或 REPLACE 语句不值得担心删除所有数据然后重新插入。

如果 Delete 语句通过,但在您发出插入之前,您的服务器重新启动 apache 并且内存被转储......似乎很牵强,但可能会发生。更多的用户、更多的更新、更可能的改变……你可以将 DELETE 和 INSERT 放在一个事务中,但现在你可能会锁定一个表——这也会影响性能。

于 2013-07-31T21:52:56.070 回答
1

这通常是我在更新此类选项时所做的。启动事务通常更容易,删除旧选项列表,然后插入用户选择的新选项。它可能是两个查询,但它们是简单的查询。

另一种选择是手动构建“更改”列表 - 找出新内容,找出删除的内容,然后删除删除/插入新的。这通常需要更多的执行开销,只是为了完成同样的事情。无论如何,您仍然会运行两个查询。

于 2013-07-31T21:52:44.030 回答
0

只是为了完成其他答案,从概念的角度来看,UPDATE修改现有的行。DELETE+INSERT将创建新行。

虽然起初相当理论,但这具有实际意义:

  • 例如,关于数据库的引用完整性(外键约束、级联)。
  • 这也可能导致触发不同的触发器
  • 最后DELETE+INSERT可能(并且可能)与UPDATES同一行上的并发冲突。
于 2013-07-31T22:25:29.413 回答