前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >insert into,insert ignore into, on duplicate key update,replace into-唯一键约束

insert into,insert ignore into, on duplicate key update,replace into-唯一键约束

原创
作者头像
IT工作者
发布2022-01-10 16:45:28
发布2022-01-10 16:45:28
55000
代码可运行
举报
文章被收录于专栏:程序技术知识程序技术知识
运行总次数:0
代码可运行

当MySQL表字段设置unique key或者primary key时,被约束的字段就必须是唯一的。新插入数据直接使用insert into,如果出现唯一性冲突,就会抛出异常。我们可以根据需求选择合适的插入语句。

为了演示,我们先新建一张user表,SQL语句如下,其中user_id为主键,username为唯一索引

代码语言:javascript
代码运行次数:0
复制
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `user_id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '用户id',
  `username` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '用户名',
  `password` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '密码',
  `mobile_phone_number` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '手机号码',
  `email` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '邮箱',
  `delete_state` tinyint(1) UNSIGNED DEFAULT 0 COMMENT '用户状态,1表示删除,0表示未删除',
  `create_time` datetime(0) DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime(0) DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
  PRIMARY KEY (`user_id`) USING BTREE,
  UNIQUE INDEX `uk_username`(`username`) USING BTREE COMMENT '用户名唯一'
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'JourWon', '123456', '13800000000', 'a@163.com', 0, CURRENT_TIMESTAMP, NULL);
INSERT INTO `user` VALUES (2, '马云', '123456', '13800000011', 'b@163.com', 0, CURRENT_TIMESTAMP, NULL);
INSERT INTO `user` VALUES (3, '马化腾', '123456', '13800000022', 'c@163.com', 0, CURRENT_TIMESTAMP, NULL);
INSERT INTO `user` VALUES (4, '李彦宏', '123456', '13800000033', 'd@163.com', 0, CURRENT_TIMESTAMP, NULL);
INSERT INTO `user` VALUES (5, '任正非', '123456', '13800000044', 'e@163.com', 0, CURRENT_TIMESTAMP, NULL);
INSERT INTO `user` VALUES (6, 'Jobs', '123456', '13800000055', 'f@163.com', 0, CURRENT_TIMESTAMP, NULL);
INSERT INTO `user` VALUES (7, 'Bill Gates', '123456', '13800000066', 'g@163.com', 0, CURRENT_TIMESTAMP, NULL);
INSERT INTO `user` VALUES (8, 'Buffett', '123456', '13800000077', 'h@163.com', 0, CURRENT_TIMESTAMP, NULL);

SET FOREIGN_KEY_CHECKS = 1;

常用插入语句

insert into

当插入数据时,如果唯一性校验出现重复问题,则报错;

如果没有重复性问题,则执行插入操作。

简单总结:重复则报错,不重复则插入。

示例

代码语言:javascript
代码运行次数:0
复制
INSERT INTO `user`
VALUES
    ( 8, 'Buffett', '123456', '13800000077', 'aaaaa@163.com', 0, CURRENT_TIMESTAMP, NULL );

执行结果

代码语言:javascript
代码运行次数:0
复制
INSERT INTO `user`
VALUES
    ( 8, 'Buffett', '123456', '13800000077', 'aaaaa@163.com', 0, CURRENT_TIMESTAMP, NULL )
> 1062 - Duplicate entry '8' for key 'user.PRIMARY'
> 时间: 0.001s

insert ignore into

当插入数据时,如果唯一性校验出现重复问题,则忽略错误,只以警告形式返回,不执行此SQL语句;

如果没有重复性问题,则执行插入操作。

简单总结:重复则忽略,不重复则插入。

示例

代码语言:javascript
代码运行次数:0
复制
INSERT IGNORE INTO `user`
VALUES  ( 8, 'Buffett', '123456', '13800000077', 'aaaa@163.com', 0, CURRENT_TIMESTAMP, NULL );

执行结果

代码语言:javascript
代码运行次数:0
复制
INSERT IGNORE INTO `user`
VALUES
    ( 8, 'Buffett', '123456', '13800000077', 'aaaa@163.com', 0, CURRENT_TIMESTAMP, NULL )
> Affected rows: 0
> 时间: 0.001s

insert into … on duplicate key update

当插入数据时,如果唯一性校验出现重复问题,则在原有记录基础上,更新指定字段内容,其它字段内容保留;

如果没有重复性问题,则执行插入操作。

简单总结:重复则更新指定字段,不重复则插入

示例

代码语言:javascript
代码运行次数:0
复制
INSERT INTO `user` ( username, PASSWORD, mobile_phone_number, email )
VALUES
    ( 'Buffett', '123456', '13800000088', 'aaaa@163.com' ) 
    ON DUPLICATE KEY UPDATE mobile_phone_number = '13800000088';

执行结果

代码语言:javascript
代码运行次数:0
复制
INSERT INTO `user` ( username, PASSWORD, mobile_phone_number, email )
VALUES
    ( 'Buffett', '123456', '13800000088', 'aaaa@163.com' ) 
    ON DUPLICATE KEY UPDATE mobile_phone_number = '13800000088'
> Affected rows: 2
> 时间: 0.022s

表记录,mobile_phone_number更新了,update_time也有值了,但是user_id没有变

user_id username password mobile_phone_number email delete_state create_time update_time

8 Buffett 123456 13800000088 Buffett@163.com 0 2020-05-28 09:49:53 2020-05-28 10:04:30

replace into

replace into表示插入替换数据,当插入数据时,如果唯一性校验出现重复问题,删除旧记录,插入新记录;

如果没有重复性问题,则执行插入操作,效果和insert into是一样的。

简单总结:重复则先删除再插入新记录,不重复则插入

示例

代码语言:javascript
代码运行次数:0
复制
REPLACE INTO `user` ( username, PASSWORD, mobile_phone_number, email )
VALUES
    ( 'Buffett', '123456', '13800000099', 'aaaa@163.com' );

执行结果

代码语言:javascript
代码运行次数:0
复制
REPLACE INTO `user` ( username, PASSWORD, mobile_phone_number, email )
VALUES
    ( 'Buffett', '123456', '13800000099', 'aaaa@163.com' )
> Affected rows: 2
> 时间: 0.019s

表记录,user_id和mobile_phone_number变了,update_time变为了空

user_id username password mobile_phone_number email delete_state create_time update_time

10 Buffett 123456 13800000099 aaaa@163.com 0 2020-05-28 09:49:53

使用场景总结

如果出现重复异常,希望捕获异常,则使用insert into

如果出现重复异常,希望保存旧纪录,忽略新纪录,则使用insert ignore into

如果出现重复异常,希望更新指定字段,则使用insert into … on duplicate key update

如果出现重复异常,希望删除旧记录,插入新记录,则使用replace into

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档