表结构:
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET latin1 DEFAULT NULL,
`code` varchar(10) CHARACTER SET latin1 DEFAULT NULL,
`quota_owner` varchar(32) CHARACTER SET latin1 DEFAULT NULL COMMENT '指标owner',
`is_deleted` int(1) DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `name_code_uniq_index` (`name`,`code`,`is_deleted`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8
其中name, code,is_deleted 做了唯一索引,插入时,不允许这三列插入重复记录,下面有4种方法
第一种用on duplicate key update,如果存在,则更新
insert into test(name,code,quota_owner)
values('qq','A4','') on DUPLICATE key update quota_owner='jason' ;
第二种用replace into,如果存在则覆盖
replace into test(name,code,quota_owner) values('qq','A4','2');
第三种 insert ignore into,如果存在不处理
insert IGNORE into test(name,code,quota_owner) values('qq','A4','1');
第四种与第三种效果一样,用not exists
insert into test(name,code,quota_owner)
select 'qq','A4','5' from dual where not exists(select name from test where name='qq' and code='A4')
上面是在mysql数据库层做的防止重复插入的处理,另外注意,如果在程序中使用synchronized之类的做并发处理,在单机上可以,但是如果部署到多台服务器,由于该锁的对象只属于当前jvm,其他机器不受影响,所以并不能防止重复插入。此时,需要使用分布式锁处理。另外mysql乐观锁的处理,只适用于更新,对这种插入的操作没用。
特别说明:在MYSQL中UNIQUE 索引将会对null字段失效,也就是说(a字段上建立唯一索引):
insert into test(a) values(null)
insert into test(a) values(null)
是可以重复插入的(联合唯一索引也一样)。