平时我们在设计数据库表的时候总会设计 unique  或者 给表加上 primary key 的限制条件.

此时 插入数据的时候 ,经常会有这样的情况:

我们想向数据库插入一条记录:

若数据表中存在以相同主键的记录,我们就更新该条记录。

否则就插入一条新的记录。

逻辑上我们需要怎么写:

$result = mysql_query('select * from xxx where id = 1');
$row = mysql_fetch_assoc($result);
if($row){
mysql_query('update ...');
}else{
mysql_query('insert ...');
}

但是这样写有两个问题

1、效率太差,每次执行都要执行2个sql
2、高并发的情况下数据会出问题,不能保证原子性

还好MySQL 为我们解决了这个问题:我们可以通过 ON DUPLICATE KEY UPDATE  达到以上目的, 且能保证操作的原子性和数据的完整性。

ON DUPLICATE KEY UPDATE 可以达到以下目的:

向数据库中插入一条记录:

若该数据的主键值/ UNIQUE KEY 已经在表中存在,则执行更新操作, 即UPDATE 后面的操作。

否则插入一条新的记录。

示例:

Step1 . 创建表,插入测试数据

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for mRowUpdate
-- ----------------------------
DROP TABLE IF EXISTS `mRowUpdate`;
CREATE TABLE `mRowUpdate` (
  `id` int(11) NOT NULL,
  `value` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

-- ----------------------------
-- Records of mRowUpdate
-- ----------------------------
INSERT INTO `mRowUpdate` VALUES ('1', 'sss');
INSERT INTO `mRowUpdate` VALUES ('2', 'szh');
INSERT INTO `mRowUpdate` VALUES ('3', '9999');
SET FOREIGN_KEY_CHECKS=1;

 
 
 
Step2 .测试 ON DUPLICATE KEY UPDATE 的使用方法:
 
 
INSERT INTO mRowUpdate(id,`value`) VALUES(3, 'SuperMan') ON DUPLICATE KEY UPDATE `value`='SuperMan';
 
 
 
Step3. 查询数据的变化情况
select * from test.mRowUpdate;
 
id value
1 sss
2 szh
3 SuperMan
 
 
 
 
 
==========================     话外篇   ===============================
 
 
技巧:
 
技巧 1 :
 
ON DUPLICATE KEY UPDATE 特别适用于多行插入。如:
 
INSERT INTO `table` (`a`, `b`, `c`) VALUES (1, 2, 3), (4, 5, 6) ON DUPLICATE KEY UPDATE `c`=VALUES(`a`)+VALUES(`b`);
 
          Tips: VALUES()函数只在INSERT…UPDATE语句中有意义,其它时候会返回NULL。
 
 
 
 
注意事项:
 
注意 1:
 
若多个索引都冲突,则只有一条记录被修改。
 
 
create table test(
id int not null primary key,
num int not null UNIQUE key,
tid int not null
)
为了测试两个唯一索引都冲突的情况,然后插入下面的数据

insert into test values(1,1,1), (2,2,2);
然后执行:

insert into test values(1,2,3) on duplicate key update tid = tid + 1;
因为a和b都是唯一索引,插入的数据在两条记录上产生了冲突,然而执行后只有第一条记录被修改

 

mysql主键重复,不抱错,只更新的骚操作 (如果没有插入,如果有更新)的更多相关文章

  1. (2.10)Mysql之SQL基础——约束及主键重复处理

    (2.10)Mysql之SQL基础——约束及主键重复处理 关键词:mysql约束,批量插入数据主键冲突 [1]查看索引: show index from table_name; [2]查看有约束的列: ...

  2. mysql insert插入时实现如果数据表中主键重复则更新,没有重复则插入的四种方法

    [CSDN下载] Powerdesigner 设计主键code不能重复等问题 [CSDN博客] Oracle中用一个序列给两个表创建主键自增功能的后果 [CSDN博客] MySQL自增主键删除后重复问 ...

  3. mysql insert 主键 重复问题

    转自:http://blog.163.com/liuweiyoung@126/blog/static/173131045201222122732435/ mysql中insert into和repla ...

  4. (转)mysql自增列导致主键重复问题分析

    mysql自增列导致主键重复问题分析...  原文:http://www.cnblogs.com/cchust/p/3914935.html 前几天开发童鞋反馈一个利用load data infile ...

  5. MYSQL主键自动增加的配置及auto_increment注意事项

    文章一 原文地址: http://ej38.com/showinfo/mysql-202971.html 文章二:   点击转入第二篇文章 在数据库应用,我们经常要用到唯一编号.在MySQL中可通过字 ...

  6. MySQL主键与索引的区别和联系

    MySQL主键与索引的区别和联系   关系数据库依赖于主键,它是数据库物理模式的基石.主键在物理层面上只有两个用途: 惟一地标识一行. 作为一个可以被外键有效引用的对象. 索引是一种特殊的文件(Inn ...

  7. jfinal基本应用 --报主键重复

    在使用jfinal 的Model过程中有一个很怪异的问题,发布到服务器上,只要是往表中添加字段,就报主键重复. 1.我添加表的时候调用了 public void create(Map map){ St ...

  8. MySQL主键设计

    [TOC] 在项目过程中遇到一个看似极为基础的问题,但是在深入思考后还是引出了不少问题,觉得有必要把这一学习过程进行记录. MySQL主键设计原则 MySQL主键应当是对用户没有意义的. MySQL主 ...

  9. Mysql主键索引、唯一索引、普通索引、全文索引、组合索引的区别

    原文:Mysql主键索引.唯一索引.普通索引.全文索引.组合索引的区别 Mysql索引概念: 说说Mysql索引,看到一个很少比如:索引就好比一本书的目录,它会让你更快的找到内容,显然目录(索引)并不 ...

随机推荐

  1. MAC电脑安装svn客户端cornerstone

    个人感觉在mac上最好用的svn客户端就是cornerstone,公司客户端也统一使用这个 sudo spctl --master-disable 这条命令作用就是使得mac运行安装任何来源App,不 ...

  2. SQLServer数据库执行较大的脚本

    当我们需要在SQLServer数据库里面执行一个比较大的文件(比如2GB)时,会发现数据库根本无法打开该脚本文件,原因是因为查询分析器只能执行100M以内的文件,所以脚本过大就会造成内存溢出.下面是具 ...

  3. Python学习---django模板语法180122

    django模板语法[Template] 模版的组成:  HTML代码+逻辑控制代码  <h1> {{ user_name }} </h1> 逻辑控制代码的组成: 1.变量: ...

  4. C# 委托/Func() 中 GetInvocationList() 方法的使用 | 接收委托多个返回值

    在日常使用委托时,有以下常用方法 方法名称 说明  Clone   创建委托的浅表副本.  GetInvocationList   按照调用顺序返回此多路广播委托的调用列表.  GetMethodIm ...

  5. C语言程序员必读的5本书

    本文由 伯乐在线 - programmer_lin 翻译自 fromdev.欢迎加入技术翻译小组.转载请参见文章末尾处的要求. 你正计划着通过看书来学习C语言吗?“书籍是人类最忠诚的朋友“.海明威一定 ...

  6. Linux的图形模式和文本模式以及单用户模式切换

    1.默认开机进入文本模式 如果想让开机自动进纯文本模式, 修改/etc/inittab 找到其中的 id:5:initdefault: 这行指示启动时的运行级是5,也就是图形模式 改成3就是文本模式了 ...

  7. problem during schema drop, statement alter table ACT_RU_VARIABLE

    将activiti的databaseSchemaUpdate设置为drop-create抛出DbSqlSession 错误 发布于2015-02-14 16:03:57 浏览7851次 Excepti ...

  8. PostgreSQL 连接的问题

    一.在postgresql的安装文件夹\8.3\data\pg_hba.conf里面(或者在开始菜单程序下面的postgresql的配置文档)找到“# IPv4 local connections:” ...

  9. 【OpenCV】透视变换矫正

    演示结果参考: 功能实现:运行程序,会显示图片的尺寸,按回车键后,依次点击需矫正的图片的左上.右上.左下.右下角,并能显示其坐标,结果弹出矫正后的图片,如图上的PIC2对话框.可以继续选择图片四个点进 ...

  10. 【LGP5162】WD与积木

    题目 场面过度玄学,容易引起不适 我们发现我们要求的这个期望由分母和分子两部分构成 易发现 \[Ans=\frac{\sum_{i=1}^nS_2(n,i)\times i\times i!}{\su ...