如果一个表中的字段,设置了 unique key 或者 primary key,那么该字段下的值,必须是唯一的。
插入新数据时,直接使用 insert into
语句,如果出现了重复的数据,违反了唯一性约束,那么就会抛出异常。所以我们可以根据需求选择合适的插入语句。
新建一张 tb_user 表,将 user_id 作为主键,idCard为唯一索引
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for tb_user
-- ----------------------------
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
`user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',
`username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户姓名',
`id_card` varchar(18) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`user_id`) USING BTREE,
UNIQUE INDEX `un_id_card`(`id_card`) USING BTREE COMMENT '身份证号唯一'
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tb_user
-- ----------------------------
INSERT INTO `tb_user` VALUES (1, '张三', '370000199901016666');
INSERT INTO `tb_user` VALUES (2, '李四', '370000199901016667');
INSERT INTO `tb_user` VALUES (3, '王五', '370000199901016668');
SET FOREIGN_KEY_CHECKS = 1;
insert into
适用出现重复异常,希望捕获异常重复则报错,不重复则插入。
当插入新数据时,如果数据有重复,违反唯一性约束,则报错。如果没有重复数据,则执行插入操作。
INSERT INTO tb_user ( user_id, username, id_card )
VALUES
( 3, "赵六", '370000199901016669' )
insert ignore into
适用出现重复异常,希望保存旧纪录,忽略新纪录重复则忽略,不重复则插入
当插入数据时,如果数据有重复,违反了唯一性约束,则忽略错误,只以警告形式返回,不执行此SQL语句。如果没有重复性问题,则执行插入操作。
INSERT IGNORE INTO tb_user ( user_id, username, id_card )
VALUES
( 3, "赵六", '370000199901016669' )
insert into ... on duplicate key update
适用出现重复异常,希望更新指定字段重复则更新指定字段,不重复则插入
当插入数据时,如果唯一性校验出现重复问题,则在原有记录的基础上,更新指定字段内容,其他字段内容保留。如果没有重复性问题,则执行插入操作。
INSERT INTO tb_user ( user_id, username, id_card )
VALUES
( 3, "赵六", '370000199901016669' )
ON DUPLICATE KEY UPDATE username = "赵六"
查看表的内容会发现,user_id 和 id_card 没有发生改变,username由 王五 变成了 赵六。
注意(借鉴我舍友大炮儿的文章):
如果插入一条数据时,主键和唯一性约束都存在与表中,但是主键确定的数据和唯一性约束确定的数据不是同一条(如果出现这种情况,说明插入的数据有问题,此处为假设),此时 update 的数据为主键确定的那一条
如果执行的为 insert 语句,返回: Affected rows: 1
如果为 update 语句,返回:Affected rows: 0 或 Affected rows: 2(此处影响的行数仅代表执行的是什么操作)
replace into
适用出现重复异常,希望删除旧记录,插入新记录重复则先删除再插入新数据,不重复则插入
replace into 表示插入或替换数据,当插入数据时,如果唯一性校验出现重复问题,删除旧记录,然后插入新的记录。如果没有重复性问题,那么执行插入操作,效果和 insert into 是一样的。
REPLACE INTO tb_user ( user_id, username, id_card )
VALUES ( 3, "王五", '370000199901016669' )