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的语句。

相关推荐
摇滚侠7 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 12
java·数据库·笔记
川石课堂软件测试8 小时前
学习软件测试需掌握的一些知识
数据库·python·sql·功能测试·网络协议·mysql·http
2501_937767169 小时前
自建 SQL 数据库定时备份踩坑复盘与落地思路
数据库·sql
silvamux_10 小时前
10款模型写种草笔记:可发布性、返工来源与成本数据缺口复盘
java·数据库·笔记
I Am a robert girl12 小时前
从 GameHorizon 拆解多时间尺度游戏评测:数据管线、离线基准与在线回放的三层设计
数据库·游戏·多时间尺度·数据管线·游戏评测·离线基准·在线回放
躺柒12 小时前
读数据安全架构设计与实践17安全架构案例(下)
数据库·安全·零信任·安全架构·防火墙·无边界
SelectDB12 小时前
实时更新排错现场:导入了却查到旧数据,和 FINAL 越加越慢的两条路
大数据·数据库·数据分析
SelectDB13 小时前
拿 Planet 的账单一行行对下来,我总结出三个可自查的校验点
大数据·数据库·数据分析
SelectDB13 小时前
Apache Doris + Vane:让多模态数据进入业务分析
大数据·数据库·数据分析
pjj1985415 小时前
ClickHouse 与 Doris 数据库技术梳理:看懂分析型数据库
数据库·clickhouse