首页 > 数据库 >mysql与lightdb中的insert on duplicate/replace

mysql与lightdb中的insert on duplicate/replace

时间:2023-05-21 21:05:46浏览次数:45  
标签:insert name UPDATE replace duplicate user file id

最近看pg中insert的实现源码,看到on conflict的excluded优点疑惑,顺带总结下mysql和pg中已存在更新、不存在插入的差异(注:oracle是merge into实现)。

在mysql中的insert on duplicate和lightdb的on conflict是等价的。

逻辑都是基于唯一约束进行已存在则更新,否则插入。

insert record
IF
  exist duplicate record
THEN
  do something on duplicated rows
ELSE
  do nothing
END IF

mysql示例

create table t1
(
    id bigint primary key auto_increment,
    a  integer unique,
    b  integer default 999
);
INSERT INTO test_insert_on_dup_update(id, a)
VALUES (1, 1);
INSERT INTO test_insert_on_dup_update(id, a)
VALUES (5, 5);
INSERT INTO test_insert_on_dup_update(id, a)
VALUES (10, 10);

insert into t1(a,b) values(1,199) on duplicate update b = 1;

  如果插入的记录与a跟b上的索引值都发生了冲突,且发生冲突的记录有多条会怎么样呢?

into t1(id, a) values(1,5) on duplicate update b = 1;

  因为a=1跟b=5都存在,这个时候有两行记录与即将插入的记录有冲突。按照前面介绍的规则来看,貌似id=1跟a=5这两条记录的b都会被更新成1。但事实是只有一条有冲突的记录会应用on duplicate后面的子句。而这条被命中记录就是在所有满足条件的记录中,其id值在聚集索引叶节点的链表中最靠前的那条记录。在本例中也就是id=1的那条记录。该sql的实际效果等价于:

set b=1 where id=1 or a=5 limit 1;

lightdb实例

create table meta_data (
        id serial,
        user_id varchar(128) DEFAULT NULL,
        file_name varchar(1024) DEFAULT NULL,
        file_path varchar(1024) DEFAULT NULL,
        update_time TIMESTAMP DEFAULT NULL,
        UNIQUE (user_id,file_name)
    );


postgres=# d meta_data
                                      Table "public.meta_data"
   Column    |            Type             |                       Modifiers                        
-------------+-----------------------------+--------------------------------------------------------
 id          | integer                     | not null default nextval('meta_data_id_seq'::regclass)
 user_id     | character varying(128)      | default NULL::character varying
 file_name   | character varying(1024)     | default NULL::character varying
 file_path   | character varying(1024)     | default NULL::character varying
 update_time | timestamp without time zone | 
Indexes:
    "meta_data_user_id_file_name_key" UNIQUE CONSTRAINT, btree (user_id, file_name)

INSERT INTO meta_data (
               user_id,
               file_name,
               file_path,
               UPDATE_TIME )
     VALUES ( 'user_id01',
              'file_name01',
              '/usr/local/file_name01',
              now())
ON CONFLICT (user_id, file_name) DO UPDATE SET file_path = EXCLUDED.file_path, UPDATE_TIME = EXCLUDED.UPDATE_TIME;    

INSERT INTO meta_data (
               user_id,
               file_name,
               file_path,
               UPDATE_TIME )
     VALUES ( 'user_id02',
              'file_name02',
              '/usr/local/file_name02',
              now())
ON CONFLICT (user_id, file_name) DO UPDATE SET file_path = EXCLUDED.file_path, UPDATE_TIME = EXCLUDED.UPDATE_TIME;
=================
INSERT INTO meta_data (
               user_id,
               file_name,
               file_path,
               UPDATE_TIME )
     VALUES ( 'user_id02',
              'file_name02',
              '/usr/local/file_name03',
              now())
ON CONFLICT (user_id, file_name) DO UPDATE SET file_path = EXCLUDED.file_path, UPDATE_TIME = EXCLUDED.UPDATE_TIME;
Insert on meta_data  (cost=0.00..0.02 rows=0 width=0)
  Conflict Resolution: UPDATE
  Conflict Arbiter Indexes: meta_data_user_id_file_name_key
  ->  Result  (cost=0.00..0.02 rows=1 width=1318)

http://events.jianshu.io/p/57f262e3a07d replace会导致自增键增加,insert on duplicate不会。

https://www.sjkjc.com/postgresql/insert-on-conflict/

  在pg中,如果表上定义了主键或多个唯一索引,是通过resolve_unique_index_expr函数先得到where字段列表,然后在plan时确定用哪个索引进行唯一性判断。

  如果有多个符合条件的索引,通常是被选中用来过滤记录的索引的key的那条记录被修改,而不是多条都被修改。

 http://www.light-pg.com/docs/lightdb/current/sql-insert.html

LightDB Enterprise Postgres--金融级关系型数据库,更快、更稳、更懂金融!



标签:insert,name,UPDATE,replace,duplicate,user,file,id
From: https://blog.51cto.com/zhjh256/6320191

相关文章

  • postgres 错误duplicate key value violates unique constraint 解决方案
    出错代码tortoise.exceptions.IntegrityError:duplicatekeyvalueviolatesuniqueconstraint"word_bank2_pkey"原文连接分析bugpostgres出现该问题着实没仔细看数据表序列ID,、出现的原因是:以word_bank2表为列子.id是唯一的且id在数据库中是自增的.而现在数据库中存......
  • 路由导航报错:NavigationDuplicated: Avoided redundant navigation to current locati
    跳转页面时候,重复点击菜单引起路由重复报错;点击按钮跳转到同一个或当前的路径会报错。为每一个Promise添加一个回调函数this.$router.push({name:'Cats',},()=>{})修改VueRouter原型对象上的push/replace方法在router/index.js文件中添加如下代码//获取原型对......
  • Duplicate class androidx.lifecycle.ViewModelLazy found in modules lifecycle-view
    AS版本:AndroidStudioBumblebee|2021.1.1Patch1Build#AI-211.7628.21.2111.8139111,builtonFebruary2,2022Runtimeversion:11.0.11+9-b60-7590822amd64VM:OpenJDK64-BitServerVMbyOracleCorporationWindows1010.0GC:G1YoungGeneration,G1OldGene......
  • Commonly Used Prompts for Reducing Duplicate Rate
    Simplerewrite:Tryhardtorewritethefollowingcontent,makesurethemeaningisthesameastheoriginalmeaningbutjusttrytousedifferentwordsespeciallyformalwords:Rewriteabstractorsomecopiedtextsfromapaper:Rewritethefollowing......
  • MySQL8JSON数组函数之json_array_append、json_array_insert
    json_array_append、json_array_insert顾名思义就是向数组中追加和插入值,因为没有找到合适的例子,所以就使用官方的例子进行说明1、json_array_append向指定的位置后追加值,查询和修改的函数如下所示:updatetest_jsonsettest_json_array=json_array_append(test_json_array,......
  • 记一个 Duplicate class kotlin-stblib vs kotlin-stdlib-jdk7/8 编译问题引发的案例
    某天将项目kotlin版本升级到了1.8.0,然后编译报错了,Duplicateclasskotlin-stblibvskotlin-stdlib-jdk7/8然后开始寻求解决方案...Duplicateclasskotlin-stblibvskotlin-stdlib-jdk7/8kotlin-stdlibkotlin1.8.0基于JVM1.8编译,不再支持JVM1.6和1.7。后续不......
  • 【mysql】类似replace 存在更新,否则插入的几种方式
    我们在向数据库里插入数据的时候,会遇到要将原有主键或者unique索引所在记录更新的情况,而如果没有主键或者unique索引冲突的时候,直接执行插入操作。这种情况下,有三种方式执行:1.直接直接每条select,判断,然后insert,毫无疑问,这是最笨的方法了,不断的查询判断,有主键或索引冲突,执......
  • location.href和location.replace的区别
    情景比如支付过程中或者使用商品的优惠券,而使用这张优惠券需要取请求一个第三方的地址,中间会有一次跳转。若使用window.location.href=“url”,按流程操作是没问题的,但是如果用户点击返回,则无法跳回原本的提交订单的页面,会一直进行重复请求,造成程序出错。所以,必须替换成wind......
  • ubuntu apt 安装报错:Media change: please insert the disc labeled 'Ubuntu 20.04.5
    前言如果你在Ubuntu上使用apt安装软件包时遇到"Mediachange:pleaseinsertthedisclabeled..."的错误消息,这通常是因为apt源列表中包含CD/DVD源,但你的系统中没有插入相应的安装介质(CD或DVD)。解决检查/etc/apt/sources.list文件中,是否出现CD/DVD源。类似d......
  • Postgresql insert on conflict笔记
    描述针对数据写入时有主键冲突的情况,INSERTONCONFLICT语法可以将冲突主键的INSERT行为转换为UPDATE行为,从而实现冲突主键的覆盖写入。该特性又称UPSERT覆盖写,与MySQL的REPLACEINTO类似。[WITH[RECURSIVE]with_query[,...]]INSERTINTOtable_name[ASalias][......