测试背景:针对TdSQL,GDB,OceanBase,GreatDB,达梦进行mysql 5.7.35进行兼容性测试。 效果如下:
MySQL 模式测试
1. DDL
1.1标准DDL
验证脚本:功能验证/MySQL模式/DDL.sql
用例编号 | DDL类型 | 测试用例描述 | TdSQL | GDB | OceanBase | GreatDB | 达梦 |
---|---|---|---|---|---|---|---|
01 | create table | 基本建表语句 | Y | Y | Y | Y | Y |
02 | 缺省值约束 | ||||||
03 | 非空约束 | ||||||
04 | 唯一性约束 | ||||||
05 | 主键约束 | ||||||
06 | 外键约束 | ||||||
07 | CTAS建表 | ||||||
08 | 表结构复制 | ||||||
09 | 创建临时表 | ||||||
10 | 创建范围分区表 | ||||||
11 | 创建HASH分区表 | ||||||
12 | 创建LIST分区表 | ||||||
13 | 创建key分区表 | ||||||
14 | 创建范围-HASH分区 | ||||||
15 | 创建范围-LIST分区 | ||||||
16 | 创建LIST-范围分区 | ||||||
17 | 创建LIST-HASH分区 | ||||||
18 | create index | 基本建索引 在线 | |||||
19 | 唯一性索引 在线 | ||||||
20 | 全局索引 在线 | ||||||
21 | 本地索引 在线 | ||||||
22 | create view | 创建视图 | |||||
23 | alter database | 修改数据库属性 | |||||
24 | Alter table | 增加列 在线 | |||||
25 | 删除列 在线 | ||||||
26 | 重命名列 在线 | ||||||
27 | 修改列类型 在线 | ||||||
28 | 重命名表 在线 | ||||||
29 | 新建索引 在线 | ||||||
30 | 新建唯一索引 在线 | ||||||
31 | 删除索引 在线 | ||||||
32 | 删除主键 在线 | ||||||
33 | 删除外键 在线 | ||||||
34 | 增加新的分区 在线 | ||||||
35 | 删除分区 在线 | ||||||
36 | 字段注释 在线 | ||||||
37 | alter index | 重命名索引 在线 | |||||
38 | 重建索引 在线 | ||||||
39 | 索引失效 在线 | ||||||
40 | truncate table | truncate整个表 | |||||
41 | comment | 注释表 | |||||
42 | 注释字段 | ||||||
43 | rename table | 重命名表 | |||||
44 | drop index | 删除索引 | |||||
45 | drop table | 删除表 | |||||
46 | drop view | 删除视图 |
1.2.全局唯一自增列
用例说明 验证全局自增列的特性
- 1.全局唯一
- 2.分区内单调递增
预期结果:
用例编号 | DDL类型 | 测试用例描述 | TdSQL | GDB | OceanBase | GreatDB | 达梦 |
---|---|---|---|---|---|---|---|
01 | 创建分区表带自增列 | 创建对象成功 | Y | Y | Y | Y | Y |
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c(以OB为例)
1 创建序列:
drop table test_range_partition_table;
create table test_range_partition_table (
insert_time datetime default CURRENT_TIMESTAMP,
id int auto_increment,
c3 int
)
partition by range (c3) (
partition p1 values less than (10),
partition p2 values less than (20),
partition p3 values less than (30),
partition px values less than MAXVALUE
);
检查创建成功:
desc test_range_partition_table;
2 使用序列插入10000行数据并核查 插入成功
操作命令:
for i in `seq 1 40`;
do
mysql -h192.168.1.90 -P2881 -uuser1@mysql_tenant -p"password" -c -Dtest -e "\"insert into test_range_partition_table(c3) values($i)\"";
done
检查350行数据插入成功
mysql -h192.168.1.90 -P2881 -uuser1@mysql_tenant -p"password" -c -Dtest -e "select count(*) from test_range_partition_table;"
4 检查数据全局唯一且单调递增 列id的值在全局保持唯一,分区内单调递增
操作命令:
select min(id),max(id),count(distinct id),count(*) from test_range_partition_table;
select * from (
select 'P1' as p,insert_time, id,c3 from test_range_partition_table partition (p1)
union
select 'P2' as p,insert_time, id,c3 from test_range_partition_table partition (p2)
union
select 'P3' as p,insert_time, id,c3 from test_range_partition_table partition (p3)
union
select 'Px' as p,insert_time, id,c3 from test_range_partition_table partition (px))
order by c3;
5 删除表 成功
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
drop table test_range_partition_table;
1.3.一级及二级分区表
用例说明:验证一级和二级分区创建和使用
预期结果:
用例编号 | DDL类型 | 测试用例描述 | TdSQL | GDB | OceanBase | GreatDB | 达梦 |
---|---|---|---|---|---|---|---|
01 | 创建一级range和二级hash分区 | 创建对象成功 | Y | Y | Y | Y | Y |
执行步骤
1 创建表并初始化数据:
drop table mysql_range_hash_table;
create table mysql_range_hash_table
(
id int,
name varchar(200),
province_id int,
constraint pk_r_h primary key (id,province_id,name)
)
Primary_zone= ' RANDOM'
partition by range (province_id)
subpartition by hash(id)
subpartitions 128
(
partition p1 values less than(100),
partition p2 values less than(200),
partition pdefault values less than (maxvalue)
) ;
检查数据字典查看二级分区创建成功:
show create table MYSQL_RANGE_HASH_TABLE;
2 验证该分区表均匀分布在所有节点 各个分区均匀分布于所有可用节点
登陆信创数据库集群sys租户:
mysql -h192.168.1.90 -uroot@sys -P2881 -D信创数据库 -c (已OB为例)
查询分区表的物理分布:
select s.zone,s.svr_ip,d.database_name,t.table_name,count(*)
from __all_virtual_table t, __all_virtual_meta_table m , __all_server s, __all_virtual_database d
where t.table_id=m.table_id and m.svr_ip = s.svr_ip and t.database_id=d.database_id and m.role=1
and t.table_name='MYSQL_RANGE_HASH_TABLE'
group by s.zone,s.svr_ip,d.database_name,t.table_name;
3 删除分区表 成功
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
drop table MYSQL_RANGE_HASH_TABLE;
1.4.外键约束
用例说明:验证基于分区表的外键约束
注:因为分区表的物理分布不一致,该用例旨在说明跨分区跨节点的外键的可用性
预期结果:
用例编号 | DDL类型 | 测试用例描述 | TdSQL | GDB | OceanBase | GreatDB | 达梦 |
---|---|---|---|---|---|---|---|
01 | 创建表及外键约束 | 创建对象成功 | Y | Y | Y | Y | Y |
执行步骤
1 创建表及外键约束 创建对象成功
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
foreign_key_checks=on
创建表并初始化数据:
drop table mysql_table_fk;
drop table mysql_table_key;
create table mysql_table_key (did integer primary key) partition by hash(did) partitions 3;
create table mysql_table_fk
( pid integer,
did integer,
constraint mysql_pk primary key(pid),
constraint mysql_fk foreign key(did) references mysql_table_key(did)
)
partition by hash(pid) partitions 3;
检查数据字典查看外键创建成功:
show create table mysql_table_key;
show create table mysql_table_fk;
2 初始化数据并验证外键 Insert / Update语句会因为违反引用约束报错:
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
insert into mysql_table_key(did) values(1);
insert into mysql_table_fk (pid,did) values(1,2);
insert into mysql_table_fk (pid,did) values(2,1);
update mysql_table_fk set did=3 where did=1;
commit;
drop table mysql_range_hash_table;
3 删除表和数据 成功
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
drop table mysql_table_fk;
drop table mysql_table_key;
1.5.全局索引
用例说明:验证全局索引
注:全局索引的分区规则跟表分区是相互独立的,可以支持分区表上非分区键的全局性唯一性索引
执行步骤
1 创建分区表 创建对象成功
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
drop table test_range_partition_table;
create table test_range_partition_table (
c1 integer primary key,
c2 varchar(32)
)
partition by range (c1) (
partition p1 values less than (1000),
partition p2 values less than (2000),
partition p3 values less than (3000),
partition px values less than MAXVALUE);
2 尝试在非分区列创建local唯一索引 创建失败
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
create unique index idx_1 on test_range_partition_table (c2) local;
3 尝试在非分区列创建全局唯一索引成功 创建成功
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
create unique index idx_1 on test_range_partition_table (c2);
4 插入同分区和不同分区的重复列值 由于违反唯一性约束,插入失败
登陆信创数据库集群MySQL租户:
insert into test_range_partition_table values(100,100);
insert into test_range_partition_table values(200,100);
insert into test_range_partition_table values(1100,100);
5 根据全局索引键查询 执行计划走全局索引
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
explain select count(c2) from test_range_partition_table where c2=100;
6 删除表和索引 成功
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
drop index idx_1 on test_range_partition_table;
drop table test_range_partition_table;
1.6.复制表
用例说明:验证信创数据库复制表功能
注:将更新频率低访问频率高的表定义为复制表,表的副本自动在租户所属服务器上产生复制副本,以避免分布式事务。
预期结果:
用例编号 | DDL类型 | 测试用例描述 | TdSQL | GDB | OceanBase | GreatDB | 达梦 |
---|---|---|---|---|---|---|---|
01 | 创建一张复制表主副本在zone_1 ,另一张表主副本分别在zone_2 | 创建对象成功 | Y | Y | Y | Y | Y |
执行步骤
登陆信创数据库集群MySQL租户:
1 创建表并初始化数据:
drop table table_item;
drop table table_trade;
create table table_item (
i_id integer not null,
i_name varchar(24),
i_price decimal(5,2),
PRIMARY KEY (i_id))
locality='F,R{all_server}@zone_1,F,R{all_server}@zone_2,F,R{all_server}@zone_3' primary_zone='zone_1' duplicate_scope='cluster';
create table table_trade (
trade_id integer primary key,
i_id integer)
partition by hash(trade_id) partitions 3;
insert into table_item values(1,'hat',2), (2,'bread',3),(3,'milk',4);
insert into table_trade values(1,1),(2,2),(3,3);
commit;
2 运行复制表和交易表的连接查询,检查执行计划 plan type是 LOCAL
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
explain extended select * from table_item a, table_trade b where a.i_id=b.i_id and b.trade_id=1;
explain extended select * from table_item a, table_trade b where a.i_id=b.i_id and b.trade_id=2;
explain extended select * from table_item a, table_trade b where a.i_id=b.i_id and b.trade_id=3;
3 删除表和数据 成功
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
drop table table_trade;
drop table table_item;
2. DML
2.1.标准DML
验证脚本:功能验证/MySQL模式/DML.sql
用例编号 | DDL类型 | 测试用例描述 | TdSQL | GDB | OceanBase | GreatDB | 达梦 |
---|---|---|---|---|---|---|---|
01 | insert | 基本语句 | |||||
02 | 子查询方式 | ||||||
03 | 插入时含空值 | ||||||
04 | 插入时多行数据 | ||||||
05 | 插入时set语句 | ||||||
06 | 插入时引用已经赋值的字段 | ||||||
07 | 插入时忽略错误(前提) | ||||||
08 | update | 更新时用select子句 | |||||
09 | 更新时用case when子句 | ||||||
10 | 更新时用limit子句 | ||||||
11 | 更新时用select子查询 | ||||||
12 | 更新时用order by子句 | ||||||
13 | 更新时用多表同时更新 | ||||||
14 | 更新时用inner join子句 | ||||||
15 | 更新数据时忽略错误 | ||||||
16 | delete | 删除数据 | |||||
17 | 删除数据时用select子查询 |
2.2.Replace into
用例说明:验证replace into 语句
预期结果:
用例编号 | DDL类型 | 测试用例描述 | TdSQL | GDB | OceanBase | GreatDB | 达梦 |
---|---|---|---|---|---|---|---|
01 | 创建一级range和二级hash分区 | 创建对象成功 | Y | Y | Y | Y | Y |
执行步骤
1 创建表并初始化数据 创建对象成功
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
创建表并初始化数据:
drop table test_replace1;
create table test_replace(c1 integer primary key, c2 integer);
insert into test_replace values(1,1);
2 运行merge into语句 运行成功
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
replace into test_replace values(1,2);
replace into test_replace values(2,2);
3 检查运行结果 c1, c2=(1,2),(2,2)
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
select * from test_replace;
4 删除表 成功
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
drop table test_replace;
2.3.Insert on duplicate key update
用例说明: 验证insert on duplicate key update多行语句
预期结果:
用例编号 | DDL类型 | 测试用例描述 | TdSQL | GDB | OceanBase | GreatDB | 达梦 |
---|---|---|---|---|---|---|---|
01 | 创建一级range和二级hash分区 | 创建对象成功 | Y | Y | Y | Y | Y |
执行步骤
1 创建表并初始化数据 创建对象成功
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
创建表并初始化数据:
drop table test_insert_duplicate;
create table test_insert_duplicate(c1 integer primary key, c2 integer);
2 运行insert on duplicate key update语句 运行成功
登陆信创数据库集群MySQL租户:
insert into test_insert_duplicate values(1,1);
insert into test_insert_duplicate(c1,c2) values(1,2) on duplicate key update c2=2;
commit;
3 检查运行结果 c1, c2=(1,2)
登陆信创数据库集群MySQL租户:
select * from test_insert_duplicate;
4 删除表 成功
登陆信创数据库集群MySQL租户:
drop table test_insert_duplicate;
3. 查询语句
3.1 标准查询
预期结果:
用例编号 | DQL类型 | 测试用例描述 | TdSQL | GDB | OceanBase | GreatDB | 达梦 |
---|---|---|---|---|---|---|---|
01 | select | 基本语句 | Y | Y | Y | Y | Y |
02 | select for update | 查询加锁 | |||||
03 | table_name as t | 表别名引用 | |||||
04 | column_name c | 字段别名 | |||||
05 | inner join | 内连接 | |||||
06 | left join | 左外连接 | |||||
07 | right join | 右外连接 | |||||
08 | union all | 全连接 | |||||
09 | 84960 as draw_id | 获取固定值 | |||||
10 | group by | 分组查询 | |||||
11 | limit | 限制输出 | |||||
12 | substring | 字符串截取 | |||||
13 | group_concat | 合并行 | |||||
14 | concat | 合并列 | |||||
15 | all(sub select) | all子查询 | |||||
16 | any(sub select) | any子查询 | |||||
17 | exists | exists子查询 | |||||
18 | not exists | not exists查询 | |||||
19 | regexp | 正则表达式 | |||||
20 | like binary | 按子母大小写查询 |
3.2.窗口函数
用例说明:验证窗口分析函数
注:
1.窗口分析函数,SQL99中也称为OLAP函数,对相关数据行集合的统计分析
2.本用例初始化一张学生成绩表,通过部分窗口分析函数举例查询满足不同的查询需求
预期结果:
用例编号 | DDL类型 | 测试用例描述 | TdSQL | GDB | OceanBase | GreatDB | 达梦 |
---|---|---|---|---|---|---|---|
01 | 创建一级range和二级hash分区 | 创建对象成功 | Y | Y | Y | Y | Y |
执行步骤
1 创建表并初始化数据
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
创建表并初始化数据:
create table score_tbl(class int, student int, score number, primary key(class, student));
insert into score_tbl values
(1,1,90), (1,2,80), (1,3,85), (1,4,82), (1,5,82), (1,6,80), (2,1,87), (2,2,88), (2,3,67), (2,4,79);
2 查询每个学生班里分数与自己相邻的学生(包括自己一共三个人)的最高分 成功
登陆信创数据库集群MySQL租户:
select class,student,score,max(score) over (partition by class order by score desc rows between 1 preceding and 1 following) max_score from score_tbl;
3 查询学校里每个学生分数与其分差在10分以内的同学(包含自己)的最高分 成功
登陆信创数据库集群MySQL租户:
select class,student,score,max(score) over (partition by class order by score desc range between 10 preceding and 10 following) max_score from score_tbl;
4 查询每个学生在自己班级的分数名次 成功
登陆信创数据库集群MySQL租户:
select class,student,score,rank() over (partition by class order by score desc) max_score from score_tbl;
5 查询每个学生的分数、所在班级的分数总和以及第一名同学的学号 成功
登陆信创数据库集群MySQL租户:
select class,student,score,sum(score) over (partition by class) sum_score,
first_value(student) over (partition by class order by score desc) first_stu
from score_tbl;
6 删除表 成功
登陆信创数据库集群MySQL租户:
drop table score_tbl;
3.3.通过Hint并行查询
用例说明:验证通过Hint并行查询行为的能力
预期结果:
用例编号 | DDL类型 | 测试用例描述 | TdSQL | GDB | OceanBase | GreatDB | 达梦 |
---|---|---|---|---|---|---|---|
01 | 创建一级range和二级hash分区 | 创建对象成功 | Y | Y | Y | Y | Y |
执行步骤
1 创建分区表并初始化数据
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
创建表并初始化数据:
create table emp(emp_id integer, emp_name varchar(200), mgr_id integer) partition by range(emp_id) (partition p1 values less than (5), partition p2 values less than(10));
insert into emp values
(1,'Tom',3),(2,'Jone',3),(3,'MJ',4),(4,'Kurt',null),(5,'David',2),(6,'Scott',1);
2 通过Hint进行并行查询 运行成功,通过执行计划可以看到并行查询的关键字
1.PX BLOCK ITERATOR
2.dop=4
登陆信创数据库集群MySQL租户:
explain select /*+parallel(2) */ * from emp;
3 删除表 成功
登陆信创数据库集群MySQL租户:
mysql -h192.168.1.90 -uroot@mysql_tenant -P2881 -c
drop table emp;
4.过程语言支持
验证脚本:功能验证/MySQL模式/{procedure.sql, function.sql}
用例编号 | DQL类型 | 测试用例描述 | TdSQL | GDB | OceanBase | GreatDB | 达梦 |
---|---|---|---|---|---|---|---|
01 | 存储过程 | ||||||
02 | 自定义函数 |
5. 数据类型兼容性
验证脚本:功能验证/MySQL模式/data_type.sql
用例编号 | 数据类型 | 测试用例描述 | TdSQL | GDB | OceanBase | GreatDB | 达梦 |
---|---|---|---|---|---|---|---|
01 | 整数类型 | BIT | |||||
02 | BOOL/BOOLEAN | ||||||
03 | TINYINT | ||||||
04 | SMALLINT | ||||||
05 | MEDIUMINT | ||||||
06 | INT/INTEGER | ||||||
07 | BIGINT | ||||||
08 | 定点类型 | DECIMAL | |||||
09 | NUMERIC | ||||||
10 | 浮点类型 | FLOAT | |||||
11 | DOUBLE | ||||||
12 | 日期类型 | YEAR | |||||
13 | DATE | ||||||
14 | 时间类型 | DATETIME | |||||
15 | TIMESTAMP | ||||||
16 | TIME | ||||||
17 | 普通字符类型 | CHAR | |||||
18 | BINARY | ||||||
19 | VARCHAR | ||||||
20 | VARBINARY | ||||||
21 | ENUM | ||||||
22 | SET | ||||||
23 | 大对象字符类型 | TINYTEXT | |||||
24 | TINYLOB | ||||||
25 | TEXT | ||||||
26 | BLOB | ||||||
27 | MEDIUMTEXT |
6. 内置函数兼容性
验证脚本:功能验证/MySQL模式/building_function.sql
用例编号 | 函数内置 | 测试用例描述 | TdSQL | GDB | OceanBase | GreatDB | 达梦 |
---|---|---|---|---|---|---|---|
01 | ASCII | 返回ASCII码值 | |||||
02 | CONCAT | 连接字符串 | |||||
03 | CONCAT_WS | 连接字符串时用指定字符隔开 | |||||
04 | INSERT | 字符串替换 | |||||
05 | FIND_IN_SET | 查找字符串位置 | |||||
06 | LCASE/LOWER | 字符串小写 | |||||
07 | LEFT | 字符串左截取 | |||||
08 | LENGTH | 字符串字符数 | |||||
09 | LTRIM | 切掉字符串开头的空格 | |||||
10 | POSITION | 字符串第一次出现的位置 | |||||
11 | QUOTE | 反斜杠转义字符串中的单引号 | |||||
12 | REPEAT | 字符串重复的次数 | |||||
13 | REVERSE | 颠倒字符串 | |||||
14 | RIGHT | 字符串右截取 | |||||
15 | RTRIM | 字符串尾部的空格 | |||||
16 | STRCMP | 字符串比较 | |||||
17 | TRIM | 字符串两边截取 | |||||
18 | UCASE/UPPER | 字符串变大写 | |||||
19 | ABS(x) | X绝对值 | |||||
20 | BIN(x) | X二进制 | |||||
21 | CEILING(x) | X最小整数 | |||||
22 | FLOOR(x) | x的最大值 | |||||
24 | GREATEST | 集合中最大的值 | |||||
25 | LEAST | 集合中最小的值 | |||||
26 | MOD(x,y) | x/y的模(余数) | |||||
29 | RAND | 随机数 | |||||
31 | ROUND | 四舍五入 | |||||
32 | SIGN(x) | 数字x的符号的值 | |||||
33 | SQRT(x) | X的平方根 | |||||
34 | TRUNCATE(x,y) | x截短为y位小数 | |||||
35 | CURDATE | 当前日期 | |||||
36 | CURTIME | 当前的时间 | |||||
37 | DATE_ADD | 日期相加 | |||||
38 | DATE_FORMAT | 日期格式化 | |||||
39 | DAYOFWEEK | 返回星期 | |||||
40 | DAYOFMONTH | 返回一个月的第几天 | |||||
41 | DAYOFYEAR | 返回一年的第几天 | |||||
42 | HOUR | 小时 | |||||
43 | MINUTE | 分钟 | |||||
44 | MONTH | 月份 | |||||
45 | WEEK | 周 | |||||
46 | YEAR | 年 | |||||
47 | AVG | 平均值 | |||||
48 | COUNT | 个数 | |||||
49 | MIN | 最小值 | |||||
50 | MAX | 最大值 | |||||
51 | SUM | 总数 |