plaintext自动换行:关放大阅读展开代码-- 切换到 test 数据库 USE test; -- 如果表已存在,先删除,方便重复测试 DROP TABLE IF EXISTS user_profiles; -- 创建测试表 CREATE TABLE user_profiles ( id INT PRIMARY KEY, username VARCHAR(50) NOT NULL, email VARCHAR(100) NOT NULL, followers INT DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uk_email (email) ); INSERT INTO user_profiles (id, username, email, followers) VALUES (101, 'Alice', 'alice@example.com', 1500), (102, 'Bob', 'bob@example.com', 800), (103, 'Charlie', 'charlie@example.com', 3200); INSERT INTO user_profiles (id, username, email, followers) VALUES (102, 'Robert', 'robert@example.com', 250); REPLACE INTO user_profiles (id, username, email, followers) VALUES (103, 'Charles', 'charlie@example.com', 3500); INSERT INTO user_profiles (id, username, email, followers) VALUES (102, 'Bobby', 'bob@example.com', 950) ON DUPLICATE KEY UPDATE username = VALUES(username), followers = followers + 50; -- 注意这里的不同写法
总结与比较
| 特性 | INSERT INTO |
REPLACE INTO |
INSERT INTO ... ON DUPLICATE KEY UPDATE |
|---|---|---|---|
| 处理冲突 | 失败并报错 | 删除旧行,插入新行 | 更新旧行的指定字段 |
| 操作本质 | 纯插入 | DELETE + INSERT |
INSERT or UPDATE |
| 对未指定列的影响 | 无 | 如果有默认值,会重置为默认值 | 无影响,保持原样 |
对 AUTO_INCREMENT ID 的影响 |
正常增加 | 可能会消耗一个ID(删除旧行,插入新行) | 如果是更新操作,则不影响ID |
| 触发器 | INSERT 触发器 |
DELETE 和 INSERT 触发器 |
如果插入,触发INSERT;如果更新,触发UPDATE |
| 性能 | - | 通常性能较低,因为它涉及删除和插入,开销更大 | 通常性能更高,因为它只做原地更新 |
| 适用场景 | 确保数据唯一性,不希望覆盖 | 需要用新数据完全覆盖旧记录的场景 | 最常用,用于“存在即更新,不存在即插入”的逻辑 |
一句话总结:
INSERT INTO 来保证数据的纯粹性,防止意外覆盖。REPLACE INTO,想清楚“删除重建”的副作用是否可以接受。INSERT INTO ... ON DUPLICATE KEY UPDATE 是最高效、最安全、最常用的选择。本文作者:hedeoer
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!