写点什么

KunlunBase 对 MySQL 私有 DML 语法的支持

作者:KunlunBase
  • 2022 年 7 月 12 日
  • 本文字数:2979 字

    阅读完需:约 10 分钟

前言

为了让 MySQL 的应用更为便捷地迁移到 KunlunBase,我们做了很多兼容 MySQL 的工作。


本篇章主要介绍 KunlunBase 现在已经支持的 MySQL 常用的私有 DML 语法,以及这些语法与原生 MySQL 的差异。

一、兼容 MySQL 的 insert ignore 语法

功能: 忽略违背唯一约束的新元组。


示例:


postgres -> create table t1(a int primary key, b int not null unique);CREATE TABLE# 违背唯一约束,不进行插入postgres -> insert ignore into t1(a,b) values (4,4);INSERT 0 1postgres -> insert ignore into t1(a,b) values (4,4);INSERT 0 0
复制代码


和原生 MySQL 的差异:


  • 只忽略唯一性约束,如果违背其他约束(例如分区约束、非 null 约束),则报错。


例如:


postgres -> insert ignore into t1(a,b) values (4,NULL);ERROR:  null value in column "b" violates not-null constraintDETAIL:  Failing row contains (4, null)
复制代码

二、兼容 MySQL 的 INSERT...ONDUPLICATE KEY UPDATE...语法

**功能:**插入数据;如果违背了某个唯一约束,则转变为更新操作,对其中一个冲突的元组进行更新。


示例:


postgres -> create table t1 (a int primary key, b int not null unique);CREATE TABLEpostgres -> insert into t1 values(3,3), (4,4);INSERT 0 2

# 插入的数据和已有的两个元组都冲突,但只更新了其中一个元组(3,3)postgres -> insert into t1 values(3,4) on duplicate key update b=2;INSERT 0 2postgres -> select * from t1; a | b---+--- 3 | 2 4 | 4
复制代码


和原生 MySQL 的差异:


  • 暂不支持在 ON DUPLICATE KEY UPDATE 子句中使用 VALUES()函数来引用新值,可以使用 excluded 虚拟表来代替。


例如:


postgres -> INSERT INTO t1 VALUES(3,0) ON DUPLICATE KEY UPDATE b = excluded.b;INSERT 0 2postgres -> select * from t1; a | b---+--- 3 | 0 4 | 4(2rows)postgres -> INSERT INTO t1 VALUES(3,0) ON DUPLICATE KEY UPDATE b=VALUES(b);ERROR:  syntax error at or near "VALUES"
复制代码


  • 往临时表批量写入多个新元组时,如果新元组之间存在唯一性冲突,则会报错(根本原因是临时表存在于计算节点,使用的不是 innodb 引擎)。


例如:


postgres -> create temp table t1(a int primary key, b int not null unique);CREATE TABLEpostgres -> INSERT INTO t1 VALUES(5,5), (5,6) ON DUPLICATE KEY UPDATE b = excluded.b;ERROR:  ON CONFLICT DO UPDATE command cannot affect row a secondtimeHINT:  Ensure that norows proposed for insertion within the same command have duplicate constrained values.postgres ->
复制代码


  • 临时表返回的影响行数的差异。即使更新前后的值相同,临时表返回的影响行数仍然大于 0。


例如:


postgres -> create temp table t1(a int primary key, b int not null unique);CREATE TABLEpostgres -> INSERT INTO t1 VALUES(5,5) ON DUPLICATE KEY UPDATE b=excluded.b;INSERT 0 1postgres -> INSERT INTO t1 VALUES(5,5) ON DUPLICATE KEY UPDATE b=excluded.b;INSERT 0 1
复制代码

三、兼容 mysql 的 replace into 语法

**功能:**插入元组;如果存在冲突的旧元组,则删除所有与之冲突的旧元组。


示例:


postgres -> create table t1(a int primary key, b int not null unique);CREATE TABLEpostgres -> insert into t1 values(3,3),(4,4);INSERT 0 2
postgres -> replace into t1 values(3,4);INSERT 0 3postgres -> select * from t1; a | b---+--- 3 | 4(1row)
复制代码


和原生 MySQL 的差异:


  • 往临时表批量写入多个新元组时,如果新元组之间存在唯一性冲突,则会报错(根本原因是临时表存在于计算节点,使用的不是 innodb 引擎)。


例如:


postgres -> create table t1(a int primary key, b int not null unique);CREATE TABLEpostgres -> replace into t1 values(1,1),(1,2);INSERT 0 3
postgres -> create temp table t2(a int primary key,b int not null unique);CREATE TABLEpostgres -> replace into t2 values(1,1),(1,2);ERROR: REPLACEINTO command cannot affect row a secondtimeHINT: Ensure that norows proposed for insertion within the same command have duplicate constrained values.
复制代码

四、兼容 MySQL 的 update/delete...order by...limit.. 语法

**功能:**指定更新/删除的元组的顺序和数量。


示例:


postgres -> create table t1 (a int primary key, b int);CREATE TABLEpostgres -> insert into t1 select generate_series(1,100),generate_series(1,100);INSERT 0 100
# 对非分区表的有序更新postgres -> update t1 set b=b+1 order by a desc limit 4 returning*; a | b-----+----- 100 | 101 99 | 100 98 | 99 97 | 98(4rows)
UPDATE 4
postgres -> drop table t1;DROP TABLEpostgres -> CREATE TABLE t1 (A INT PRIMARY KEY,B INT) PARTITION BY RANGE(a);CREATE TABLEpostgres -> CREATE TABLE t1p1 PARTITION OF t1 FOR VALUES FROM (0) TO (100);CREATE TABLEpostgres -> CREATE TABLE t1p2 PARTITION OF t1 FOR VALUES FROM (100) TO (200);CREATE TABLEpostgres -> insert into t1 select generate_series(0,199);INSERT 0 200
# 指定分区表删除的总量postgres -> delete from t1 limit 4 returning *; a | b---+--- 0 | 1 | 2 | 3 |(4rows)
DELETE 4
复制代码


和原生 MySQL 的差异:


  • 暂不支持指定分区表的更新/删除的顺序(注意:临时表的分区表已经支持)。 当然,实际使用中需要严格规定更新/删除顺序的场景是极少的,这一限制并不会对 KunlunBase 的用户造成困扰。


例如:


postgres -> CREATE TABLE t1 (A INT PRIMARY KEY, B INT) PARTITION BY RANGE(a);CREATE TABLEpostgres -> CREATE TABLE t1p1 PARTITION OF t1 FOR VALUESFROM (0) TO (100);CREATE TABLEpostgres -> CREATE TABLE t1p2 PARTITION OF t1 FORVALUESFROM (100) TO (200);CREATE TABLE
# 不能指定分区表删除顺序postgres -> delete from t1 order by a limit 4 returning *;ERROR: Kunlun-db: Cannot push down planpostgres ->
复制代码

END

昆仑数据库是一个 HTAP NewSQL 分布式数据库管理系统,可以满足用户对海量关系数据的存储管理和利用的全方位需求。应用开发者和 DBA 的使用昆仑数据库的体验与单机 MySQL 和单机 PostgreSQL 几乎完全相同,因为首先昆仑数据库支持 PostgreSQL 和 MySQL 双协议,支持标准 SQL:2011 的 DML 语法和功能以及 PostgreSQL 和 MySQL 对标准 SQL 的扩展。同时,昆仑数据库集群支持水平弹性扩容,数据自动拆分,分布式事务处理和分布式查询处理,健壮的容错容灾能力,完善直观的监测分析告警能力,集群数据备份和恢复等 常用的 DBA 数据管理和操作。所有这些功能无需任何应用系统侧的编码工作,也无需 DBA 人工介入,不停服不影响业务正常运行。昆仑数据库具备全面的 OLAP 数据分析能力,通过了 TPC-H 和 TPC-DS 标准测试集,可以实时分析最新的业务数据,帮助用户发掘出数据的价值。昆仑数据库支持公有云和私有云环境的部署,可以与 docker,k8s 等云基础设施无缝协作,可以轻松搭建云数据库服务。请访问 http://www.zettadb.com/ 获取更多信息并且下载昆仑数据库软件、文档和资料。KunlunBase 项目已开源

【GitHub:】https://github.com/zettadb

【Gitee:】https://gitee.com/zettadb

发布于: 刚刚阅读数: 3
用户头像

KunlunBase

关注

还未添加个人签名 2022.03.09 加入

还未添加个人简介

评论

发布
暂无评论
KunlunBase对MySQL私有DML语法的支持_国产数据库_KunlunBase_InfoQ写作社区