OceanBase数据库使用 INSERT 语句违反唯一约束冲突解决办法及两者差异分析

当在OceanBase数据库上创建带有唯一性约束的表,在向表中插入唯一性约束的冲突的数据时会提示因违反唯一性约束报错,OceanBase在其官网上提供了两种解决策略,但其官网并未详细说明两种策略的差异,于是早上对两种策略进行一些测试,对比下两者的差异。

>如在测试中哪有错误的地方,还望对此熟悉的大牛多多指正,不胜感激。

一、创建带有唯一性约束表

复制代码
[admin@obproxy-node ~]$ obclient -h 10.110.3.152 -uroot@sys#obcluster -pob@Passwd -P2883 -c -A oceanbase
Welcome to the OceanBase.  Commands end with ; or \g.
Your OceanBase connection id is 36
Server version: OceanBase_CE 4.0.0.0 (r100000282022112511-dd289d2407609a88b1fcdf2be9e7c384cb8e19d0) (Built Nov 25 2022 11:58:08)
 
Copyright (c) 2000, 2018, OceanBase and/or its affiliates. All rights reserved.
 
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
 
obclient [oceanbase]> use test;
Database changed
obclient [test]> create table customer(
    ->     id number not null primary key,
    ->     name varchar(10) not null,
    ->     salary number,
    ->     create_time datetime not null default current_timestamp
    ->  );
Query OK, 0 rows affected (0.132 sec)
 
obclient [test]> desc customer;
+-------------+---------------+------+-----+-------------------+-------+
| Field       | Type          | Null | Key | Default           | Extra |
+-------------+---------------+------+-----+-------------------+-------+
| id          | decimal(10,0) | NO   | PRI | NULL              |       |
| name        | varchar(10)   | NO   |     | NULL              |       |
| salary      | decimal(10,0) | YES  |     | NULL              |       |
| create_time | datetime      | NO   |     | CURRENT_TIMESTAMP |       |
+-------------+---------------+------+-----+-------------------+-------+
4 rows in set (0.011 sec)

二、插入重复主键数据

复制代码
-- 当表上有唯一性约束的时候,插入相同的记录,数据库会报错。提示因有主键冲突,数据未插入
obclient [test]> insert into customer(id, name, salary)  values (1,'zhangsan', 3000) ,(1,'lisi', 10003);
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
obclient [test]> select * from customer;
Empty set (0.004 sec)

三、解决办法

根据OceanBase官网资料,提供两种避免约束冲突的办法,分别是INSERT IGNORE INTO和INSERT INTO ON DUPLICATE KEY UPDATE 两种办法可进行避免。

  • 通过 INSERT IGNORE INTO 避免约束冲突,IGNORE 关键字可以忽略由于约束冲突导致的 INSERT 失败的影响。

  • 通过 INSERT INTO ON DUPLICATE KEY UPDATE 避免约束冲突,可以指定对重复主键或唯一键的后续处理
    说明

  • 指定 ON DUPLICATE KEY UPDATE:当要插入的主键或唯一键有重复时,会用配置值替换待插入的值。

  • 不指定 ON DUPLICATE KEY UPDATE:当要插入的主键或唯一键有重复时,插入报错

复制代码
obclient [test]> insert ignore into customer(id, name, salary)  values (1,'zhangsan', 3000) ,(1,'lisi', 10003);
Query OK, 1 row affected (0.011 sec)
 
obclient [test]> select * from customer;
+----+----------+--------+---------------------+
| id | name     | salary | create_time         |
+----+----------+--------+---------------------+
|  1 | zhangsan |   3000 | 2022-12-20 10:08:17 |
+----+----------+--------+---------------------+
1 row in set (0.003 sec)
 
obclient [test]> insert into customer(id, name, salary) values (3,'zhaowu', 10003),(3, 'wangliu', 10004) on duplicate key update name=values(name);
Query OK, 3 rows affected (0.011 sec)
Records: 2  Duplicates: 1  Warnings: 0
 
obclient [test]> select * from customer;
+----+----------+--------+---------------------+
| id | name     | salary | create_time         |
+----+----------+--------+---------------------+
|  1 | zhangsan |   3000 | 2022-12-20 10:08:17 |
|  3 | wangliu  |  10003 | 2022-12-20 10:08:59 |
+----+----------+--------+---------------------+
2 rows in set (0.014 sec)
 
obclient [test]> insert into customer(id, name, salary) values (5,'xiaoming', 10003),(6, 'xiaowang', 10004) on duplicate key update name=values(name);
Query OK, 2 rows affected (0.012 sec)
Records: 2  Duplicates: 0  Warnings: 0
 
obclient [test]> select * from customer;
+----+----------+--------+---------------------+
| id | name     | salary | create_time         |
+----+----------+--------+---------------------+
|  1 | zhangsan |   3000 | 2022-12-20 10:08:17 |
|  3 | wangliu  |  10003 | 2022-12-20 10:08:59 |
|  5 | xiaoming |  10003 | 2022-12-20 10:10:09 |
|  6 | xiaowang |  10004 | 2022-12-20 10:10:09 |
+----+----------+--------+---------------------+
4 rows in set (0.005 sec)
 
obclient [test]> insert into customer(id, name, salary) values (7,'huawei', 10003),(7, 'aiguo', 10004) on duplicate key update name=values(name);
Query OK, 3 rows affected (0.006 sec)
Records: 2  Duplicates: 1  Warnings: 0
 
obclient [test]> select * from customer;
+----+----------+--------+---------------------+
| id | name     | salary | create_time         |
+----+----------+--------+---------------------+
|  1 | zhangsan |   3000 | 2022-12-20 10:08:17 |
|  3 | wangliu  |  10003 | 2022-12-20 10:08:59 |
|  5 | xiaoming |  10003 | 2022-12-20 10:10:09 |
|  6 | xiaowang |  10004 | 2022-12-20 10:10:09 |
|  7 | aiguo    |  10003 | 2022-12-20 10:12:19 |
+----+----------+--------+---------------------+
5 rows in set (0.001 sec)
 
obclient [test]> insert into customer(id, name, salary) values (8,'xiaoA', 10003),(8, 'xiaoB', 10004),(8, 'xiaoC', 10005) on duplicate key update name=values(name);
Query OK, 5 rows affected (0.009 sec)
Records: 3  Duplicates: 2  Warnings: 0
 
obclient [test]> select * from customer;
+----+----------+--------+---------------------+
| id | name     | salary | create_time         |
+----+----------+--------+---------------------+
|  1 | zhangsan |   3000 | 2022-12-20 10:08:17 |
|  3 | wangliu  |  10003 | 2022-12-20 10:08:59 |
|  5 | xiaoming |  10003 | 2022-12-20 10:10:09 |
|  6 | xiaowang |  10004 | 2022-12-20 10:10:09 |
|  7 | aiguo    |  10003 | 2022-12-20 10:12:19 |
|  8 | xiaoC    |  10003 | 2022-12-20 10:35:46 |
+----+----------+--------+---------------------+
6 rows in set (0.002 sec)

复制

四、差异分析

通过反复测试,发现INSERT IGNORE INTO和INSERT INTO ON DUPLICATE KEY UPDATE在使用上也有个小小的差异,就是使用INSERT IGNORE INTO插入带有唯一性约束数据时,会插入第一条value后的语句, 而使用INSERT INTO ON DUPLICATE KEY UPDATE插入带有唯一性约束数据时会插入最后一条value的语句。

相关推荐
前端世界32 分钟前
用Python打造智能成绩分析系统:从异常处理到断言验证的全流程实战
服务器·数据库·python
JavaArchJourney1 小时前
数据库分库分表
数据库·分布式
ZhangBlossom1 小时前
【Java】EasyExcel实现导入导出数据库中的数据为Excel
java·数据库·excel
不见长安在2 小时前
redis集群下如何使用lua脚本
数据库·redis·lua
可观测性用观测云2 小时前
阿里云 RDS PostgreSQL 可观测最佳实践
数据库
馨谙2 小时前
SELinux 文件上下文管理详解:从基础到实战
jvm·数据库·oracle
ClouGence2 小时前
百草味数据架构升级实践:打造 Always Ready 的企业级数据平台
大数据·数据库·数据分析
川石课堂软件测试3 小时前
Python | 高阶函数基本应用及Decorator装饰器
android·开发语言·数据库·python·功能测试·mysql·单元测试
.又是新的一天.3 小时前
08-Jmeter数据驱动、数据库的操作、命令行执行方式
数据库·jmeter
LilySesy4 小时前
ABAP+如果在join的时候需要表1的字段某几位等于表2的字段的某几位,需要怎么做?
服务器·前端·数据库·sap·abap·alv