假设有一张demo表,主键为id,唯一索引是code
create table demo
(
id int auto_increment,
name int null,
gender int null,
age int null,
code int null,
constraint demo_pk
primary key (id)
);
create unique index demo_code_uindex
on demo (code);
replace into 会根据唯一索引或主键进行判断,如果存在则覆盖写入字段,如果不存在则新增。
此方法有坑,如果主键是自增的,且通过唯一索引来进行操作时,主键会变更,该方法底层是先进性delete,在insert
如果有子表依赖的话不建议使用。
replace into 事例
REPLACE INTO demo(id, name, gender, age, code) VALUES (1,'1',1,1,1)
通过主键修改,此时没有任何问题,id还是1
当我们通过唯一索引code来更改。
REPLACE INTO demo(name, gender, age, code) VALUES ('1',1,1,1)
没执行一次 主键id都会自增。
on duplicate key 如果遇到重复的唯一索引则会进行update,否则进行新增,没有replcae的坑,不会先进行delete 在进行 insert
on duplicate key 事例:
INSERT INTO demo(name, gender, age, code)
VALUES ('1',
1,
2,
2)
ON DUPLICATE KEY UPDATE name = values(name),
gender = values(gender),
age = values(age),
code = if(values(code) = 1,values(code), code)
无论执行多少次,主键值都是不会变的。
但是此方法也有坑,如果表中不止一个唯一索引的话,在特定版本的mysql中容易产生dead lock(死锁)
当mysql执行INSERT ON DUPLICATE KEY的 INSERT时,存储引擎会检查插入的行是否会产生重复键错误。如果是的话,它会将现有的
行返回给mysql,mysql会更新它并将其发送回存储引擎。当表具有多个唯一或主键时,此语句对存储引擎检查密钥的顺序非常敏感。根据这个顺序,
存储引擎可以确定不同的行数据给到mysql,因此mysql可以更新不同的行。存储引擎检查key的顺序不是确定性的。例如,InnoDB按照索引添加到
表的顺序检查键。
insert … on duplicate key 在执行时,innodb引擎会先判断插入的行是否产生重复key错误,如果存在,在对该现有的行加上S(共享锁)锁,如果返回该行数据给mysql,然后mysql执行完duplicate后的update操作,然后对该记录加上X(排他锁),最后进行update写入。
如果有两个事务并发的执行同样的语句,那么就会产生death lock
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
小编已加密:aHR0cHM6Ly9kb2NzLnFxLmNvbS9kb2MvRFVrVm9aSGxQZUVsTlkwUnc==出于安全原因,我们把网站通过base64编码了,大家可以通过base64解码把网址获取下来。