目录
[1. INSERT INTO](#1. INSERT INTO)
[2. INSERT IGNORE INTO](#2. INSERT IGNORE INTO)
[3. INSERT INTO ... ON DUPLICATE KEY UPDATE](#3. INSERT INTO ... ON DUPLICATE KEY UPDATE)
[4. REPLACE INTO](#4. REPLACE INTO)
MySQL提供了多种数据插入方式,每种方式在处理唯一键冲突时的行为不同,同时也涉及不同的锁机制。
1. INSERT INTO
INSERT INTO
是标准的数据插入命令,用于在表中插入新行。
特点: 无就插入、有就报错
- 插入新行。
- 如果新行违反唯一键约束,则会产生错误并中止插入。
锁:
- 通常获取行锁,锁定被插入的行。
- 如果使用了事务隔离级别(可重读),可能还会涉及间隙锁,以防止幻读。
- 正常情况下,如果按照唯一键顺序插入,死锁风险较低。
2. INSERT IGNORE INTO
INSERT IGNORE INTO
在插入时忽视唯一键约束冲突。
特点: 无就插入,有就忽略当前行
- 插入新行,但如果违反唯一键约束则忽略错误。
- 不会因为唯一键冲突而中止操作。
锁:
- 类似
INSERT INTO
,获取行锁。 - 由于忽略冲突,可能减少锁竞争,降低死锁风险。
3. INSERT INTO ... ON DUPLICATE KEY UPDATE
在唯一键冲突时,更新现有的冲突行。
特点: 无就插入,有就更新
- 如果没有唯一键冲突则插入,否则更新冲突行。
- 避免了插入错误,提供了一种"尝试插入否则更新"的机制。
锁:
- 获取行锁来插入或更新数据。
- 如果涉及更新,可能会获取间隙锁,尤其在高并发环境下。
- 更新操作增加了死锁的潜在风险。
4. REPLACE INTO
如果存在唯一键冲突,则删除旧行后插入新行。
特点: 无就插入,有就先删后插,
- 插入前,先检查唯一键冲突,有则删除冲突行。
- 实质上是一个删除再插入的操作。
锁:
- 获取行锁以删除和插入数据。
- 可能会获取间隙锁,尤其是在删除旧行时。
- 由于涉及删除操作,可能会触发更复杂的锁机制,增加死锁风险。
总结
不同的插入命令在处理唯一键冲突时具有不同的行为。在锁的层面,INSERT INTO
和INSERT IGNORE INTO
通常涉及行锁,而INSERT INTO ... ON DUPLICATE KEY UPDATE
和REPLACE INTO
可能会涉及间隙锁,特别是在并发环境下。间隙锁是为了保持事务隔离性而设置的,它锁定了一个范围,防止其他事务插入到这个范围内。每种方式在并发场景下都有可能产生死锁,尤其是在多个事务试图以不同顺序访问同一组数据时。因此,设计数据库操作时需要考虑锁的影响,合理安排事务顺序,以减少死锁的可能性。