【问题标题】:INSERT ON DUPLICATE KEY UPDATE as substitute for UPDATEINSERT ON DUPLICATE KEY UPDATE 代替 UPDATE
【发布时间】:2012-08-24 19:08:23
【问题描述】:

这个问题有点关于“最佳实践”,但也是对潜在问题的搜索。我希望能够在不运行多个查询且不使用超级复杂查询的情况下对多个字段运行更新并分配不同的值。所以,我所做的是创建了一个具有主键和“名称”列作为唯一键的表。

现在,当我想用​​不同的值更新多个列时,我可以运行如下查询:

INSERT INTO my_table (name, description) VALUES ('name', 'mydescription'), ('name2', 'description2') ON DUPLICATE KEY UPDATE description = VALUES(description)

这是个坏主意吗?有一个更好的方法吗?标准警察会来逮捕我吗?


编辑:我确实注意到了一个潜在的问题,即竞争条件。如果一个用户在另一个用户编辑一行时删除了一行并保存了信息,则编辑将重新创建该行。 (这可以用作功能或错误。)

【问题讨论】:

  • 这是一个类似的问题,但我想更多地询问这是否允许。在这种情况下,我不太担心性能(我知道,我知道),因为应用程序被包含并限制使用。但是有一个简单的替代方案吗?使用update 执行此操作的唯一方法是使用UPDATE 并带有一个有点难看的case 条件。
  • 它有效,而且非常简洁。请参阅下面的答案以获取替代方法。

标签: mysql insert on-duplicate-key


【解决方案1】:

进一步到my comment above(链接到另一个发布者建议使用已知存在记录的INSERT ... ON DUPLICATE KEY UPDATE 对性能的影响的问题),可以使用多表UPDATE 语法和一个具体化的表从常量使用UNION:

UPDATE my_table JOIN (
    SELECT 'name' AS name, 'mydescription' AS description
  UNION ALL
    SELECT 'name2', 'description2'
) t USING (name) SET my_table.description = t.description

【讨论】:

  • 尽管我不想承认...我不太确定这里发生了什么...这是一个看似复杂的查询,而我试图使其保持简单和可维护。
  • @Tom:你只是从一个子查询创建一个表t,该子查询由两个SELECT <constant>, <constant>语句组成,由UNION组合而成;然后将该表加入到name 列匹配的my_table,并根据需要更新description 列。如果您不关心性能并且觉得这种方法太复杂,那么您使用 INSERT ... ON DUPLICATE KEY UPDATE 的原始方法可能是最好的选择。
  • 如何通过这种方法添加多列?
  • @Tom:你是什么意思?如果您想在匹配name 的同时更新更多的description,只需将附加数据添加为子查询中的新列(例如SELECT ... , 'newdata' AS column_name)并向SET 子句添加进一步的语句(例如@987654340 @)。
  • 您可以添加更多的 UNION。保持不变,它们运行起来并不昂贵,这样您就可以避免重新插入已删除行的风险。
猜你喜欢
  • 2015-07-30
  • 2010-10-07
  • 2013-10-03
  • 2011-01-29
  • 2017-04-24
  • 2011-08-09
  • 1970-01-01
  • 2023-02-06
  • 1970-01-01
相关资源
最近更新 更多