Home > Database > Mysql Tutorial > body text

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

WBOY
Release: 2016-06-01 13:32:09
Original
1255 people have browsed it

bitsCN.com

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

 

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

 

方法一:

使用

 INSERT INTO ON ... DUPLICATE KEY UPDATE ...
Copy after login

表的创建如下:

[sql] 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;  
Copy after login

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

[sql] 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;  
Copy after login

该条插入语句的含义是:向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。

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

[sql] 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;  
Copy after login

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

[sql] Specified key was too long; max key length is 1000 bytes  
Copy after login

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

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

看这里

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

方法二:

使用dual虚拟表来实现。

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

[sql] 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;  
Copy after login

插入语句则是形如:

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

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

[sql] 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');  
Copy after login

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

[sql] UPDATE `test_table` SET   `value1` = `value1` + 1, `value2` = `value2` + 2, `value3` = `value3` + 3  WHERE `val1` = 'abcd' AND `val2` = 0 AND `val3` = 'xyz';  
Copy after login

 

 

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

 

bitsCN.com
Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template