Div*_*ero 16 mysql database-design upsert
通常,我想在我的一个用户上运行查询,我希望以1对1的关系存储与该用户相关联的行.所以,让我们说(这只是一个任意的例子),我有一个表跟踪用户的汽车,以及一些关于汽车的信息.每个用户可以拥有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')
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能把它变成一个"原子地"起作用的优雅陈述?如果在另一个进程中SELECT和UPDATE语句之间的行被删除,会发生什么?我的UPDATE语句将失败INSERT语句应该运行的地方.我觉得我需要做两个相似(但不同)的陈述来完成同样的事情!我需要的是一些声明,它将向我保证我想要的数据存在于表中,特别是当我只想要一行满足我的要求时.例如,它可能是这样的(当然这是完全构成的):
MAKE SURE A ROW IN cars WHERE user_id=5 IS SET WITH car_make='toyota', car_model='prius'
Run Code Online (Sandbox Code Playgroud)
这样,如果user_id已经存在,那么它将被更新,否则将被插入.此外,如果我更改了要求,例如说每个用户可以拥有给定car_make的零个或一个汽车,那么我可以进一步指定:
MAKE SURE A ROW IN cars WHERE user_id=5 AND car_make='toyota' IS SET WITH car_model='prius'
Run Code Online (Sandbox Code Playgroud)
我希望我的问题有道理!如何改进这种经常出现的基本insert-if-not-found或update-if-found操作?谢谢你的帮助!
mis*_*hac 17
您可以使用" REPLACE INTO "或" INSERT ... ON DUPLICATE KEY UPDATE ".我相信第二个是你想要的,但有些情况下REPLACE INTO很方便.
如果你想在一个语句中这样做,我建议使用INSERT ... ON DUPLICATE KEY UPDATE语法,如下所示:
INSERT INTO table (id, someothervalue) VALUES (1, 'hi mom')
ON DUPLICATE KEY UPDATE someothervalue = 'hi mom';
Run Code Online (Sandbox Code Playgroud)
INSERT如果没有具有指定键值(主键或唯一键)的现有记录,则将执行初始语句.如果记录已存在,则执行以下UPDATE语句(someothervalue = 3).
所有版本的MySQL都支持此功能.有关详细信息,请参阅MySQL参考手册页面INSERT ... ON DUPLICATE KEY UPDATE