mysql处理某个唯一索引时存在则更新,不存在则插入的情况应该是很常见的,网上也有很多类似的文章,我今天就讲讲当这个唯一的索引是多列唯一索引时可能会遇到的问题和方法。

方法一:

使用 INSERT INTO ON ... DUPLICATE KEY UPDATE ... :

表的创建如下:

CREATE TABLE `test_table` (`id`  int(11) NOT NULL AUTO_INCREMENT ,`var1`  varchar(100) CHARACTER SET utf8 DEFAULT NULL,`var2`  tinyint(1) NOT NULL DEFAULT '0',`var3`  varchar(100) character set utf8 default NULL,`value1`  int(11) NOT NULL DEFAULT '1',`value2`  int(11) NULL DEFAULT NULL,`value3`  int(5) DEFAULT NULL,PRIMARY KEY (`Id`),UNIQUE INDEX `index_var` (`var1`, `var2`, `var3`)
) ENGINE=MyISAM DEFAULT CHARACTER SET=latin1 AUTO_INCREMENT=1;

其中该表中var1、var2和var3完全相同的记录只能有一条,所以建了一个多列唯一索引index_var,这样一来我们就可以使用  INSERT INTO ON ... DUPLICATE KEY UPDATE ... 来实现插入数据时存在则更新,不存在则插入的功能了,如下:

INSERT INTO `test_table`
(`var1`, `var2`, `var3`, `value1`, `value2`, `value3`) VALUES
('abcd', 0, 'xyz', 1, 2, 3)
ON DUPLICATE KEY UPDATE `value1` = `value1` + 1 AND
`value2` = `value2` + 2 AND `value3` = `value3` + 3;

该条插入语句的含义是:向test_table表中插入,如果不存在val1 = 'abcd',val2 = 0, val3 = ‘xyz’的记录,那就插入

val1 = 'abcd',val2 = 0, val3 = ‘xyz’,value1 = 1, value2 = 2, value3 = 3的记录,

如果存在,那就更新value1的值为value1+1,更新value2的值为value2+2,更新value3的值为value3+3。

这样,的确是没有问题的,但是,如果表的创建如下:

CREATE TABLE `test_table` (`id`  int(11) NOT NULL AUTO_INCREMENT ,`var1`  varchar(1024) CHARACTER SET utf8 DEFAULT NULL,`var2`  tinyint(1) NOT NULL DEFAULT '0',`var3`  varchar(1024) character set utf8 default NULL,`value1`  int(11) NOT NULL DEFAULT '1',`value2`  int(11) NULL DEFAULT NULL,`value3`  int(5) DEFAULT NULL,PRIMARY KEY (`Id`),UNIQUE INDEX `index_var` (`var1`, `var2`, `var3`)
) ENGINE=MyISAM DEFAULT CHARACTER SET=latin1 AUTO_INCREMENT=1;

注意:var1和var3的最大长度由100变成了1024,此时执行该创建语句时会报如下错误:

Specified key was too long; max key length is 1000 bytes

这是由于index_var索引的为1024 * 3 + 1 + 1024 * 3 > 1000导致的,如果遇到这种情况怎么办?有两种解决办法。

第一,将数据库的engine由MyISAM换成InnoDB就可以了,那么这两个引擎有什么区别呢?

看这里

不过,这样换有一个缺点,就是InnoDB的性能没有MyISAM的好,那么如果想要不牺牲性能的话,那就只有用第二个方法了,也就是我们这里说的方法二!

方法二:

使用dual虚拟表来实现。

使用dual虚拟表来实现的话就不需要创建多列唯一索引了,表的创建如下:

CREATE TABLE `test_table` (`id`  int(11) NOT NULL AUTO_INCREMENT ,`var1`  varchar(1024) CHARACTER SET utf8 DEFAULT NULL,`var2`  tinyint(1) NOT NULL DEFAULT '0',`var3`  varchar(1024) character set utf8 default NULL,`value1`  int(11) NOT NULL DEFAULT '1',`value2`  int(11) NULL DEFAULT NULL,`value3`  int(5) DEFAULT NULL,PRIMARY KEY (`Id`)
) ENGINE=MyISAM DEFAULT CHARACTER SET=latin1 AUTO_INCREMENT=1;

插入语句则是形如:

INSERT INTO table
(primarykey, field1, field2, ...)
SELECT key, value1, value2, ...
FROM dual
WHERE not exists (select * from table where primarykey = id);

的语句,此时我们可以用以下语句代替:

INSERT INTO `test_table` SELECT 0, 'abcd', 0, 'xyz', 1, 2, 3
FROM dual WHERE NOT EXISTS (
SELECT * FROM `test_table` WHERE
`var1` = 'abcd' AND `var2` = 0 AND `var3` = 'xyz');

此时,如果val1 = 'abcd',val2 = 0, val3 = ‘xyz’的记录不存在,那么就会执行该插入语句插入该记录,如果存在,那就需要我们再使用相应的更新语句来更新记录:

UPDATE `test_table` SET
`value1` = `value1` + 1, `value2` = `value2` + 2, `value3` = `value3` + 3
WHERE `val1` = 'abcd' AND `val2` = 0 AND `val3` = 'xyz';

OK!到这里,基本上讲完了。

注:转载请注明出处!

参考:

http://thobian.info/?p=1035

http://blog.51yip.com/mysql/1515.html

转载于:https://www.cnblogs.com/jiangu66/p/3184797.html

mysql处理存在则更新,不存在则插入(多列唯一索引)相关推荐

  1. mysql两列唯一索引吗_mysql多字段唯一索引

    项目中需要用到联合唯一索引: 例如:有以下需求:每个人每一天只有可能产生一条记录:处了程序约定之外,数据库本身也可以设定: 例如:user表中有userID,userName两个字段,如果不希望有2条 ...

  2. mysql隐式锁定辅助索引_当Mysql - InnoDB行锁遇到复合主键和多列索引-Go语言中文社区...

    背景 今天在配合其他项目组做系统压测,过程中出现了偶发的死锁问题.分析代码后发现有复合主键的update情况,更新复合主键表时只使用了一个字段更新,同时在事务内又有对该表的insert操作,结果出现了 ...

  3. mysql 唯一索引_面试官:谈谈你对mysql索引的认识?

    引言 大家好,我渣渣烟.我曾经写过一篇<面试官:讲讲mysql表设计要注意啥>,当时写完后,似乎效果还行! 于是呢,决定再来一个mysql的数据库专题,这篇我们就来谈谈关于索引方面的mys ...

  4. access建立两个字段唯一索引_面试官:谈谈你对mysql索引的认识?

    引言 这篇我们就来谈谈关于索引方面的mysql面试题.还是老规矩,讲的是在Innodb存储引擎下的情形,毕竟我还真没用过Mysiam之类的存储引擎. ps:其实很早就想写了,一直偷懒! 其实这下面每个 ...

  5. peewee 实现 有则更新,无则插入.

    背景:想用peewee实现 mysql数据库 有则更新,无则插入.几番查找,发现在官方文档中有.下图: 在本地的数据库测试了,以下是测试语句及结果: 表结构 class Practice(Model) ...

  6. 别踩坑!使用MySQL唯一索引请注意

    背景 在程序设计中,我们往往需要确保数据的唯一性,比如在常见的注册模块,我们需要确保一个手机号只能注册为一个账号.这种情况下,我们的程序往往是第一道关卡,用户来注册之前,首先判断这个手机号是否已经注册 ...

  7. mysql 更改 uf_SQL经典实例(四)插入、更新和删除

    插入默认值 定义表的某些列的默认值: create table D (id integer default 0); 所有的数据库都支持使用default关键字来显式地为某一列指定默认值: insert ...

  8. mysql replace update_mysql的replace,存在更新,不存在插入

    insert 标准的sql语句中,插入数据只有一种形式insert into tablename (列明) values (列值); 插入多条insert into tablename (列明) va ...

  9. mysql用一个表更新另一个表的方法

    Solution 1:  修改1列(navicate可行) update student s, city c set s.city_name = c.name where s.city_code = ...

最新文章

  1. 关于epel源的配置
  2. 十七、生产者消费者问题
  3. nginx+tomcat集群负载均衡中的多虚拟主机配置
  4. linux wlan进程名称,linux无线网络配置无线网卡驱动安装与wlan802.11配置
  5. sql 语言中 when case 用法
  6. codeforces 339A-C语言解题报告
  7. linux8重启服务代码,linux(centos8):安装分布式事务服务seata(seata 1.3.0/centos 8.2)
  8. java 井字棋 人机_一个井字棋tictactoe游戏的java实现 | Soo Smart!
  9. 【WPF】在MenuItem中下划线“_”显示不正常
  10. python json转xml_Python实现XML到JSON的转换并编写,python,xml,转化,为,Json,进行,写入
  11. 译:25个面试中最常问的问题和答案
  12. Spring Boot + WebSocket实现网页在线实时聊天
  13. 英媒:俄黑客靠窃密跻身“成功企业家” 被捕时昏迷
  14. python输入球的半径_python程序设计:输入球体半径r,计算球体的体积和表面积
  15. 环球黑卡可以透支吗?环球黑卡是信用卡吗
  16. vmware应用程序无法正常启动0xc000007b
  17. 【Materials Studio学习六】构建固液表面
  18. Midjourney API 接口对接历程
  19. ARM实验板移植Linux操作系统,LCD显示汉字(名字)
  20. PB函数大全(超全,解析很全面)

热门文章

  1. 适配器模式(为被封装对象提供不同的接口)
  2. IDEA 程序包org.springframework.web.bind.annotation不存在
  3. Bit-Z召开全球生态联盟暨韩国战略发布会 将成立BZ资本
  4. Android热更新方案Robust
  5. w ndows7防火墙文件名,Windows7中的防火墙是什么? 爱问知识人
  6. java中的复合数据类型是什么_【填空题】类是Java中的一种重要的复合数据类型,是组成Java程序的基本要素。一个类的实现包括两部分:____和_____....
  7. java 微信转账 ca_error_C#关于微信红包开发问题:CA证书出错,请登录微信支付商户平台下载证书...
  8. opencv 训练人脸对比_【项目案例python与人脸识别】基于OpenCV开源计算机视觉库的人脸识别之python实现...
  9. windows系统禁止更改服务启动类型_Win10系统关闭自动更新方法
  10. java label api_使用python API进行的培训作为Java API中LabelImage模块的输入?