REPLACE INTO的用法与INSERT很相似,最终在表中的目的是插入一行新的数据。不同的是,当插入时出现主键或者唯一索引冲突的时候,会删除原有记录,重新插入新的记录。因此,除非表具有主键或者唯一索引,否则使用REPLACE INTO无任何意义。
以下新建了一个表来进行测试,并添加触发检视REPLACE INTO是如何工作的:
CREATE TABLE `replace_into` ( `id` int(11) NOT NULL AUTO_INCREMENT, `uid` int(11) NOT NULL, `name` char(10) CHARACTER SET utf8 NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `unique_uid` (`uid`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=1334 DEFAULT CHARSET=utf8; CREATE TRIGGER `insert_before_trigger` BEFORE INSERT ON `replace_into` FOR EACH ROW insert into `trigger_log` (`id`,`table_name`,`action`) values(NULL,'replace_into','insert_before'); CREATE TRIGGER `insert_after_trigger` AFTER INSERT ON `replace_into` FOR EACH ROW insert into `trigger_log`(`id`,`table_name`,`action`) values(NULL,'replace_into','insert_after'); CREATE TRIGGER `update_after_trigger` AFTER UPDATE ON `replace_into` FOR EACH ROW insert into `trigger_log`(`id`,`table_name`,`action`) values(NULL,'replace_into','update_after'); CREATE TRIGGER `delete_after_trigger` AFTER DELETE ON `replace_into` FOR EACH ROW insert into `trigger_log`(`id`,`table_name`,`action`) values(NULL,'replace_into','delete_after');
插入一些测试数据后,执行REPLACE INTO
[SQL] replace into `replace_into` values (1333,313,'dd') 受影响的行: 2 时间: 0.036ms
可以发现,执行成功后受影响的行数为2,让我们来看看触发器的记录
第一步:尝试插入,但发现唯一性冲突,插入失败
第二步:删除表中唯一性冲突的旧记录
第三步:插入新的行
总结:REPLACE INTO会先删除原有的行,再插入新的行,如果为了偷懒这样写,会导致性能低下。还有一点,由于第三步插入了新的行,如果没有指定自增主键,那么自增ID也会随之改变。
INSERT … ON DUPLICATE KEY UPDATE在mysql 4.1版本以后开始支持,
执行语句:
[SQL] insert into `replace_into` values (NULL,313,'aaaaaaaaaa') ON DUPLICATE KEY UPDATE `name`='asd' 受影响的行: 2 时间: 0.043ms
看看触发器的记录:
第一步:尝试插入,但发现唯一性冲突,插入失败
第二步:执行更新语句
总结:使用INSERT … ON DUPLICATE KEY UPDATE,可以将原本3条sql语句整合成一条,而且不会造成delete旧数据。
时间: 2024-10-17 03:11:45