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 ...
随机推荐
- Error:(1, 1) java: 非法字符: ‘\ufeff’
一.问题 用IDEA打开eclipse java项目编译时,出现以下错误: Error:(1, 1) java: 非法字符: '\ufeff' Error:(1, 10) java: 需要class, ...
- BootStap学习笔记(1)
移动设备优先: 为了让开发的网站对移动设备友好,确保适当的绘制和触屏缩放,需要在网页的head之中添加viewport meat标签:如下: <metaname="viewport& ...
- 图片缩放插件GestureImageView——Android 常用插件推荐(一)
Android 开发过程中,交互效果是一个非常繁琐的过程,甚至比Web开发过程中JS特效更加复杂.通过多年的发展,常用的交互方式已经发展相当成熟,而且有很多非常好的插件.为了避免重复造轮子,一些常用的 ...
- Jenkins自动化测试
Jenkins自动化测试 一个持续集成的基本原则是构建应该是可验证的.你必须能够客观地确定一个特定的构建是否准备就绪构建过程的下一个阶段,最便捷的方式做到这一点是使用自动化测试.如果没有适当的自动化测 ...
- Netty源码分析第3章(客户端接入流程)---->第5节: 监听读事件
Netty源码分析第三章: 客户端接入流程 第五节: 监听读事件 我们回到AbstractUnsafe的register0()方法: private void register0(ChannelPro ...
- Extreme Learning Machine 翻译
本文是作者这几天翻译的一篇经典的ELM文章,是第一稿,所以有很多错误以及不足之处. 另外由于此编辑器不支持MathType所以好多公式没有显示出来,原稿是word文档. 联系:250101249@qq ...
- FileZilla-FTP连接失败
状态: 已登录状态: 读取“/”的目录列表...命令: CWD /响应: 250 CWD successful. "/" is current directory.命令: TYPE ...
- Redux 入门教程(一):基本用法
转自http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html(仅供个人学习使用) 首先明确一点, ...
- PowerDesgner的视图显示设置教程
一.简介 PowerDesgner是一款实用的数据库原型设计软件,但一些新手往往会觉得不好上手,应小伙伴需要,整理了一下PowerDesgner的视图显示设置教程: 首先,PowerDesgner的数 ...
- No.1001_第六次团队会议
黯淡的一日 今天发生了很令人不爽的一件事,杜正远又被叫去实验室了.昨天界面就很难做,而且我们组人手稀缺,他的缺席让我很难做下去. 今天开会我自己没做出什么来,就加了一个群组的添加功能,同样,曾哲昊也没 ...