MySQL复合主键下ON DUPLICATE KEY UPDATE语句失效问题
问题的起因,假设有一张表,里面保存了交易订单,每张订单有唯一的ID,有最后更新时间,还有数据,详情如下:
|
1
2
3
4
5
6
7
|
+-------+----------+------+-----+---------------------+-------+| Field | Type | Null | Key | Default | Extra |+-------+----------+------+-----+---------------------+-------+| UID | int(11) | NO | PRI | 0 | || Time | datetime | NO | | 0000-00-00 00:00:00 | || Data | int(11) | YES | | NULL | |+-------+----------+------+-----+---------------------+-------+ |
针对这张表会做追加及更新的操作,具体来说就是如果订单不存在就INSERT一条新的,如果已存在就UPDATE。由于入库前无法得知相应记录是否已存在,通常的做法无法以下几种:
1、先SELECT一下,再决定INSERT还是UPDATE;
2、直接UPDATE,如果受影响行数是0,再INSERT;
3、直接INSERT,如果发生主键冲突,再UPDATE;
这几种方法都有缺陷,对MySQL来说其实最好的是直接利用INSERT...ON DUPLICATE KEY UPDATE...语句,具体到上面的test表,执行语句如下 :
|
1
|
INSERT INTO test VALUES (1, '2016-1-1', 10) ON DUPLICATE KEY UPDATE Time='2016-1-1',Data=10; |
可以很好的插入或更新数据,一条语句就搞定,至此一直工作得很好。
后来因为查询方式变更,要求将UID和Time两个字段做联合主键,此时表结构如下:
|
1
2
3
4
5
6
7
|
+-------+----------+------+-----+---------------------+-------+| Field | Type | Null | Key | Default | Extra |+-------+----------+------+-----+---------------------+-------+| UID | int(11) | NO | PRI | 0 | || Time | datetime | NO | PRI | 0000-00-00 00:00:00 | || Data | int(11) | YES | | NULL | |+-------+----------+------+-----+---------------------+-------+ |
但是问题来了:一但Time字段被更新,即使是相同的UID,也被数据库认为是不同的主键,因此不会产生主键冲突,上面的语句就失效了,数据库里出现了很多UID相同的数据。
开始寻找解决办法,其实也简单,按MySQL文档里的说明,ON DUPLICATE KEY UPDATE语句判断是否冲突是依靠主键或唯一索引,因此为UID建立唯一索引就可以了。先建索引:
|
1
|
CREATE UNIQUE INDEX IDX_UID ON test(UID); |
再测试一下插入:
|
1
2
|
INSERT INTO test VALUES (1, '2016-1-1', 10) ON DUPLICATE KEY UPDATE Time='2016-1-1',Data=10;INSERT INTO test VALUES (1, '2016-2-1', 20) ON DUPLICATE KEY UPDATE Time='2016-2-1',Data=20; |
MySQL复合主键下ON DUPLICATE KEY UPDATE语句失效问题的更多相关文章
- Mysql中Insert into xxx on duplicate key update问题
要点:Insert into xxx on duplicate key update可以在唯一索引重复的情况下,进行更新操作. (1) 插入里边的字段应该只有一个 唯一索引: ...
- mysql INSERT ... ON DUPLICATE KEY UPDATE语句
网上关于INSERT ... ON DUPLICATE KEY UPDATE大多数文章都是同一篇文章转来转去,首先这个语法的目的是为了解决重复性,当数据库中存在某个记录时,执行这条语句会更新它,而不存 ...
- MySQL中insert ignore into, on duplicate key update,replace into,insert … select … where not exist的一些用法总结
在MySQL中进行条件插入数据时,可能会用到以下语句,现小结一下.我们先建一个简单的表来作为测试: CREATE TABLE `books` ( `id` ) NOT NULL AUTO_INCREM ...
- mysql 插入重复值 INSERT ... ON DUPLICATE KEY UPDATE
向数据库插入记录时,有时会有这种需求,当符合某种条件的数据存在时,去修改它,不存在时,则新增,也就是saveOrUpdate操作.这种控制可以放在业务层,也可以放在数据库层,大多数数据库都支持这种需求 ...
- MySQL 当记录不存在时insert,当记录存在时update(ON DUPLICATE KEY UPDATE, REPLACE语句)
MySQL 当记录不存在时insert,当记录存在时更新 网上基本有三种解决方法. 第一种:示例一:insert多条记录 假设有一个主键为 client_id 的 clients 表,可以使用下面的语 ...
- mysql 添加数据如果数据存在就更新ON DUPLICATE KEY UPDATE和REPLACE INTO
#下面建立game表,设置name值为唯一索引. CREATE TABLE `game` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar( ...
- 步步为营Hibernate全攻略(四)剪不断理还乱之:复合主键 && 组合映射
一:复合主键 复合主键即两个或多个字段联合起来作为主键,它的通常做法是将主键相关字段抽取出来放到一个单独的类中,但是这样的类是有要求的: 1. 必须实现序列化接口 2. 必须覆盖e ...
- mysql 中 replace into 与 insert into on duplicate key update 的使用和不同点
replace into和insert into on duplicate key update都是为了解决我们平时的一个问题 就是如果数据库中存在了该条记录,就更新记录中的数据,没有,则添加记录. ...
- INSERT ... ON DUPLICATE KEY UPDATE Syntax
一 mybatis中返回自动生成的id 当有时我们插入一条数据时,由于id很可能是自动生成的,如果我们想要返回这条刚插入的id怎么办呢.在mysql数据中我们可以在insert下添加一个selectK ...
随机推荐
- 菜鸟vimer成长记——第4.0章、Vim插件管理利器-Vundle
定义 Vundle是vim bunler和简称,它是一个vim插件管理器. Vim本身缺乏对插件的有效管理,安装插件并配置.vimrc文件非常不便.gmarik受到Ruby的bunler的启发,开发了 ...
- 【TestNG测试】TestNG、Maven、testng.xml构建测试工程
创建一个maven工程 使用Idea创建maven工程 建立类似如上的工程结构,src/main/java,src/test/java,pom.xml,testng.xml,这里由于我们使用工程是 ...
- 与(&)、或(|)等运算符理解及其特殊用途
1.按位与运算符(&) 在与运算中两个开关是串联的,如果我们要开灯,需要两个开关都打开灯才会打开.理解为A与B都打开,则开灯,所以是1&1=1任意一个开关没打开,都不开灯,所以其他运算 ...
- 【SIKIA计划】_07_Unity3D游戏开发-坦克大战笔记
[新增分类][AudioClips]音频剪辑[AudioMixers]音频混合器[Editor][Fonts]字体[Materials]材质[Models]模型[Standard Assets] [渲 ...
- 《杜增强讲Unity之Tanks坦克大战》7-坦克血条
7 坦克血条 点击菜单GameObject->UI->Slider创建Slider 选中EventSystem,设置Horizontal Axis为HorzontalUI,Vertic ...
- MYSQL 表转 JavaBean 工具类
import org.apache.commons.lang.StringUtils; import java.io.BufferedWriter; import java.io.File; impo ...
- TP里where的查询方式,比如or应该怎么写?
这应该是个基础..只是我没有系统的学TP,所以用到了临时查了手册. 正常来说,thinkphp里的查询方式是: ThinkPHP可以支持直接使用字符串作为查询条件,但是大多数情况推荐使用数组或者对象来 ...
- 使用CNN做数字识别和人脸识别
上次写的一层神经网络也都贴这里了. 我有点困,我先睡觉,完了我再修改 这个代码写法不太符合工业代码的规范,仅仅是用来学习的的.还望各位见谅 import sys,ossys.path.append(o ...
- Analysis 图标分析 - loadrunner
analysis常见 /
- python-分叉树枝
import turtle def draw_branch(length): #绘制右侧树枝 if length >5: if length == 10: turtle.pencolor('gr ...