【问题标题】:Create if an entry if it doesn't exist, otherwise update?如果条目不存在则创建,否则更新?
【发布时间】:2010-10-16 07:42:57
【问题描述】:

用这么短的话来说有点奇怪,呵呵。

无论如何,我想要的基本上是更新表中的条目(如果确实存在),否则创建一个用相同数据填充它的新条目。

我知道这很容易,但就我使用 MySQL 的程度而言,我还是比较陌生:P

【问题讨论】:

标签: mysql


【解决方案1】:

很多开发人员仍然执行查询来检查表中是否存在字段,然后根据第一次查询的结果执行插入或更新查询。 尝试使用 ON DUPLICATE KEY 语法,这比执行 2 个查询更快更好。更多信息可以找到here

INSERT INTO table (a,b,c) VALUES (4,5,6) 重复密钥更新 c=9;

如果你想为 c 保持相同的值,你可以使用相同的值进行更新

INSERT INTO table (a,b,c) VALUES (4,5,6) 重复密钥更新 c=6;

“替换”和“重复键”的区别:

替换:插入,或删除和插入

在重复键上:插入或更新

如果您的表没有主键或唯一键,则替换没有任何意义。

您还可以使用VALUES 函数来避免必须两次指定实际值。例如。而不是

INSERT INTO table (a,b,c) VALUES (4,5,6) ON DUPLICATE KEY UPDATE c=6;

你可以使用

INSERT INTO table (a,b,c) VALUES (4,5,6) ON DUPLICATE KEY UPDATE c=VALUES(c);

VALUES(c) 将计算为之前指定的值 (6)。

【讨论】:

  • IMO,这个回复更好地回答了这个问题。如果当行已经存在时你真的想要更新,REPLACE 是破坏性的:“REPLACE 的工作方式与 INSERT 完全一样,除了如果表中的旧行与 PRIMARY KEY 或 UNIQUE 索引的新行具有相同的值,则在插入新行之前删除旧行。” (MySQL 手册)
  • 请注意,它不完全是“插入或更新”,而是“插入或删除+插入”,这意味着如果您只想更新部分列,这不是一个合适的解决方案:与更新不同,没有指定值的列的值将被设置为默认值(并且会丢失)
  • “REPLACE INTO”和“INSERT INTO ... ONDUPLICATE KEY”之间存在差异。在第二个中,您可以访问旧值(甚至可以像 value = value + 1 一样操作它们),然后通过在 ON DUPLICATE 中包含 value = value 来避免旧值丢失,以避免将值设置回默认值
【解决方案2】:

使用“替换成”:

 REPLACE INTO table SET id = 42, foo = 'bar';

MySQL documentation中查看更多信息

【讨论】:

  • 它为 REPLACE INTO 用户 SET ip = '$uip', lastcheck = '$tim' 创建了多个条目
  • 那么您遇到的行为是预期的。一个字段必须是主要字段或唯一字段才能正常工作。否则,MySQL 怎么知道防止重复?看来您应该在此表中拥有 user_id(作为主键),您也可以在替换中设置它。
  • 所以我有一个名为 uid 的主键,它是 INT,但它仍在创建重复项。你是说我需要修改查询吗?如果是这样,它最终应该是什么?
  • 实际上,没关系,我通过将 ip 更改为 VARCHAR 并将其设置为 UNIQUE 来使其工作。
【解决方案3】:

正如其他人所说,REPLACE 是要走的路。不过要小心使用它,因为它实际上在桌子上做了一个DELETEINSERT。这在大多数情况下都很好,但如果您的外键带有 ON DELETE CASCADE 这样的约束,则可能会导致一些大问题。

【讨论】:

    【解决方案4】:

    在 MySQL 手册中查找 REPLACE

    REPLACE 的工作方式与 INSERT 完全相同, 除了如果表中的旧行 具有与 a 的新行相同的值 PRIMARY KEY 或 UNIQUE 索引,旧的 行在新行被删除之前被删除 插入。请参见第 12.2.5 节,“插入 语法”。

    REPLACE 是 MySQL 对 SQL 标准。它要么插入,要么 删除和插入。对于另一个 MySQL 对标准 SQL 的扩展——即 插入或更新 - 请参阅 Section 12.2.5.3, “插入 ... 开启 DUPLICATE KEY UPDATE 语法”。

    如果您有以下 INSERT 查询:

    INSERT INTO table (id, field1, field2) VALUES (1, 23, 24)
    

    这是您应该运行的 REPLACE 查询:

    REPLACE INTO table (id, field1, field2) VALUES (1, 23, 24)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多