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

原创 2013年07月10日 19:28:59

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  





博主所有文章已转自私人博客 Joe 的个人博客,谢谢关注!





mysql 如果数据不存在,则插入新数据,否则更新的实现方法

CREATE TABLE `table_test` ( `my_key` int(11) NOT NULL default '0', `value` varchar(21) NOT NULL d...
  • zxk364961978
  • zxk364961978
  • 2017年05月09日 13:41
  • 2017

mysql有数据就更新,没数据就插入

原文链接:sql插入数据已经存在,则执行update更新-mysql教程-数据库-壹聚教程网 http://www.111cn.net/database/mysql/76509.htm 在很多...
  • qq_26222859
  • qq_26222859
  • 2016年06月30日 11:28
  • 867

MySQL 记录不存在时插入 记录存在则更新的实现方法

INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1; INSERT 中 ON DUPLICATE KEY...
  • u011403672
  • u011403672
  • 2017年04月25日 10:18
  • 262

MySQL存在时更新,否则新增

当参数与表中UNIQUE索引重复时执行update,否则执行insert,适用于批量处理 MySQL语句: INSERT INT table_name (field1_name,field...
  • sanzhongguren
  • sanzhongguren
  • 2017年07月10日 17:01
  • 432

MySQL insert 存在则更新,不存在则插入

有时候我们需要用一个表去记录某些经常变动的数据,比如现在有一个表,是用来记录页面被访问的IP和访问次数的。你可以用传统的方法,只需要一个IP字段,只要客户端访问,就把IP写入表中。查询的时候用grou...
  • qingguiyu
  • qingguiyu
  • 2016年12月30日 13:07
  • 3559

mysql 有则更新无则插入

表结构如下: CREATE TABLE `test` ( `name` varchar(255) DEFAULT NULL, `id` int(11) NOT NULL AUTO_INCRE...
  • qq_27292113
  • qq_27292113
  • 2017年10月25日 14:01
  • 388

mysql 存在则更新 不存在则插入 SQL语句

[源] = [http://www.jb51.net/article/23059.htm] 代码如下: INSERT table (auto_id, auto_name) va...
  • Cashey1991
  • Cashey1991
  • 2011年10月16日 09:35
  • 4117

Mysql—实现批量插入,存在就更新,不存在就插入

Mysql插入数据的SQL语句主要有: 1、insert into表示插入数据,数据库会检查主键,如果出现重复会报错; 2、replace into表示插入替换数据,需求表中有PrimaryKey...
  • nxstack
  • nxstack
  • 2017年06月21日 17:06
  • 1867

MySQL插入数据时,如果记录不存在则insert,如果存在则update

MySQL 当记录不存在时insert,当记录存在时更新 网上基本有三种解决方法。 第一种: 示例一:insert多条记录 假设有一个主键为 client_id 的 clients 表,可以使...
  • AAA123524457
  • AAA123524457
  • 2015年06月19日 09:47
  • 18210

MySql_插入记录时,存在就更新(或不做任何动作),不存在就添加

今天本码农在批量插入数据的时候,遇到一个问题,由于数据是经常更新的,但是又不想出现冗余数据,所以我希望达到的目的是:插入一条数据的时候,先判断是否存在这条记录,如果存在,我就更新这条记录,不存在就插入...
  • BuptZhengChaoJie
  • BuptZhengChaoJie
  • 2016年03月27日 18:37
  • 13471
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:mysql处理存在则更新,不存在则插入(多列唯一索引)
举报原因:
原因补充:

(最多只允许输入30个字)