【问题标题】:MySQL "good" way to insert a row if not found, or update it if it is found如果找不到,MySQL“好”的方式插入一行,如果找到则更新它
【发布时间】:2010-10-20 07:10:51
【问题描述】:

很多时候,我想对我的一个用户运行查询,我希望在其中存储一行并与该用户以一对一的关系关联。因此,假设(这只是一个任意示例),我有一个跟踪用户汽车的表格,以及有关汽车的一些信息。每个用户可以拥有 0 辆或 1 辆汽车。如果用户没有汽车,则表中没有该用户的条目。

汽车表(再次,只是一个例子): id, user_id, car_make, car_model

所以,当我更新这张表时,我总是会做这样的事情(伪代码):

result = SELECT * FROM cars WHERE user_id=5
if (num_rows(result)>0){
    UPDATE cars SET car_make='toyota', car_model='prius' WHERE user_id=5
}else{
    INSERT INTO cars (user_id, car_make, car_model) VALUES (5, 'toyota', 'prius')
}

我怎样才能把它变成一个“原子”工作的优雅语句?如果在另一个进程中,该行在 SELECT 和 UPDATE 语句之间被删除,会发生什么?我的 UPDATE 语句将在 INSERT 语句应该运行的地方失败。而且我觉得我需要做两个相似(但不同)的陈述来完成同样的事情!我需要的是一些声明,可以确保我想要的数据存在于表中,尤其是当我只想要满足我要求的 1 行时。例如,它可能是这样的(当然这完全是虚构的):

MAKE SURE A ROW IN cars WHERE user_id=5 IS SET WITH car_make='toyota', car_model='prius'

这样,如果user_id为5已经存在,则更新,否则插入。此外,如果我更改了要求,例如说每个用户可以拥有零辆或一辆给定 car_make 的汽车,那么我可以进一步指定:

MAKE SURE A ROW IN cars WHERE user_id=5 AND car_make='toyota' IS SET WITH car_model='prius'

我希望我的问题是有道理的!我该如何改进这个经常出现的基本插入如果未找到或更新如果找到操作?感谢您的帮助!

【问题讨论】:

    标签: mysql database-design upsert


    【解决方案1】:

    将您的列属性设置为 UNIQUE,否则会产生重复条目。

    【讨论】:

      【解决方案2】:

      这称为 UPSERT(UP 日期或 SERT)。您可以搜索许多关于它的 SO 问题。 See Wikipedia

      编辑: MySQL 4.1+ 支持 INSATE(INSert 或 updATE),只要你有一个主键。 MySQL Manual

      【讨论】:

        【解决方案3】:

        来自my other Stack Overflow answer

        如果您想在单个语句中执行此操作,我建议使用INSERT ... ON DUPLICATE KEY UPDATE 语法,如下所示:

        INSERT INTO table (id, someothervalue) VALUES (1, 'hi mom')
          ON DUPLICATE KEY UPDATE someothervalue = 'hi mom';
        

        如果不存在具有指定键值(主键或唯一键)的现有记录,则将执行初始 INSERT 语句。如果记录已存在,则执行以下UPDATE 语句(someothervalue = 3)。

        所有版本的 MySQL 都支持此功能。有关详细信息,请参阅MySQL Reference Manual page for INSERT ... ON DUPLICATE KEY UPDATE

        【讨论】:

          【解决方案4】:

          我如何使用 ON DUPLICATE KEY UPDATE 的示例: INSERT INTO 注册表(名称,值)VALUES ('" . $key . "', '" . $val . "') ON DUPLICATE KEY UPDATE value= '" . $val . "'"

          【讨论】:

            【解决方案5】:

            我认为切换它更容易。尝试插入,然后更新。

            MySQL 特别有一个子句'ON DUPLICATE KEY'

            在重复键更新时插入汽车(字段)值(值)...

            这当然需要您设置正确的唯一键。

            【讨论】:

              【解决方案6】:

              您可以使用“REPLACE INTO”或“INSERT… ON DUPLICATE KEY UPDATE”。我相信第二种是你想要的,但有些情况下 REPLACE INTO 很方便。

              【讨论】:

                【解决方案7】:

                在 Oracle 中,您有 Merge

                不知道 MySql,但该术语可能会给您提供其他搜索内容。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2020-07-08
                  • 2017-06-09
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-12-16
                  • 2018-12-10
                  相关资源
                  最近更新 更多