1.3.3.4. DDL
1.3.3.4.1. GaussDB-Oracle
1.3.3.4.1.1. 创建库
语法
CREATE DATABASE [IF NOT EXISTS] DB_NAME
警告
可通过参数unisql.change.database.to.schema配置来决定通过统一SQL转换后逻辑:
当unisql.change.database.to.schema=1时,统一SQL转换为创建模式;CREATE SCHEMA schema_name;
当unisql.change.database.to.schema=0时,统一SQL转换为创建库;CREATE DATABASE db_name;
示例
-- 转换前MySQL SQL:
CREATE DATABASE IF NOT EXISTS testdb;
-- 统一SQL配置unisql.change.database.to.schema=1,转换后GaussDB-Oracle SQL:
CREATE SCHEMA testdb;
-- 统一SQL配置unisql.change.database.to.schema=0,转换后GaussDB-Oracle SQL:
CREATE DATABASE testdb;
1.3.3.4.1.2. 删除库
语法
DROP DATABASE [IF EXISTS] DB_NAME
警告
可通过参数unisql.change.database.to.schema配置决定统一SQL转换后对象为DATABASE或SCHEMA:
当unisql.change.database.to.schema=1时,统一SQL转换为删除模式;DROP SCHEMA [IF EXISTS] schema_name CASCADE;
当unisql.change.database.to.schema=0时,统一SQL转换为删除库;DROP DATABASE [IF EXISTS] db_name;
unisql.change.database.to.schema参数值默认为0。
示例
-- 转换前MySQL SQL:
DROP DATABASE IF EXISTS testdb;
-- 统一SQL配置unisql.change.database.to.schema=1,转换后GaussDB-Oracle SQL:
DROP SCHEMA IF EXISTS testdb CASCADE;
-- 统一SQL配置unisql.change.database.to.schema=0,转换后GaussDB-Oracle SQL:
DROP DATABASE IF EXISTS testdb;
1.3.3.4.1.3. 切换库
语法
USE DB_NAME
警告
DB_NAME 不能为mysql或GaussDB-Oracle关键字,否则在执行过程中报错。
示例
-- 转换前MySQL SQL:
USE DB_NAME
-- 转换后GaussDB-Oracle SQL:
SET SCHEMA 'DB_NAME'
1.3.3.4.1.4. 创建普通表
语法
CREATE TABLE [IF NOT EXISTS] TABLE_NAME(
COLUMN_NAME1 DATATYPE [AUTO_INCREMENT] [DEFAULT ...] [ON UPDATE CURRENT_TIMESTAMP] [ZEROFILL]
[CHARSET | CHARACTER SET CHARSET_NAME] [COLLATE COLLATION_NAME] [COMMENT COMMENT_STRING]
[, ...]
[, PRIMARY KEY(COLUMN_NAME [, ...] [USING BTREE])]
[, INDEX INDEX_NAME(COLUMN_NAME [, ...] [USING BTREE])]
[, FULLTEXT [KEY] [FULL_INDEX_NAME](COLUMN_NAME [, ...])]
)
[ENGINE = ENGINE_NAME]
[[DEFAULT] CHARSET | CHARACTER SET [=] CHARSET_NAME]
[[DEFAULT] COLLATE [=] COLLATION_NAME]
[ROW_FORMAT [=] FORMAT_NAME]
[COMMENT [=] COMMENT_STRING]
[DELAY_KEY_WRITE [=] {0|1}]
[CHECKSUM [=] {0|1}]
警告
对于CHARACTER/CHARACTER SET、COLLATE、ROW_FORMAT可选字段,统一SQL均为语法支持,无实际功能; 支持创建前缀索引语法,无实际功能;
对于表中列指定了自增主键,当向主键列中null值时,等同于default会自动生成自增主键值,例如:
– 转换前MySQL SQL(id为自增主键列): INSERT INTO t1(id, name) VALUES(NULL, ‘test’);
– 转换后GaussDB-Oracle SQL: INSERT INTO t1(id, name) VALUES(DEFAULT, ‘test’);
支持PRIMARY KEY、UNIQUE KEY、KEY、INDEX对象带备注,如对象没有指定名称则根据规则:表名_指定列(多个列间用下划线拼接)_后缀 生成对象名称,
说明:PRIMARY KEY后缀为 _pkey
、UNIQUE KEY后缀为 _key
、KEY和INDEX后缀为 _idx
;
FULLTEXT KEY转换为普通索引,转换后只支持普通索引,不支持全文索引功能,如果建表语句中fulltext key未指定索引名称,转换后会自动生成名称,名称格式为:tablename_columnname[_columnname]_idx。
一个表多个对象的名称超过63个字符,且前63个字符一致,因GAUSSDB_ORACLE会截取前63个字符作为对象名称,会导致后创建的对象失败,这种统一sql不做特殊处理;
GAUSSDB_ORACLE中相同名称的约束只能创建一个,不同表产生相同名称的约束对象统一sql不做特殊处理。
示例
-- 转换前MySQL SQL:
CREATE TABLE IF NOT EXISTS test_table(
id int AUTO_INCREMENT,
co1 varchar(20) DEFAULT 'abc' COMMENT 'this is a test column',
co2 text CHARSET utf8 COLLATE utf8_general_ci NOT NULL,
co3 timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
co4 numeric(5, 3) ZEROFILL,
co5 varchar(200),
PRIMARY KEY(id),
INDEX idx_co12(co1, co2),
KEY idx_co5(co5(50))
)
ENGINE=InnoDB
DEFAULT CHARACTER SET utf8
DEFAULT COLLATE=utf8_bin
ROW_FORMAT = COMPACT
COMMENT = 'this is test table';
-- 转换后GaussDB-Oracle SQL:
CREATE TABLE IF NOT EXISTS test_table (
id serial,
co1 nvarchar2(20) DEFAULT 'abc' ,
co2 text NOT NULL,
co3 timestamp DEFAULT CURRENT_TIMESTAMP(0),
co4 numeric(5,3),
PRIMARY KEY(id)
) ;
COMMENT ON TABLE test_table IS 'this is test table';
COMMENT ON COLUMN test_table.co1 IS 'this is a test column';
CREATE INDEX idx_co12 ON test_table(co1,co2);
CREATE INDEX idx_co5 ON test_table(co5);
-- 转换前MySQL SQL:
CREATE TABLE EXAMPLE_TABLE (
COLUMN1 INT AUTO_INCREMENT COMMENT 'COLUMN1',
COLUMN2 VARCHAR ( 255 ) NOT NULL COMMENT 'COLUMN2',
COLUMN3 VARCHAR ( 50 ) NOT NULL COMMENT 'COLUMN3',
COLUMN4 INT COMMENT 'COLUMN4',
COLUMN5 INT COMMENT 'COLUMN5',
COLUMN6 INT COMMENT 'COLUMN6',
COLUMN7 INT COMMENT 'COLUMN7',
COLUMN8 INT COMMENT 'COLUMN8',
COLUMN9 INT COMMENT 'COLUMN9',
COLUMN10 INT COMMENT 'COLUMN10',
PRIMARY KEY ( COLUMN1 ) COMMENT '主键 ',
UNIQUE KEY ( COLUMN2, COLUMN3, COLUMN4 ) COMMENT '唯一索引',
KEY ( COLUMN5 ) COMMENT 'KEY',
INDEX ( COLUMN6, COLUMN7, COLUMN8, COLUMN9, COLUMN10 ) COMMENT '索引'
) COMMENT = '用户信息表';
-- 转换后GaussDB-Oracle SQL:
CREATE TABLE EXAMPLE_TABLE (
COLUMN1 serial,
COLUMN2 nvarchar2 ( 765 ) NOT NULL,
COLUMN3 nvarchar2 ( 150 ) NOT NULL,
COLUMN4 INT,
COLUMN5 INT,
COLUMN6 INT,
COLUMN7 INT,
COLUMN8 INT,
COLUMN9 INT,
COLUMN10 INT,
CONSTRAINT example_table_pkey PRIMARY KEY ( COLUMN1 ),
CONSTRAINT example_table_column2_column3_column4_key UNIQUE ( COLUMN2, COLUMN3, COLUMN4 ));
CREATE INDEX example_table_column5_idx ON EXAMPLE_TABLE ( COLUMN5 );
CREATE INDEX example_table_column6_column7_column8_column9_column10_idx ON EXAMPLE_TABLE ( COLUMN6, COLUMN7, COLUMN8, COLUMN9, COLUMN10 );
COMMENT ON TABLE EXAMPLE_TABLE IS '用户信息表';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN1 IS 'COLUMN1';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN2 IS 'COLUMN2';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN3 IS 'COLUMN3';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN4 IS 'COLUMN4';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN5 IS 'COLUMN5';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN6 IS 'COLUMN6';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN7 IS 'COLUMN7';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN8 IS 'COLUMN8';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN9 IS 'COLUMN9';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN10 IS 'COLUMN10';
COMMENT ON CONSTRAINT example_table_pkey ON EXAMPLE_TABLE IS '主键 ';
COMMENT ON CONSTRAINT example_table_column2_column3_column4_key ON EXAMPLE_TABLE IS '唯一索引';
COMMENT ON INDEX example_table_column5_idx IS 'KEY';
COMMENT ON INDEX example_table_column6_column7_column8_column9_column10_idx IS '索引'
-- 转换前MySQL SQL:
create table GROUPS (
id int,
name varchar(100),
name_desc varchar(100),
trans_name varchar(100),
test_values varchar(100),
values1 varchar(100),
GROUPS int
);
-- 转换后GaussDB-Oracle SQL:
create table GROUPS (id int,
name nvarchar2(300),
name_desc nvarchar2(300),
trans_name nvarchar2(300),
test_values nvarchar2(300),
values1 nvarchar2(300),
GROUPS int
)
-- 转换前MySQL SQL:
CREATE TABLE unisql_delay_key_write_check (
employee_id INT NOT NULL AUTO_INCREMENT,
employee_name VARCHAR(255),
department VARCHAR(100),
PRIMARY KEY (employee_id)
) DELAY_KEY_WRITE=1 CHECKSUM=0
-- 转换后GaussDB-Oracle SQL:
CREATE TABLE unisql_delay_key_write_check (
employee_id serial NOT NULL,
employee_name nvarchar2(765),
department nvarchar2(300),
CONSTRAINT unisql_delay_key_write_check_pkey PRIMARY KEY(employee_id))
1.3.3.4.1.5. 修改普通表
语法
ALTER TABLE [IF EXISTS] TABLE_NAME
[DROP PRIMARY KEY | INDEX INDEX_NAME]
| ADD [COLUMN] [IF NOT EXISTS] COLUMN_NAME DATATYPE [CHARACTER SET CHARSET_NAME] [COLLATE COLLATE_NAME] [DEFAULT ...] [COMMENT COMMENT_STRING]
| MODIFY [COLUMN] COLUMN_NAME DATATYPE [CHARACTER SET CHARSET_NAME] [COLLATE COLLATE_NAME] [DEFAULT ...] [COMMENT COMMENT_STRING]
| CHANGE [COLUMN] COLUMN_OLD_NAME COLUMN_NEW_NAME DATATYPE [CHARACTER SET CHARSET_NAME] [COLLATE COLLATE_NAME] [DEFAULT ...] [COMMENT COMMENT_STRING]
| ADD INDEX | KEY INDEX_NAME(COLUMN_NAME [, ...])
| RENAME INDEX | KEY INDEX_OLD_NAME TO INDEX_NEW_NAME
| CONVERT TO CHARACTER SET CHARSET_NAME
| COMMENT COMMENT_STRING
警告
ALTER TABLE…CONVERT TO CHARACTER SET…仅语法支持,无实际功能,且受配置参数控制,config/unisql.conf中unisql.replace.sql参数可配置需要替换的sql语句。
ALTER TABLE TABLE_NAME change 中 DATATYPE 为 double(p,s) 时转换为decimal(p,s),p、s参考数据类型章节; (numeric和decimal是等价的)。
ALTER TABLE TABLE_NAME change 中 DATATYPE 为 datetime 时转换为timestamp(0);(mysql datetime对应无精度的timestamp)。
ALTER TABLE TABLE_NAME MODIFY|CHANGE 在 GaussDB 中修改类型需要有类型转换逻辑,不是所有类型都支持转换,类型是否可以修改,需要遵循 GaussDB 的约束规则,比如blob类型修改成int不支持。
ALTER TABLE TABLE_NAME ADD 的IF NOT EXISTS 转化到GaussDB-Oracle后被忽略,所以添加表中已经存在的列,在GaussDB-Oracle执行会报错。
ALTER TABLE IF EXISTS TABLE_NAME 后仅支持 DROP PRIMARY KEY 、ADD [COLUMN] xxx、MODIFY [COLUMN] xxx、CHANGE [COLUMN] xxx 语法。
示例
-- 转换前MySQL SQL:
ALTER TABLE test_table DROP PRIMARY KEY;
ALTER TABLE test_table DROP INDEX idx_co12;
ALTER TABLE test_table ADD COLUMN IF NOT EXISTS co5 VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT 'this is a comment';
ALTER TABLE test_table MODIFY COLUMN co5 text CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT 'test column' COMMENT 'this is another comment';
ALTER TABLE test_table CHANGE COLUMN co5 co5_new blob DEFAULT NULL COMMENT 'this is a new comment';
ALTER TABLE test_table ADD INDEX idx_co5(co5);
ALTER TABLE test_table ADD KEY idx_co5_another(co5);
ALTER TABLE test_table RENAME INDEX idx_co5 TO idx_co5_new;
ALTER TABLE test_table CONVERT TO CHARACTER SET utf8;
ALTER TABLE test_table COMMENT 'this is a new table comment';
ALTER TABLE test_table ADD COLUMN mediumintColumn mediumint DEFAULT 0 ;
-- 转换后GaussDB-Oracle SQL:
ALTER TABLE test_table DROP CONSTRAINT test_table_pkey;
DROP INDEX idx_co12;
ALTER TABLE test_table ADD co5 nvarchar2(20) DEFAULT NULL;
COMMENT ON COLUMN test_table.co5 IS 'this is a comment';
ALTER TABLE test_table ALTER COLUMN co5 TYPE text;
ALTER TABLE test_table ALTER COLUMN co5 SET DEFAULT 'test column';
COMMENT ON COLUMN test_table.co5 IS 'this is another comment';
ALTER TABLE test_table RENAME co5 TO co5_new;
ALTER TABLE test_table ALTER COLUMN co5_new TYPE bytea;
ALTER TABLE test_table ALTER COLUMN co5_new SET DEFAULT NULL;
COMMENT ON COLUMN test_table.co5_new IS 'this is a new comment';
CREATE INDEX idx_co5 ON test_table (co5);
CREATE INDEX idx_co5_another ON test_table (co5);
ALTER INDEX idx_co5 RENAME TO idx_co5_new;
-- unisql.replace.sql = 'select 1'
select 1;
COMMENT ON TABLE test_table IS 'this is a new table comment';
ALTER TABLE unisql_mediumint_test ADD mediumintColumn int DEFAULT 0;
-- 转换前MySQL SQL:
ALTER TABLE if exists unisql_table_alter_table DROP PRIMARY KEY;
ALTER TABLE if exists unisql_table_alter_table ADD COLUMN IF NOT EXISTS co6 VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT 'this is a comment';
ALTER TABLE if exists unisql_table_alter_table MODIFY COLUMN co5 text CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT 'test column' COMMENT 'this is another comment';
ALTER TABLE if exists unisql_table_alter_table CHANGE COLUMN co5 co51 text DEFAULT NULL COMMENT 'this is a new comment';
-- 转换后GaussDB-Oracle SQL:
ALTER TABLE IF EXISTS unisql_table_alter_table DROP CONSTRAINT unisql_table_alter_table_pkey;
ALTER TABLE IF EXISTS unisql_table_alter_table ADD co6 nvarchar2(60) DEFAULT NULL;
COMMENT ON COLUMN unisql_table_alter_table.co6 IS 'this is a comment';
ALTER TABLE IF EXISTS unisql_table_alter_table ALTER COLUMN co5 TYPE text;
ALTER TABLE IF EXISTS unisql_table_alter_table ALTER COLUMN co5 SET DEFAULT 'test column';
COMMENT ON COLUMN unisql_table_alter_table.co5 IS 'this is another comment';
ALTER TABLE IF EXISTS unisql_table_alter_table RENAME co5 TO co51;
ALTER TABLE IF EXISTS unisql_table_alter_table ALTER COLUMN co51 TYPE text;
ALTER TABLE IF EXISTS unisql_table_alter_table ALTER COLUMN co51 SET DEFAULT NULL;
COMMENT ON COLUMN unisql_table_alter_table.co51 IS 'this is a new comment';
1.3.3.4.1.6. 创建分区表
语法
CREATE TABLE [IF NOT EXISTS] TABLE_NAME(
COLUMN_NAME1 DATATYPE [AUTO_INCREMENT] [DEFAULT ...] [ON UPDATE CURRENT_TIMESTAMP] [ZEROFILL]
[COLLATE COLLATION_NAME] [COMMENT COMMENT_STRING]
[, ...]
[, PRIMARY KEY(COLUMN_NAME [, ...] [USING BTREE])]
[, INDEX INDEX_NAME(COLUMN_NAME [, ...] [USING BTREE])]
)
PARTITION BY RANGE [COLUMNS](COLUMN_NAME)(
PARTITION PARTITION_NAME VALUES LESS THAN (VALUE_1)
[, ...]
)
示例
-- 转换前MySQL SQL:
CREATE TABLE IF NOT EXISTS test_table_partition(
id int AUTO_INCREMENT,
co1 varchar(20) DEFAULT 'abc' COMMENT 'this is a test column',
co2 text NOT NULL COLLATE 'utf8_bin',
co3 timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
co4 numeric(5, 3) ZEROFILL,
PRIMARY KEY(id),
INDEX idx_co12(co1)
)
PARTITION BY RANGE COLUMNS(id)
(
PARTITION p0 VALUES LESS THAN (100),
PARTITION p1 VALUES LESS THAN (200),
PARTITION p2 VALUES LESS THAN (300)
);
-- 转换后GaussDB-Oracle SQL:
CREATE TABLE IF NOT EXISTS test_table_partition (
id serial,
co1 nvarchar2(60) DEFAULT 'abc' ,
co2 text NOT NULL,
co3 timestamp DEFAULT CURRENT_TIMESTAMP(0),
co4 numeric(5,3),
CONSTRAINT test_table_partition_pkey PRIMARY KEY(id)
) PARTITION BY RANGE (id) (
PARTITION p0 VALUES LESS THAN (100),
PARTITION p1 VALUES LESS THAN (200),
PARTITION p2 VALUES LESS THAN (300)
);
CREATE INDEX idx_co12 ON test_table_partition (co1);
COMMENT ON COLUMN test_table_partition.co1 IS 'this is a test column';
1.3.3.4.1.7. 创建用户
语法
CREATE USER USER_NAME@HOST_NAME IDENTIFIED BY PASSWORD
示例
-- 转换前MySQL SQL:
CREATE USER 'user1'@'localhost' IDENTIFIED BY '123456';
-- 转换后GaussDB-Oracle SQL:
CREATE USER "user1" IDENTIFIED BY '123456';
1.3.3.4.1.8. 修改用户
语法
ALTER USER USER_NAME@HOST_NAME
[IDENTIFIED BY NEW_PASSWORD]
| [ACCOUNT LOCK | UNLOCK]
示例
-- 转换前MySQL SQL:
ALTER USER 'user1'@'localhost' IDENTIFIED BY 'abc567890';
ALTER USER 'user1'@'localhost' ACCOUNT LOCK;
ALTER USER 'user1'@'localhost' ACCOUNT UNLOCK;
-- 转换后GaussDB-Oracle SQL:
ALTER USER "user1" IDENTIFIED BY 'abc567890';
ALTER USER "user1" ACCOUNT LOCK;
ALTER USER "user1" ACCOUNT UNLOCK;
1.3.3.4.1.9. 设置外键约束
语法
SET FOREIGN_KEY_CHECKS = {0 | 1}
警告
其中 0 表示禁用外键约束,1 表示启用外键约束
示例
-- 转换前MySQL SQL:
SET FOREIGN_KEY_CHECKS = 0;
SET FOREIGN_KEY_CHECKS = 1;
-- 转换后GaussDB-Oracle SQL:
seelct 1;
1.3.3.4.1.10. 修改自增列的起始值
语法
ALTER TABLE table_name AUTO_INCREMENT = number
警告
- 修改自增列的起始值目前限制:
依赖unisql.conf文件中配置unisql.auto.increment.column的相关内容;
GaussDB-Oracle默认的序列名称为:表名_列名_seq,本次转化使用GaussDB-Oracle默认的序列名称,用户需要保证模式下序列名称唯一;
MySQL的修改自增列的起始值是DDL语句,转化后变成DQL语句;
对于MySQL的Bigint类型自增列,转化到GaussDB-Oracle后类型为Bigserial,所以起始值范围:1到2^63 - 1;MySQL的其他整形类型,转化到GaussDB-Oracle后类型为serial,所以起始值范围:1到2^31 - 1。
示例
CREATE TABLE test_table_auto_increment (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(50),
PRIMARY KEY (id)
) ENGINE=InnoDB;
-- 转换前MySQL SQL:
ALTER TABLE test_table_auto_increment AUTO_INCREMENT = 100;
-- 转换后GaussDB-Oracle SQL:
SELECT setval('test_table_auto_increment_id_seq', 100, FALSE)
1.3.3.4.1.11. 优化存储空间
语法
OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL]
TABLE TABLE_NAME [, TABLE_NAME] ...
警告
GaussDB-Oracle(V500)不支持OPTIMIZE TABLE语法,对应的语法为 VACUUM TABLE_NAME 且VACUUM只支持单表。
示例
--转化前转换前MySQL SQL:
OPTIMIZE LOCAL TABLE students,courses;
OPTIMIZE NO_WRITE_TO_BINLOG TABLE students,courses,enrollments;
--转化后GaussDB-Oracle SQL:
VACUUM students; VACUUM courses;
VACUUM students; VACUUM courses; VACUUM enrollments;
1.3.3.4.1.12. 删除表主键约束并创建新的主键约束
语法
ALTER TABLE TABLE_NAME DROP PRIMARY KEY, ADD PRIMARY KEY(COLUMN_NAME[,COLUMN_NAME]);
警告
GaussDB-Oracle(V500)不支持上述语法,需要拆分为两句sql并使用begin…end语句块将这两句sql作为整体执行。
删除的主键约束名称和新创建的主键约束名称使用GaussDB-Oracle(V500)默认的命名格式:table_name_pkey。
示例
--转化前转换前MySQL SQL:
ALTER TABLE parent_table DROP PRIMARY KEY, add PRIMARY KEY(parent_id);
--转化后GaussDB-Oracle SQL:
begin
ALTER TABLE parent_table DROP CONSTRAINT parent_table_pkey;
ALTER TABLE parent_table ADD CONSTRAINT parent_table_pkey PRIMARY KEY(parent_id);
end;
1.3.3.4.1.13. 删除表的索引
语法
DROP INDEX [IF EXISTS] INDEX_NAME ON TABLE_NAME
警告
转化需要开启元数据功能,如果由约束自动创建的索引,那么会转化成删除约束,否则会转化成普通删除索引;
源库的索引名称是表级别的全局唯一,而目标库GaussDB-Oracle505是模式级别的全局唯一,使用时需要源库那边保持索引名的模式级别的全局唯一,同时表中的约束名和索引名不要重名;
仅支持唯一索引、普通索引、复合索引的删除。
示例
--SQL准备
CREATE TABLE drop_index_table (
COLUMN1 INT AUTO_INCREMENT primary key COMMENT 'COLUMN1',
COLUMN2 VARCHAR(255) NOT NULL COMMENT 'COLUMN2',
COLUMN3 VARCHAR(50) NOT NULL COMMENT 'COLUMN3',
COLUMN4 INT COMMENT 'COLUMN4',
COLUMN5 INT COMMENT 'COLUMN5',
CONSTRAINT uq_drop_index_table_c2 UNIQUE (COLUMN2) COMMENT '唯一索引',
KEY idx_drop_index_table_column3 (COLUMN3) COMMENT 'KEY1'
) COMMENT = '用户信息表';
CREATE INDEX idx_drop_index_table_c4 ON drop_index_table(COLUMN4,COLUMN5);
--转化前转换前MySQL SQL:
DROP INDEX uq_drop_index_table_c2 on drop_index_table;
DROP INDEX idx_drop_index_table_column3 on drop_index_table;
DROP INDEX idx_drop_index_table_c4 on drop_index_table;
--转化后GaussDB-Oracle505.2 SQL:
ALTER TABLE drop_index_table DROP CONSTRAINT uq_drop_index_table_c2;
DROP INDEX idx_drop_index_table_column3;
DROP INDEX idx_drop_index_table_c4;
1.3.3.4.2. Oracle_19C
1.3.3.4.2.1. 创建普通表
语法
CREATE TABLE [IF NOT EXISTS] TABLE_NAME(
COLUMN_NAME1 DATATYPE [AUTO_INCREMENT] [DEFAULT ...] [ON UPDATE CURRENT_TIMESTAMP] [ZEROFILL]
[CHARSET | CHARACTER SET CHARSET_NAME] [COLLATE COLLATION_NAME] [COMMENT COMMENT_STRING]
[, ...]
[, PRIMARY KEY(COLUMN_NAME [, ...] [USING BTREE])]
[, INDEX INDEX_NAME(COLUMN_NAME [, ...] [USING BTREE])]
[, FULLTEXT [KEY] [FULL_INDEX_NAME](COLUMN_NAME [, ...])]
)
[ENGINE = ENGINE_NAME]
[[DEFAULT] CHARSET | CHARACTER SET [=] CHARSET_NAME]
[[DEFAULT] COLLATE [=] COLLATION_NAME]
[ROW_FORMAT [=] FORMAT_NAME]
[COMMENT [=] COMMENT_STRING]
[DELAY_KEY_WRITE [=] {0|1}]
[CHECKSUM [=] {0|1}]
警告
对于CHARACTER/CHARACTER SET、COLLATE、ROW_FORMAT、ENGINE、DELAY_KEY_WRITE、CHECKSUM可选字段,统一SQL均为语法支持,无实际功能; 支持创建前缀索引语法,无实际功能;
支持PRIMARY KEY、UNIQUE KEY、KEY、INDEX对象带备注,如对象没有指定名称则根据规则:表名_指定列(多个列间用下划线拼接)_后缀 生成对象名称,
说明:PRIMARY KEY后缀为 _pkey
、UNIQUE KEY后缀为 _key
、KEY和INDEX后缀为 _idx
;
FULLTEXT KEY转换为普通索引,转换后只支持普通索引,不支持全文索引功能,如果建表语句中fulltext key未指定索引名称,转换后会自动生成名称,名称格式为:tablename_columnname[_columnname]_idx。
不支持在text类型上建立索引;
不支持多个字段使用AUTO_INCREMENT属性;
如果字段类型是DATATIME/TIMESTAMP, 则DEFAULT 值不支持时间格式的字符串,如 DEFAULT ‘2023-01-01 00:00:00’;
oracle不支持约束和索引的注释,统一SQL转换后忽略了约束和索引上的注释;
不支持在double类型字段上使用AUTO_INCREMENT属性;
不支持针对单独某个列建多个索引;
示例
-- 转换前MySQL SQL:
CREATE TABLE IF NOT EXISTS test_table_123 (
id int AUTO_INCREMENT,
co1 varchar(20) DEFAULT 'abc' COMMENT 'this is a test column',
co2 text CHARSET utf8 COLLATE utf8_general_ci NOT NULL,
co3 timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
co4 numeric(5, 3) ZEROFILL,
co5 varchar(200) CHARACTER SET utf8,
co6 varchar(20),
PRIMARY KEY(id) USING BTREE,
INDEX idx_co12(co1) USING BTREE,
KEY idx_co5(co5),
FULLTEXT idx_fulltex_co2(co6)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET utf8
DEFAULT COLLATE=utf8_bin
ROW_FORMAT=COMPACT
COMMENT = 'this is test table';
-- 转换后Oracle_19C SQL:
CREATE TABLE test_table_123 (
id int GENERATED BY DEFAULT AS IDENTITY,
co1 varchar2(60) DEFAULT 'abc' ,
co2 clob NOT NULL,
co3 timestamp DEFAULT CURRENT_TIMESTAMP(0),
co4 numeric(5,3),
co5 varchar2(600),
co6 varchar2(60),
CONSTRAINT test_table_123_pkey PRIMARY KEY(id)
);
CREATE INDEX idx_co12 ON test_table_123 (co1);
CREATE INDEX idx_co5 ON test_table_123 (co5);
CREATE INDEX idx_fulltex_co2 ON test_table_123 (co6);
COMMENT ON TABLE test_table_123 IS 'this is test table';
COMMENT ON COLUMN test_table_123.co1 IS 'this is a test column';
-- 转换前MySQL SQL:
CREATE TABLE EXAMPLE_TABLE (
COLUMN1 INT AUTO_INCREMENT COMMENT 'COLUMN1',
COLUMN2 VARCHAR ( 255 ) NOT NULL COMMENT 'COLUMN2',
COLUMN3 VARCHAR ( 50 ) NOT NULL COMMENT 'COLUMN3',
COLUMN4 INT COMMENT 'COLUMN4',
COLUMN5 INT COMMENT 'COLUMN5',
COLUMN6 INT COMMENT 'COLUMN6',
COLUMN7 INT COMMENT 'COLUMN7',
COLUMN8 INT COMMENT 'COLUMN8',
COLUMN9 INT COMMENT 'COLUMN9',
COLUMN10 INT COMMENT 'COLUMN10',
PRIMARY KEY ( COLUMN1 ) COMMENT '主键 ',
UNIQUE KEY ( COLUMN2, COLUMN3, COLUMN4 ) COMMENT '唯一索引',
KEY ( COLUMN5 ) COMMENT 'KEY',
INDEX ( COLUMN6, COLUMN7, COLUMN8, COLUMN9, COLUMN10 ) COMMENT '索引'
) COMMENT = '用户信息表';
-- 转换后Oracle_19C SQL:
CREATE TABLE EXAMPLE_TABLE (
COLUMN1 int GENERATED BY DEFAULT AS IDENTITY ,
COLUMN2 varchar2(765) NOT NULL,
COLUMN3 varchar2(150) NOT NULL,
COLUMN4 int ,
COLUMN5 int ,
COLUMN6 int ,
COLUMN7 int ,
COLUMN8 int ,
COLUMN9 int ,
COLUMN10 int ,
CONSTRAINT example_table_pkey PRIMARY KEY(COLUMN1),
CONSTRAINT example_table_column2_column3_column4_key UNIQUE(COLUMN2, COLUMN3, COLUMN4)
);
CREATE INDEX example_table_column5_idx ON EXAMPLE_TABLE (COLUMN5);
CREATE INDEX example_table_column6_column7_column8_column9_column10_idx ON EXAMPLE_TABLE (COLUMN6, COLUMN7, COLUMN8, COLUMN9, COLUMN10);
COMMENT ON TABLE EXAMPLE_TABLE IS '用户信息表';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN1 IS 'COLUMN1';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN2 IS 'COLUMN2';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN3 IS 'COLUMN3';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN4 IS 'COLUMN4';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN5 IS 'COLUMN5';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN6 IS 'COLUMN6';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN7 IS 'COLUMN7';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN8 IS 'COLUMN8';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN9 IS 'COLUMN9';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN10 IS 'COLUMN10';
1.3.3.4.2.2. 修改普通表
语法
ALTER TABLE TABLE_NAME
[DROP PRIMARY KEY | INDEX INDEX_NAME]
| ADD [COLUMN] [IF NOT EXISTS] COLUMN_NAME DATATYPE [CHARACTER SET CHARSET_NAME] [COLLATE COLLATE_NAME] [DEFAULT ...] [COMMENT COMMENT_STRING]
| MODIFY [COLUMN] COLUMN_NAME DATATYPE [CHARACTER SET CHARSET_NAME] [COLLATE COLLATE_NAME] [DEFAULT ...] [COMMENT COMMENT_STRING]
| CHANGE [COLUMN] COLUMN_OLD_NAME COLUMN_NEW_NAME DATATYPE [CHARACTER SET CHARSET_NAME] [COLLATE COLLATE_NAME] [DEFAULT ...] [COMMENT COMMENT_STRING]
| ADD INDEX | KEY INDEX_NAME(COLUMN_NAME [, ...])
| RENAME INDEX | KEY INDEX_OLD_NAME TO INDEX_NEW_NAME
| CONVERT TO CHARACTER SET CHARSET_NAME
| COMMENT COMMENT_STRING
警告
ALTER TABLE…CONVERT TO CHARACTER SET…仅语法支持,无实际功能,且受配置参数控制,config/unisql.conf中unisql.replace.sql参数可配置需要替换的sql语句。
ALTER TABLE TABLE_NAME change 中 DATATYPE 为 double(p,s) 时转换为decimal(p,s),p、s参考数据类型章节; (numeric和decimal是等价的)。
ALTER TABLE TABLE_NAME change 中 DATATYPE 为 datetime 时转换为timestamp(0);(mysql datetime对应无精度的timestamp)。
ALTER TABLE TABLE_NAME MODIFY|CHANGE 在 Oracle_19C 中修改类型需要有类型转换逻辑,不是所有类型都支持转换,类型是否可以修改,需要遵循 Oracle_19C 的约束规则,比如blob类型修改成int不支持。
ALTER TABLE TABLE_NAME ADD 的IF NOT EXISTS 转化到Oracle_19C后被忽略,所以添加表中已经存在的列,在Oracle_19C执行会报错。
ALTER TABLE IF EXISTS TABLE_NAME MySQL 不支持该语法,在转换的时候报错。
ALTER TABLE 暂时支持一次修改一个属性,不支持使用逗号连接两个属性。
ALTER TABLE 表名、列名是关键字,使用反单引号引起来时,会转换成双引号。
ALTER TABLE DEFAULT 布尔类型 false 和 true 分别会被转换成 0 和 1; DEFAULT 表达式用双引号引起的,会转换成单引号引起来。
ALTER TABLE TABLE_NAME DROP INDEX INDEX_NAME 会被转换成 DROP INDEX INDEX_NAME。
ALTER TABLE TABLE_NAME DROP PRIMARY KEY 转换语句不改变。
ALTER TABLE TABLE_NAME 转换涉及类型,按照 MySQL 转 Oracle_19C 的逻辑。
ALTER TABLE TABLE_NAME CHARACTER SET 字符集设置,COLLATE 排序规则设置转换时会忽略。
ALTER TABLE TABLE_NAM ADD INDEX 会直接转换成 CREATE INDEX 语句。
如果字段类型是DATATIME/TIMESTAMP, 则DEFAULT 值不支持时间格式的字符串,如 DEFAULT ‘2023-01-01 00:00:00’。
示例
-- 转换前MySQL SQL:
ALTER TABLE test_table DROP PRIMARY KEY;
ALTER TABLE test_table DROP INDEX idx_co12;
ALTER TABLE test_table ADD COLUMN IF NOT EXISTS co5 VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT 'this is a comment';
ALTER TABLE test_table MODIFY COLUMN co5 text CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT 'test column' COMMENT 'this is another comment';
ALTER TABLE test_table CHANGE COLUMN co5 co5_new blob DEFAULT NULL COMMENT 'this is a new comment';
ALTER TABLE test_table ADD INDEX idx_co5(co5);
ALTER TABLE test_table ADD KEY idx_co5_another(co5);
ALTER TABLE test_table RENAME INDEX idx_co5 TO idx_co5_new;
ALTER TABLE test_table CONVERT TO CHARACTER SET utf8;
ALTER TABLE test_table COMMENT 'this is a new table comment';
ALTER TABLE test_table ADD COLUMN mediumintColumn mediumint DEFAULT 0 ;
ALTER TABLE employees ADD COLUMN nickname VARCHAR(50) DEFAULT "none";
ALTER TABLE employees ADD is_admin number(1,0) DEFAULT FALSE;
-- 转换后Oracle_19C SQL:
ALTER TABLE test_table DROP PRIMARY KEY;
DROP INDEX idx_co12;
ALTER TABLE test_table ADD co5 varchar2(20) DEFAULT NULL;
COMMENT ON COLUMN test_table.co5 IS 'this is a comment';
ALTER TABLE test_table ALTER COLUMN co5 text;
ALTER TABLE test_table ALTER COLUMN co5 DEFAULT 'test column';
COMMENT ON COLUMN test_table.co5 IS 'this is another comment';
ALTER TABLE test_table RENAME co5 TO co5_new;
ALTER TABLE test_table ALTER COLUMN co5_new bytea;
ALTER TABLE test_table ALTER COLUMN co5_new DEFAULT NULL;
COMMENT ON COLUMN test_table.co5_new IS 'this is a new comment';
CREATE INDEX idx_co5 ON test_table (co5);
CREATE INDEX idx_co5_another ON test_table (co5);
ALTER INDEX idx_co5 RENAME TO idx_co5_new;
-- unisql.replace.sql = 'select 1'
select 1;
COMMENT ON TABLE test_table IS 'this is a new table comment';
ALTER TABLE unisql_mediumint_test ADD mediumintColumn int DEFAULT 0;
1.3.3.4.2.3. 删除表
语法
DROP TABLE TABLE_NAME
示例
-- 转换前MySQL SQL:
DROP TABLE test_table;
-- 转换后Oracle_19C SQL:
DROP TABLE test_table;
1.3.3.4.2.4. 拷贝表结构
语法
CREATE TABLE [IF NOT EXISTS] TABLE_NAME LIKE TABLE_NAME
警告
Oracle_19C 不支持 IF NOT EXISTS,IF NOT EXISTS为语法糖会被直接删除
只拷贝表结构,表的约束,索引,自增序列,注释,主键,字符集不能拷贝
表名不支持大小写敏感,特殊字符,反引号大小写敏感
示例
-- 转换前MySQL SQL:
CREATE TABLE new_tbl LIKE orig_tbl;
-- 转换后Oracle_19C SQL:
CREATE TABLE new_tbl AS SELECT * FROM orig_tbl WHERE 1= 0;
1.3.3.4.3. OceanBase-Oracle
1.3.3.4.3.1. 创建普通表
语法
CREATE TABLE [IF NOT EXISTS] TABLE_NAME(
COLUMN_NAME1 DATATYPE [AUTO_INCREMENT] [DEFAULT ...] [ON UPDATE CURRENT_TIMESTAMP] [ZEROFILL]
[CHARSET | CHARACTER SET CHARSET_NAME] [COLLATE COLLATION_NAME] [COMMENT COMMENT_STRING]
[, ...]
[, PRIMARY KEY(COLUMN_NAME [, ...] [USING BTREE])]
[, INDEX INDEX_NAME(COLUMN_NAME [, ...] [USING BTREE])]
[, FULLTEXT [KEY] [FULL_INDEX_NAME](COLUMN_NAME [, ...])]
)
[AUTO_INCREMENT = number]
[ENGINE = ENGINE_NAME]
[[DEFAULT] CHARSET | CHARACTER SET [=] CHARSET_NAME]
[[DEFAULT] COLLATE [=] COLLATION_NAME]
[ROW_FORMAT [=] FORMAT_NAME]
[COMMENT [=] COMMENT_STRING]
[DELAY_KEY_WRITE [=] {0|1}]
[CHECKSUM [=] {0|1}]
警告
对于CHARACTER/CHARACTER SET、COLLATE、ROW_FORMAT、ENGINE、DELAY_KEY_WRITE、CHECKSUM可选字段,统一SQL均为语法支持,无实际功能; 支持创建前缀索引语法,无实际功能;
支持PRIMARY KEY、UNIQUE KEY、KEY、INDEX对象带备注,如对象没有指定名称则根据规则:表名_指定列(多个列间用下划线拼接)_后缀 生成对象名称,
说明:PRIMARY KEY后缀为 _pkey
、UNIQUE KEY后缀为 _key
、KEY和INDEX后缀为 _idx
;
FULLTEXT KEY转换为普通索引,转换后只支持普通索引,不支持全文索引功能,如果建表语句中fulltext key未指定索引名称,转换后会自动生成名称,名称格式为:tablename_columnname[_columnname]_idx。
不支持在text类型上建立索引;
不支持多个字段使用AUTO_INCREMENT属性;
如果字段类型是DATATIME/TIMESTAMP, 则DEFAULT 值不支持时间格式的字符串,如 DEFAULT ‘2023-01-01 00:00:00’;
OceanBase-Oracle不支持约束和索引的注释,统一SQL转换后忽略了约束和索引上的注释;
不支持在double类型字段上使用AUTO_INCREMENT属性;
不支持针对单独某个列建多个索引;
对于 AUTO_INCREMENT 建表选项,内部使用自定义序列,序列名命名方式为: UNISQL_AUTO_INCREMENT_SEQ_<object_id>. 统一 SQL 内部会修改 auto_increment 列使用序列的 NEXTVAL 作为默认值。
示例
-- 转换前MySQL SQL:
CREATE TABLE IF NOT EXISTS test_table_123 (
id int AUTO_INCREMENT,
co1 varchar(20) DEFAULT 'abc' COMMENT 'this is a test column',
co2 text CHARSET utf8 COLLATE utf8_general_ci NOT NULL,
co3 timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
co4 numeric(5, 3) ZEROFILL,
co5 varchar(200) CHARACTER SET utf8,
co6 varchar(20),
PRIMARY KEY(id) USING BTREE,
INDEX idx_co12(co1) USING BTREE,
KEY idx_co5(co5),
FULLTEXT idx_fulltex_co2(co6)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET utf8
DEFAULT COLLATE=utf8_bin
ROW_FORMAT=COMPACT
COMMENT = 'this is test table';
-- 转换后OceanBase-Oracle SQL:
CREATE TABLE test_table_123 (
id int GENERATED BY DEFAULT AS IDENTITY,
co1 varchar2(60) DEFAULT 'abc' ,
co2 clob NOT NULL,
co3 timestamp DEFAULT CURRENT_TIMESTAMP(0),
co4 numeric(5,3),
co5 varchar2(600),
co6 varchar2(60),
CONSTRAINT test_table_123_pkey PRIMARY KEY(id)
);
CREATE INDEX idx_co12 ON test_table_123 (co1);
CREATE INDEX idx_co5 ON test_table_123 (co5);
CREATE INDEX idx_fulltex_co2 ON test_table_123 (co6);
COMMENT ON TABLE test_table_123 IS 'this is test table';
COMMENT ON COLUMN test_table_123.co1 IS 'this is a test column';
-- 转换前MySQL SQL:
CREATE TABLE EXAMPLE_TABLE (
COLUMN1 INT AUTO_INCREMENT COMMENT 'COLUMN1',
COLUMN2 VARCHAR ( 255 ) NOT NULL COMMENT 'COLUMN2',
COLUMN3 VARCHAR ( 50 ) NOT NULL COMMENT 'COLUMN3',
COLUMN4 INT COMMENT 'COLUMN4',
COLUMN5 INT COMMENT 'COLUMN5',
COLUMN6 INT COMMENT 'COLUMN6',
COLUMN7 INT COMMENT 'COLUMN7',
COLUMN8 INT COMMENT 'COLUMN8',
COLUMN9 INT COMMENT 'COLUMN9',
COLUMN10 INT COMMENT 'COLUMN10',
PRIMARY KEY ( COLUMN1 ) COMMENT '主键 ',
UNIQUE KEY ( COLUMN2, COLUMN3, COLUMN4 ) COMMENT '唯一索引',
KEY ( COLUMN5 ) COMMENT 'KEY',
INDEX ( COLUMN6, COLUMN7, COLUMN8, COLUMN9, COLUMN10 ) COMMENT '索引'
) COMMENT = '用户信息表';
-- 转换后OceanBase-Oracle SQL:
CREATE TABLE EXAMPLE_TABLE (
COLUMN1 int GENERATED BY DEFAULT AS IDENTITY ,
COLUMN2 varchar2(765) NOT NULL,
COLUMN3 varchar2(150) NOT NULL,
COLUMN4 int ,
COLUMN5 int ,
COLUMN6 int ,
COLUMN7 int ,
COLUMN8 int ,
COLUMN9 int ,
COLUMN10 int ,
CONSTRAINT example_table_pkey PRIMARY KEY(COLUMN1),
CONSTRAINT example_table_column2_column3_column4_key UNIQUE(COLUMN2, COLUMN3, COLUMN4)
);
CREATE INDEX example_table_column5_idx ON EXAMPLE_TABLE (COLUMN5);
CREATE INDEX example_table_column6_column7_column8_column9_column10_idx ON EXAMPLE_TABLE (COLUMN6, COLUMN7, COLUMN8, COLUMN9, COLUMN10);
COMMENT ON TABLE EXAMPLE_TABLE IS '用户信息表';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN1 IS 'COLUMN1';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN2 IS 'COLUMN2';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN3 IS 'COLUMN3';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN4 IS 'COLUMN4';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN5 IS 'COLUMN5';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN6 IS 'COLUMN6';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN7 IS 'COLUMN7';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN8 IS 'COLUMN8';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN9 IS 'COLUMN9';
COMMENT ON COLUMN EXAMPLE_TABLE.COLUMN10 IS 'COLUMN10';
-- 转换前MySQL SQL:
create table t1(id int auto_increment primary key, name varchar(100)) auto_increment = 100;
-- 转换后OceanBase-Oracle SQL:
create table t1(id int primary key, name varchar(100));
call unisql.create_identity_column(SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA'), 'T1', 'ID', 100);
1.3.3.4.3.2. 创建分区表
语法
CREATE TABLE [IF NOT EXISTS] TABLE_NAME(
COLUMN_NAME1 DATATYPE [AUTO_INCREMENT] [DEFAULT ...] [ON UPDATE CURRENT_TIMESTAMP] [ZEROFILL]
[COLLATE COLLATION_NAME] [COMMENT COMMENT_STRING]
[, ...]
[, PRIMARY KEY(COLUMN_NAME [, ...] [USING BTREE])]
[, INDEX INDEX_NAME(COLUMN_NAME [, ...] [USING BTREE])]
)
PARTITION BY RANGE [COLUMNS](COLUMN_NAME)(
PARTITION PARTITION_NAME VALUES LESS THAN (VALUE_1)
[, ...]
)
警告
COLUMN_NAME支持的数据类型有int,tinyint,bigint,mediumint,date,datetime,char,varchar类型,其它数据类型不做处理
mysql数据库COLUMN_NAME支持函数,统一sql不支持
mysql数据库VALUE_1支持函数,统一sql不支持
mysql数据库COLUMN_NAME为date数据类型,VALUE_1支持字符串的格式大于统一SQL,统一sql只支持’YYYY-MM-DD’这种to_date函数可以使用的字符串
分区表区分名称,分区列名称不支持大小写敏感,特殊字符,反引号大小写敏感
示例
-- 转换前MySQL SQL:
CREATE TABLE IF NOT EXISTS test_table_partition(
id int,
sale_date date
)
PARTITION BY RANGE COLUMNS(id, sale_date)
(
PARTITION p0 VALUES LESS THAN (100, '2020-07-01'),
PARTITION p1 VALUES LESS THAN (200, '2021-07-01'),
PARTITION p2 VALUES LESS THAN (300, MAXVALUE)
);
-- 转换后OceanBase-Oracle SQL:
CREATE TABLE test_table_partition (
id int,
sale_date date
)
PARTITION BY RANGE (id,sale_date)
(
PARTITION p0 VALUES LESS THAN (100, to_date('2020-07-01', 'YYYY-MM-DD')),
PARTITION p1 VALUES LESS THAN (200, to_date('2021-07-01', 'YYYY-MM-DD')),
PARTITION p2 VALUES LESS THAN (300, MAXVALUE)
);
1.3.3.4.3.3. 修改普通表
语法
ALTER TABLE TABLE_NAME
[DROP PRIMARY KEY | INDEX INDEX_NAME]
| ADD [COLUMN] [IF NOT EXISTS] COLUMN_NAME DATATYPE [CHARACTER SET CHARSET_NAME] [COLLATE COLLATE_NAME] [DEFAULT ...] [COMMENT COMMENT_STRING]
| MODIFY [COLUMN] COLUMN_NAME DATATYPE [CHARACTER SET CHARSET_NAME] [COLLATE COLLATE_NAME] [DEFAULT ...] [COMMENT COMMENT_STRING]
| CHANGE [COLUMN] COLUMN_OLD_NAME COLUMN_NEW_NAME DATATYPE [CHARACTER SET CHARSET_NAME] [COLLATE COLLATE_NAME] [DEFAULT ...] [COMMENT COMMENT_STRING]
| ADD INDEX | KEY INDEX_NAME(COLUMN_NAME [, ...])
| RENAME INDEX | KEY INDEX_OLD_NAME TO INDEX_NEW_NAME
| CONVERT TO CHARACTER SET CHARSET_NAME
| COMMENT COMMENT_STRING
| AUTO_INCREMENT = number
警告
ALTER TABLE…CONVERT TO CHARACTER SET…仅语法支持,无实际功能,且受配置参数控制,config/unisql.conf中unisql.replace.sql参数可配置需要替换的sql语句。
ALTER TABLE TABLE_NAME change 中 DATATYPE 为 double(p,s) 时转换为decimal(p,s),p、s参考数据类型章节; (numeric和decimal是等价的)。
ALTER TABLE TABLE_NAME change 中 DATATYPE 为 datetime 时转换为timestamp(0);(mysql datetime对应无精度的timestamp)。
ALTER TABLE TABLE_NAME MODIFY|CHANGE 在 OceanBase-Oracle 中修改类型需要有类型转换逻辑,不是所有类型都支持转换,类型是否可以修改,需要遵循 OceanBase-Oracle 的约束规则,比如blob类型修改成int不支持。
ALTER TABLE TABLE_NAME ADD 的IF NOT EXISTS 转化到OceanBase-Oracle后被忽略,所以添加表中已经存在的列,在OceanBase-Oracle执行会报错。
ALTER TABLE IF EXISTS TABLE_NAME MySQL 不支持该语法,在转换的时候报错。
ALTER TABLE 暂时支持一次修改一个属性,不支持使用逗号连接两个属性。
ALTER TABLE 表名、列名是关键字,使用反单引号引起来时,会转换成双引号。
ALTER TABLE DEFAULT 布尔类型 false 和 true 分别会被转换成 0 和 1; DEFAULT 表达式用双引号引起的,会转换成单引号引起来。
ALTER TABLE TABLE_NAME DROP INDEX INDEX_NAME 会被转换成 DROP INDEX INDEX_NAME。
ALTER TABLE TABLE_NAME DROP PRIMARY KEY 转换语句不改变。
ALTER TABLE TABLE_NAME 转换涉及类型,按照 MySQL 转 OceanBase-Oracle 的逻辑。
ALTER TABLE TABLE_NAME CHARACTER SET 字符集设置,COLLATE 排序规则设置转换时会忽略。
ALTER TABLE TABLE_NAM ADD INDEX 会直接转换成 CREATE INDEX 语句。
如果字段类型是DATATIME/TIMESTAMP, 则DEFAULT 值不支持时间格式的字符串,如 DEFAULT ‘2023-01-01 00:00:00’。
修改 AUTO_INCREMENT 起始值时,如果下一个值就是要设置的新的起始值,则当前内部实现会导致下一次自动插入的值要比定义的起始值大1.
示例
-- 转换前MySQL SQL:
ALTER TABLE test_table DROP PRIMARY KEY;
ALTER TABLE test_table DROP INDEX idx_co12;
ALTER TABLE test_table ADD COLUMN IF NOT EXISTS co5 VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT 'this is a comment';
ALTER TABLE test_table MODIFY COLUMN co5 text CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT 'test column' COMMENT 'this is another comment';
ALTER TABLE test_table CHANGE COLUMN co5 co5_new blob DEFAULT NULL COMMENT 'this is a new comment';
ALTER TABLE test_table ADD INDEX idx_co5(co5);
ALTER TABLE test_table ADD KEY idx_co5_another(co5);
ALTER TABLE test_table RENAME INDEX idx_co5 TO idx_co5_new;
ALTER TABLE test_table CONVERT TO CHARACTER SET utf8;
ALTER TABLE test_table COMMENT 'this is a new table comment';
ALTER TABLE test_table ADD COLUMN mediumintColumn mediumint DEFAULT 0 ;
ALTER TABLE employees ADD COLUMN nickname VARCHAR(50) DEFAULT "none";
ALTER TABLE employees ADD is_admin number(1,0) DEFAULT FALSE;
-- 转换后OceanBase-Oracle SQL:
ALTER TABLE test_table DROP PRIMARY KEY;
DROP INDEX idx_co12;
ALTER TABLE test_table ADD co5 varchar2(20) DEFAULT NULL;
COMMENT ON COLUMN test_table.co5 IS 'this is a comment';
ALTER TABLE test_table ALTER COLUMN co5 text;
ALTER TABLE test_table ALTER COLUMN co5 DEFAULT 'test column';
COMMENT ON COLUMN test_table.co5 IS 'this is another comment';
ALTER TABLE test_table RENAME co5 TO co5_new;
ALTER TABLE test_table ALTER COLUMN co5_new bytea;
ALTER TABLE test_table ALTER COLUMN co5_new DEFAULT NULL;
COMMENT ON COLUMN test_table.co5_new IS 'this is a new comment';
CREATE INDEX idx_co5 ON test_table (co5);
CREATE INDEX idx_co5_another ON test_table (co5);
ALTER INDEX idx_co5 RENAME TO idx_co5_new;
-- unisql.replace.sql = 'select 1'
select 1;
COMMENT ON TABLE test_table IS 'this is a new table comment';
ALTER TABLE unisql_mediumint_test ADD mediumintColumn int DEFAULT 0;
-- 转换前MySQL SQL:
alter table t1 auto_increment = 200;
-- 转换后OceanBase-Oracle SQL:
call unisql.change_identity_column_nextval(SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA'), 'T1', 200);
1.3.3.4.3.4. 删除表
语法
DROP TABLE TABLE_NAME
示例
-- 转换前MySQL SQL:
DROP TABLE test_table;
-- 转换后OceanBase-Oracle SQL:
DROP TABLE test_table;
1.3.3.4.3.5. 创建用户
语法
CREATE USER USER_NAME@HOST_NAME IDENTIFIED BY PASSWORD
示例
-- 转换前MySQL SQL:
CREATE USER 'user1'@'localhost' IDENTIFIED BY '123456';
-- 转换后OceanBase-Oracle SQL:
CREATE USER "user1" IDENTIFIED BY "123456";
1.3.3.4.3.6. 修改用户
语法
ALTER USER USER_NAME@HOST_NAME
[IDENTIFIED BY NEW_PASSWORD]
| [ACCOUNT LOCK | UNLOCK]
示例
-- 转换前MySQL SQL:
ALTER USER 'user1'@'localhost' IDENTIFIED BY 'abc567890';
ALTER USER 'user1'@'localhost' ACCOUNT LOCK;
ALTER USER 'user1'@'localhost' ACCOUNT UNLOCK;
-- 转换后OceanBase-Oracle SQL:
ALTER USER "user1" IDENTIFIED BY "abc567890";
ALTER USER "user1" ACCOUNT LOCK;
ALTER USER "user1" ACCOUNT UNLOCK;
1.3.3.4.4. GaussDB-Mysql
1.3.3.4.4.1. 创建含注释的表
语法
CREATE TABLE table_name(
......
) comment [=] 'xxx';
示例
-- 转换前MySQL SQL:
CREATE TABLE employees (
id INT,
name varchar(100),
last_login TIMESTAMP(6)
) COMMENT "用户信息表";
-- 转换后GaussDB-Mysql SQL:
CREATE TABLE `employees` (
`id` bigint,
`name` varchar(100),
`last_login` timestamp(6)
) COMMENT = '用户信息表';
1.3.3.4.4.2. 创建含行格式的表
语法
CREATE TABLE table_name(
......
) ROW_FORMAT [=] rowformatname;
警告
M模式只支持DYNAMIC,COMPRESSED,REDUNDANT,COMPACT行格式,其它行格式不支持
M模式行格式转换后为语法糖,目标数据库执行不报错即可,不考虑功能实现
M模式GaussDB-Mysql创建数据库语法只支持505.2版本(需要设置unisql.target.database.version = 5050200),其它版本不支持
B模式中ROW_FORMAT仅支持DEFAULT、DYNAMIC、FIXED、COMPRESSED、REDUNDANT、COMPACT, 其他选项会语法解析报错
B模式中ROW_FORMAT做语法糖处理
GaussDB MySQL 505.2 版本 M模式 示例
-- 转换前MySQL SQL:
CREATE TABLE rowformat_51969 (
id INT,
name varchar(100)
) ROW_FORMAT REDUNDANT;
-- 转换后GaussDB-Mysql SQL:
CREATE TABLE `rowformat_51969` (`id` bigint,`name` varchar(100)) ROW_FORMAT = REDUNDANT;
GaussDB MySQL 505.2 版本 B模式 示例
-- 转换前MySQL SQL:
CREATE TABLE rowformat_test (
id INT,
name varchar(100)
) ROW_FORMAT REDUNDANT;
-- 转换后GaussDB-Mysql SQL:
CREATE TABLE `rowformat_test` (`id` int,`name` varchar(100));
1.3.3.4.4.3. 创建含fulltext key的表
语法
CREATE TABLE TABLE_NAME(
COLUMN_NAME DATATYPE [...]
[, ...]
[, FULLTEXT [KEY] [FULL_INDEX_NAME](COLUMN_NAME [, ...])]
)
警告
fulltext 只是转换成了普通索引
示例
-- 转换前MySQL SQL:
CREATE TABLE test_table(
id int ,
co1 varchar(20) DEFAULT 'abc' COMMENT 'this is a test column',
PRIMARY KEY(id),
FULLTEXT KEY idx_co1(co1)
)
-- 转换后GaussDB-Mysql SQL:
CREATE TABLE `test_table` (`id` bigint,`co1` varchar(20) DEFAULT 'abc' COMMENT 'this is a test column',PRIMARY KEY(`id`),INDEX `idx_co1`(`co1`))
1.3.3.4.4.4. 创建指定ENGINE的表
语法
CREATE TABLE table_name(
......
) ENGINE [=] enginename;
警告
ENGINE选项统一SQL不做转换, 原样输出, 在目标库是语法糖, 无实际功能;
指定ENGINE的功能只在505.2版本支持
示例
-- 转换前MySQL SQL:
CREATE TABLE test123 (
id INT
) ENGINE InnoDB;
-- 转换后GaussDB-Mysql SQL:
CREATE TABLE `test123` (`id` bigint) ENGINE = InnoDB;
1.3.3.4.4.5. 创建指定字符集和字符序的表
语法
CREATE TABLE table_name(
......
) DEFAULT CHARACTER SET charset_name COLLATE collation_name;
示例
-- 转换前MySQL SQL:
CREATE TABLE tb (
id INT
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 转换后GaussDB-Mysql SQL:
CREATE TABLE `tb` (`id` bigint) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
1.3.3.4.4.6. 整理表数据
语法
OPTIMIZE TABLE table_name [, table_name];
警告
OPTIMIZE的NO_WRITE_TO_BINLOG和LOCAL选项不支持
支持 GaussDB-Mysql M 和 GaussDB-Mysql B 模式
示例
-- 转换前MySQL SQL:
optimize table test_a_51969, test_b_51969;
-- 转换后GaussDB-Mysql SQL:
VACUUM `test_a_51969`;
VACUUM `test_b_51969`;
1.3.3.4.4.7. 创建数据库
语法
CREATE {DATABASE|SCHEMA} [IF NOT EXISTS] database_name [default character set xxx] [collate xxx];
警告
将create database转换成create schema,需要修改统一sql配置项unisql.change.database.to.schema=1
同一个sql语句转换在统一sql中存在缓存,如果实例不重启的话会命中缓存,不会走转换逻辑,所以改了参数也没有用
- GaussDB-Mysql M 模式
character目前只支持utf8,COLLATE只支持utf8_general_ci,其他character/collate透传,但是不保证执行成功和语义一致
只支持505.2版本,需要设置统一sql配置项unisql.target.database.version = 5050200
- GaussDB-Mysql B 模式(默认版本 505.2),关于如何确认目标库是否为 B 模式,具体参考:修改索引名称
create database语句 或者 create schema 语句 均
不支持
关键字if not existscreate database语句 ,
不支持
字符集(character set) 和 字符序(collate),语法糖处理,转换后的sql 去除字符集和字符序create schema 语句 ,
支持
字符集(character set) 和 字符序(collate)。
GaussDB-Mysql M 模式示例
-- 转换前MySQL SQL:
create database if not exists database2_51969 default character set utf8 collate utf8_general_ci;
-- 转换后GaussDB-Mysql SQL:
CREATE DATABASE IF NOT EXISTS `database2_51969` CHARACTER SET = utf8 COLLATE = utf8_general_ci;
-- 修改配置unisql.change.database.to.schema将create database转换成create schema
EXEC SET unisql.change.database.to.schema = 1
-- 转换前MySQL SQL:
create database if not exists database2_51969 default character set utf8 collate utf8_general_ci;
-- 转换后GaussDB-Mysql SQL:
CREATE SCHEMA IF NOT EXISTS `database2_51969` CHARACTER SET = utf8 COLLATE = utf8_general_ci;
GaussDB-Mysql B 模式示例
-- 转换前,统一sql配置项unisql.change.database.to.schema为0,转换逻辑:if not exists ,字符集和字符序,均语法糖处理
create database if not exists database_test default character set utf8 collate utf8_general_ci;
-- 转换后,
CREATE DATABASE `database_test`
-- 转换前,统一sql配置项unisql.change.database.to.schema为1
create database if not exists database_test default character set utf8 collate utf8_general_ci;
-- 转换后,目标库gaussdb mysql b模式,支持create schema语句中包含字符集或者字符序
CREATE SCHEMA `database_test` CHARACTER SET = utf8 COLLATE = utf8_general_ci
-- 转换前,统一sql配置项unisql.change.database.to.schema为1
create schema if not exists database_test_1 default character set utf8 collate utf8_general_ci;
-- 转换后,目标库gaussdb mysql b模式,支持create schema语句中包含字符集或者字符序
CREATE SCHEMA `database_test_1` CHARACTER SET = utf8 COLLATE = utf8_general_ci
1.3.3.4.4.8. 切库
语法
use database_name ;
警告
统一sql参数配置
unisql.change.database.to.schema:控制数据库相关语句的转换行为
值为 0:原样透传,不进行转换
值为 1:启用以下转换规则
-- 示例: USE DATABASE转换,unisql.change.database.to.schema=1 use acm; -- 转换后: SET SCHEMA 'acm';
缓存注意事项
同一个SQL语句转换在统一SQL中存在缓存,如果实例不重启,会命中缓存而不触发转换逻辑,此时修改参数无效。
版本与模式限制
切库语句(use database_name),只支持GaussDB-Mysql B模式(默认版本 505.2),目标库B模式确认方法参考:修改索引名称
GaussDB-Mysql B 模式示例
-- 转换前USE DATABASE,unisql.change.database.to.schema=1
use acm;
-- 转换后GaussDB-Mysql B模式 SQL:
SET SCHEMA 'acm';
1.3.3.4.4.9. 删除数据库
语法
DROP {DATABASE|SCHEMA} [IF EXISTS] database_name;
警告
将drop database转换成drop schema,需要修改配置unisql.change.database.to.schema为1
同一个sql语句转换在统一sql中存在缓存,如果实例不重启的话会命中缓存,不会走转换逻辑,所以改了参数也没有用
GaussDB-Mysql系(B模式或者M模式)删除数据库语法只支持505.2版本(需要设置unisql.target.database.version = 5050200),其它版本不支持
目标库支持GaussDB-Mysql B模式和GaussDB-Mysql M模式,关于如何确认目标库是否为 B 模式,具体参考:修改索引名称
示例
-- 转换前MySQL SQL:
drop database database_test1;
-- 转换后GaussDB-Mysql SQL:
DROP DATABASE `database_test1`;
-- 修改配置unisql.change.database.to.schema将drop database转换成drop schema
EXEC SET unisql.change.database.to.schema = 1
-- 转换前MySQL SQL:
drop database database_test1;
-- 转换后GaussDB-Mysql SQL:
DROP SCHEMA `database_test1` CASCADE;
1.3.3.4.4.10. 设置外键约束
语法
SET FOREIGN_KEY_CHECKS = {0 | 1}
警告
其中 0 表示禁用外键约束, 1 表示启用外键约束; 在GaussDB 505.2版本支持
示例
-- 转换前MySQL SQL:
SET FOREIGN_KEY_CHECKS = 0;
SET FOREIGN_KEY_CHECKS = 1;
-- 转换后GaussDB-Mysql SQL:
SET FOREIGN_KEY_CHECKS=0;
SET FOREIGN_KEY_CHECKS=1;
1.3.3.4.4.11. 修改用户
语法
ALTER USER USER_NAME@HOST_NAME
[IDENTIFIED BY NEW_PASSWORD]
| [ACCOUNT LOCK | UNLOCK]
示例
-- 转换前MySQL SQL:
ALTER USER 'user1'@'localhost' IDENTIFIED BY 'abc567890';
ALTER USER 'user1'@'localhost' ACCOUNT LOCK;
ALTER USER 'user1'@'localhost' ACCOUNT UNLOCK;
-- 转换后GaussDB-Mysql SQL:
ALTER USER `user1` IDENTIFIED BY 'abc567890';
ALTER USER `user1` ACCOUNT LOCK;
ALTER USER `user1` ACCOUNT UNLOCK;
1.3.3.4.4.12. 转换表的字符集和排序规则
语法
ALTER TABLE table_name CONVERT TO CHARACTER SET charset_name [COLLATE collation_name];
警告
支持的字符集 utf8、utf8mb4、utf8mb3、latin1、binary、gbk
支持的字符序 utf8mb4_unicode_ci, utf8mb4_general_ci, latin1_swedish_ci…
字符集自动转换 utf8mb3转换后是utf8
字符序自动转换 utf8mb3_bin 转换后是utf8_bin
其他字符集(比如utf16、gb18030、big5),统一sql解析报错
字符集与字符序不匹配的情况,比如ALTER TABLE t15 CONVERT TO CHARACTER SET latin1 COLLATE utf8mb4_unicode_ci;字符集latin1和utf8mb4_unicode_ci,统一sql透传,但在目标库执行报错
示例
-- 转换前,仅转换字符集(无COLLATE)
ALTER TABLE legacy_data CONVERT TO CHARACTER SET utf8mb4;
-- 转换后
ALTER TABLE `legacy_data` CONVERT TO CHARACTER SET utf8mb4;
-- 转换前,转换字符集+COLLATE(支持的情况)
ALTER TABLE legacy_data CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 转换后
ALTER TABLE `legacy_data` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 转换前,不支持的字符集(utf16)→ 直接报错
ALTER TABLE `tbl_data` CONVERT TO CHARACTER SET utf16;
-- 转换结果
[ERROR] Unsupported character set: utf16
-- 转换前,不支持的字符集(ascii)→ 直接报错
ALTER TABLE `tbl_data` CONVERT TO CHARACTER SET ascii;
-- 转换结果
[ERROR] Unsupported character set: ascii
-- 转换前,不支持的字符集(gb18030)→ 直接报错
ALTER TABLE t2 CONVERT TO CHARACTER SET gb18030;
-- 转换结果
[ERROR] Unsupported character set: gb18030
-- 转换前,字符序gb18030_chinese_ci
ALTER TABLE `tbl_data` COLLATE gb18030_chinese_ci;
-- 转换后
ALTER TABLE `tbl_data` DEFAULT COLLATE = gb18030_chinese_ci;
-- 转换前,字符集自动转换(utf8mb3 → utf8)
ALTER TABLE old_table CONVERT TO CHARACTER SET utf8mb3;
-- 转换后
ALTER TABLE `old_table` CONVERT TO CHARACTER SET utf8;
-- 转换前,COLLATE自动转换(utf8mb3_bin → utf8_bin)
ALTER TABLE case_sensitive_table CONVERT TO CHARACTER SET utf8 COLLATE utf8mb3_bin;
-- 转换后
ALTER TABLE `case_sensitive_table` CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin;
-- 转换前,字符集与COLLATE不匹配(latin1 + utf8mb4_unicode_ci)→ 语法透传但目标库报错
ALTER TABLE t15 CONVERT TO CHARACTER SET latin1 COLLATE utf8mb4_unicode_ci;
-- 转换后
ALTER TABLE `t15` CONVERT TO CHARACTER SET latin1 COLLATE utf8mb4_unicode_ci;
1.3.3.4.4.13. 为表添加列
语法
ALTER TABLE table_name
ADD [COLUMN] [IF NOT EXISTS]
col_name column_definition
[ FIRST | AFTER existing_column];
| ADD [COLUMN] [IF NOT EXISTS] (col_name column_definition, [...])
column_definition:
- data_type
- [NOT NULL | NULL] [DEFAULT default_value]
- [ON UPDATE CURRENT_TIMESTAMP]
- [AUTO_INCREMENT] [ZEROFILL] [UNIQUE [KEY]] [PRIMARY KEY]
- COMMENT 'string'
警告
GaussDB MySQL 505.2 版本 M模式,不支持 IF NOT EXISTS和ZEROFILL ,统一sql语法糖处理,源sql包含,转换后没有;依赖统一sql配置项unisql.target.database.version,举例unisql.target.database.version=5050200,表示配置数据库版本505.2
- GaussDB MySQL 505.2 版本 B模式,
语法格式 ADD [COLUMN] [IF NOT EXISTS] col_name column_definition [ FIRST | AFTER existing_column],
支持
关键字 IF NOT EXISTS语法格式 ADD [COLUMN] [IF NOT EXISTS] (col_name column_definition, […])
不支持
关键字 IF NOT EXISTS,语法糖处理,转换后去掉IF NOT EXISTS,举例 alter table employees_11 add if not exists (phone11 varchar(20))ZEROFILL ,统一sql语法糖处理,源sql包含,转换后没有
如何确定当前目标库是gaussdb mysql的B模式具体参考: 修改索引名称 中说明
添加列,数据类型,函数以当前统一sql转换的实现为主。
GaussDB MySQL 505.2 版本 M模式 示例
-- 转换前,添加单列(带默认值,非空约束和位置信息)
ALTER TABLE user_info ADD COLUMN email VARCHAR(100) NOT NULL DEFAULT 'unknown@example.com' AFTER username;
-- 转换后
ALTER TABLE `user_info` ADD `email` varchar(100) NOT NULL DEFAULT 'unknown@example.com' AFTER `username`
-- 转换前,添加多列(含不同属性)
ALTER TABLE user_info
ADD (
age TINYINT UNSIGNED ZEROFILL NULL DEFAULT 18 COMMENT '年龄',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(3)
);
-- 转换后,添加多列(含不同属性)
ALTER TABLE `user_info` ADD (`age` tinyint NULL DEFAULT 18 COMMENT '年龄', `created_at` datetime DEFAULT CURRENT_TIMESTAMP(), `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP(3))
-- 转换前,if not exists 防止重复添加
ALTER TABLE user_info ADD COLUMN IF NOT EXISTS mobile CHAR(11) AFTER age;
--转换后
ALTER TABLE `user_info` ADD `mobile` char(11) AFTER `age`
GaussDB MySQL 505.2 版本 B模式 示例
转换前
-- 转换前,添加单列(带默认值、非空约束和位置信息)
ALTER TABLE user_info ADD COLUMN email VARCHAR(100) NOT NULL DEFAULT 'unknown@example.com' AFTER username;
-- 转换前,IF NOT EXISTS 防止重复添加
ALTER TABLE user_info ADD COLUMN IF NOT EXISTS mobile CHAR(11) AFTER age;
-- 转换前,添加单列(带属性和注释)
ALTER TABLE user_info ADD COLUMN IF NOT EXISTS ( age TINYINT UNSIGNED ZEROFILL NULL DEFAULT 18 COMMENT '年龄' );
-- 转换前,添加多列(含不同属性)
ALTER TABLE user_info
ADD (
age TINYINT UNSIGNED ZEROFILL NULL DEFAULT 18 COMMENT '年龄',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(3)
);
转换后
ALTER TABLE `user_info` ADD `email` varchar(100) NOT NULL DEFAULT 'unknown@example.com' AFTER `username`
ALTER TABLE `user_info` ADD IF NOT EXISTS `mobile` char(11) AFTER `age`
ALTER TABLE `user_info` ADD (`age` tinyint NULL DEFAULT 18 COMMENT '年龄')
ALTER TABLE `user_info` ADD (`age` tinyint NULL DEFAULT 18 COMMENT '年龄', `created_at` datetime DEFAULT CURRENT_TIMESTAMP(), `updated_at` timestamp(6) DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP(3))
1.3.3.4.4.14. 为表添加索引
语法
ALTER TABLE table_name
ADD [UNIQUE] [INDEX|KEY] [IF NOT EXISTS] [index_name]
[index_type] (index_col_name,...) [index_option] ...
解释:
[index_type]表示索引类型
index_type:
USING {BTREE}
[index_option]表示其他索引选项
index_option:
COMMENT 'string'
警告
`IF NOT EXISTS` 支持情况:
GaussDB MySQL 505.2 版本(M模式)不支持 IF NOT EXISTS 。统一 SQL 层会将其作为语法糖处理(源 SQL 包含该语法,但转换后的 SQL 会移除)。
需通过
unisql.target.database.version=5050200
显式指定目标数据库版本(5050200 表示 505.2)。
GaussDB MySQL 505.2 版本(B模式,默认版本505.2)支持 IF NOT EXISTS 语法。关于如何确认目标库是否为 B 模式,具体参考:修改索引名称
GaussDB MySQL B 模式(默认版本 505.2 )语法兼容性:
经过统一sql转换后语法格式CREATE [UNIQUE] INDEX index_name ON table (col1,col2…) COMMENT ‘xxx’
统一sql会将全文索引转换为普通索引
索引类型
BTREE
经过统一sql转换后为空,在目标库GaussDB MySQL B 模式(默认版本505.2)默认索引类型为BTREE
索引的功能和用途限制: 仅支持 普通索引(INDEX|KEY),唯一索引(UNIQUE INDEX),全文索引(Fulltext),其他索引统一sql解析报错,比如空间索引(Spatial)。
索引类型限制: 仅支持
BTREE
索引类型,尝试使用HASH
或其他类型,统一sql解析报错。索引选项处理规则:
索引选项(如
COMMENT
、VISIBLE
、INVISIBLE
)会透传到执行层,但在目标库 GaussDB for MySQL 505.2 版本(不论M模式还是B模式)中,使用VISIBLE
和INVISIBLE
时会出现语法错误,而COMMENT
选项则可以正常使用。不支持的索引选项包括:
KEY_BLOCK_SIZE
WITH PARSER
CLUSTERING
IGNORED
NOT IGNORED
以上索引选项在该环境下统一 SQL 解析会报错。
示例gaussdb mysql 505.2 M模式
-- 转换前,1. 添加普通单列索引
ALTER TABLE employees ADD INDEX idx_last_name (last_name);
-- 转换后
ALTER TABLE `employees` ADD INDEX `idx_last_name`(`last_name`)
-- 转换前,2. 添加唯一索引(多列)
ALTER TABLE employees ADD UNIQUE uidx_name_dob (first_name, date_of_birth);
-- 转换后
ALTER TABLE `employees` ADD UNIQUE `uidx_name_dob` (`first_name`, `date_of_birth`)
-- 转换前,3. 使用IF NOT EXISTS,避免重复
ALTER TABLE employees ADD KEY IF NOT EXISTS idx_salary (salary);
-- 转换后
ALTER TABLE `employees` ADD INDEX `idx_salary`(`salary`)
-- 转换前,4. 指定索引类型(如 USING BTREE)
ALTER TABLE employees ADD INDEX idx_email USING BTREE (email);
-- 转换后
ALTER TABLE `employees` ADD INDEX `idx_email`(`email`) USING BTREE
-- 转换前,5. 添加带索引选项(如COMMENT)
ALTER TABLE employees ADD UNIQUE INDEX idx_department (department_id) COMMENT 'Index for department ID';
-- 转换后
ALTER TABLE `employees` ADD UNIQUE `idx_department`(`department_id`) COMMENT 'Index for department ID'
-- 转换前,6.为表employees添加不可见索引
ALTER TABLE employees ADD INDEX idx_salary (salary) INVISIBLE;
-- 转换后
ALTER TABLE `employees` ADD INDEX `idx_salary`(`salary`) INVISIBLE
-- 转换前,7. 添加索引,不指定索引名称
ALTER TABLE users ADD INDEX (email);
-- 转换后
ALTER TABLE `users` ADD INDEX(`email`)
-- 转换前,8. 使用关键字 UNIQUE INDEX IF NOT EXISTS
ALTER TABLE employees ADD UNIQUE INDEX IF NOT EXISTS(name);
-- 转换后
ALTER TABLE `employees` ADD UNIQUE (`name`)
示例gaussdb mysql 505.2 B模式
-- 转换前
ALTER TABLE employees ADD INDEX idx_last_name (last_name);
ALTER TABLE employees ADD UNIQUE uidx_name_dob (first_name, date_of_birth);
ALTER TABLE employees ADD KEY IF NOT EXISTS idx_salary (salary);
ALTER TABLE employees ADD INDEX idx_email USING BTREE (email);
ALTER TABLE employees ADD UNIQUE INDEX idx_department (department_id) COMMENT 'Index for department ID';
ALTER TABLE employees ADD INDEX idx_salary (salary) INVISIBLE;
ALTER TABLE users ADD INDEX (email);
ALTER TABLE employees ADD UNIQUE INDEX IF NOT EXISTS(name);
-- 转换后
CREATE INDEX `idx_last_name` ON `employees` (`last_name`)
CREATE UNIQUE INDEX `uidx_name_dob` ON `employees` (`first_name`, `date_of_birth`)
CREATE INDEX IF NOT EXISTS `idx_salary` ON `employees` (`salary`)
CREATE INDEX `idx_email` ON `employees` (`email`)
CREATE UNIQUE INDEX `idx_department` ON `employees` (`department_id`) COMMENT 'Index for department ID'
CREATE INDEX `idx_salary` ON `employees` (`salary`) INVISIBLE
CREATE INDEX ON `users` (`email`)
CREATE UNIQUE INDEX IF NOT EXISTS ON `employees` (`name`)
1.3.3.4.4.15. alter table 支持 ignore和if exists
语法
ALTER [IGNORE] TABLE [IF EXISTS] table_name xxx;
其中xxx支持:
添加列(ADD [COLUMN]),
修改列 (CHANGE [COLUMN]),
删除列 (DROP [COLUMN]),
添加索引 (ADD {INDEX|KEY}),
转换字符集和字符序(CONVERT TO CHARACTER SET charset_name [COLLATE collation_name])等
警告
`IF EXISTS` 和 `IGNORE` 支持情况:
GaussDB MySQL 505.2 版本(M模式)不支持 IF EXISTS 和 IGNORE。统一 SQL 层会将其作为语法糖处理(源 SQL 包含该语法,但转换后的 SQL 会移除)。
GaussDB MySQL 505.2 版本(B模式,默认版本505.2)不支持 IGNORE ,支持 IF EXISTS。IGNORE 语法糖处理,转换后的sql去除 IGNORE 。如何确定当前目标库是gaussdb mysql的B模式具体参考: 修改索引名称 中说明
依赖配置项: GaussDB MySQL 505.2 版本(M模式),需通过
unisql.target.database.version=5050200
显式指定目标数据库版本(5050200 表示 505.2)。
GaussDB MySQL 505.2 版本(M模式)示例
-- 转换前,alter table 使用关键字 ignore 和 if exists,添加唯一索引
ALTER IGNORE TABLE IF EXISTS employees ADD UNIQUE INDEX idx_email (email);
-- 转换后
ALTER TABLE `employees` ADD UNIQUE `idx_email` (`email`)
-- 转换前,alter table 使用关键字 IF EXISTS 添加列
ALTER TABLE IF EXISTS employees ADD COLUMN department VARCHAR(50) AFTER last_name;
-- 转换后
ALTER TABLE `employees` ADD `department` varchar(50) AFTER `last_name`
-- 转换前,alter table 使用关键字 ignore ,添加索引
ALTER IGNORE TABLE employees ADD INDEX idx_username (username);
-- 转换后
ALTER TABLE `employees` ADD INDEX `idx_username`(`username`)
-- 转换前,alter table 删除hire_date列
ALTER TABLE employees DROP COLUMN hire_date;
-- 转换后
ALTER TABLE `employees` DROP COLUMN `hire_date`
GaussDB MySQL 505.2 版本(B模式)示例
转换前SQL
-- alter table 使用关键字 if exists,添加唯一索引
ALTER IGNORE TABLE IF EXISTS employees ADD UNIQUE INDEX idx_email (email);
-- alter table 使用关键字 IF EXISTS 添加列
ALTER TABLE IF EXISTS employees ADD COLUMN department VARCHAR(50) AFTER last_name;
-- alter table if exists table_name 修改列
ALTER TABLE IF EXISTS employees change COLUMN department department_2 VARCHAR(50) AFTER last_name;
-- alter table 使用关键字 ignore ,添加索引
ALTER IGNORE TABLE employees ADD INDEX idx_username (username);
-- alter table 删除hire_date列
ALTER TABLE employees DROP COLUMN hire_date;
转换后SQL
CREATE UNIQUE INDEX `idx_email` ON `employees` (`email`)
ALTER TABLE IF EXISTS `employees` ADD `department` varchar(50) AFTER `last_name`
ALTER TABLE IF EXISTS `employees` CHANGE COLUMN `department` `department_2` varchar(50) AFTER `last_name`
CREATE INDEX `idx_username` ON `employees` (`username`)
ALTER TABLE `employees` DROP COLUMN `hire_date`
1.3.3.4.4.16. 修改现有列
语法
ALTER TABLE table_name
CHANGE [COLUMN] [IF EXISTS] old_column new_column column_definition
[ FIRST | AFTER existing_column];
column_definition:
- data_type数据类型
- [NOT NULL | NULL] [DEFAULT default_value]
- [ON UPDATE CURRENT_TIMESTAMP]
- [AUTO_INCREMENT] [ZEROFILL] [UNIQUE [KEY]] [PRIMARY KEY]
- COMMENT 'string'
警告
- GaussDB MySQL 505.2 版本(M模式)
不支持
IF EXISTS和ZEROFILL ,统一sql语法糖处理,源sql包含,转换后没有。依赖统一sql配置项unisql.target.database.version,举例unisql.target.database.version=5050200,表示配置数据库版本505.2
GaussDB MySQL 505.2 版本(B模式,默认505.2版本)
不支持
IF EXISTS,不支持
zerofill,zerofill 统一sql语法糖处理, 如何确定当前目标库是gaussdb mysql的B模式具体参考: 修改索引名称 中说明修改列,数据类型,函数以当前统一sql转换的实现为主。
GaussDB MySQL 505.2 版本(M模式)示例
-- 转换前,重命名列
ALTER TABLE users CHANGE COLUMN old_username new_username VARCHAR(50) NOT NULL DEFAULT 'guest' AFTER id;
-- 转换后
ALTER TABLE `users` CHANGE COLUMN `old_username` `new_username` varchar(50) NOT NULL DEFAULT 'guest' AFTER `id`
-- 转换前,修改列数据类型(这里没有使用关键字COLUMN)
ALTER TABLE orders CHANGE order_date order_date DATETIME NOT NULL;
-- 转换后
ALTER TABLE `orders` CHANGE COLUMN `order_date` `order_date` datetime NOT NULL
-- 转换前,调整列位置,这里使用了关键字COLUMN 和 if exists
ALTER TABLE products CHANGE COLUMN if exists price price DECIMAL(10,2) AFTER product_name;
-- 转换后
ALTER TABLE `products` CHANGE COLUMN `price` `price` decimal(10,2) AFTER `product_name`
-- 转换前,修改多列
ALTER TABLE legacy_data CHANGE COLUMN name name VARCHAR(30) NOT NULL,CHANGE COLUMN id id INT DEFAULT 0 COMMENT '年龄' AFTER name;
-- 转换后
ALTER TABLE `legacy_data` CHANGE COLUMN `name` `name` varchar(30) NOT NULL, CHANGE COLUMN `id` `id` int DEFAULT 0 COMMENT '年龄' AFTER `name`
-- 转换前,修改列属性增加ZEROFILL
ALTER TABLE test_table CHANGE COLUMN id id INT ZEROFILL
-- 转换后
ALTER TABLE `test_table` CHANGE COLUMN `id` `id` int
-- 转换前,修改列属性CURRENT_TIMESTAMP带精度
ALTER TABLE test_table CHANGE COLUMN order_date order_date TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)
-- 转换后
ALTER TABLE `test_table` CHANGE COLUMN `order_date` `order_date` timestamp DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP(3)
GaussDB MySQL 505.2 版本(B模式)示例
转换前 SQL 语句:
-- 重命名列
ALTER TABLE users
CHANGE COLUMN old_username new_username VARCHAR(50) NOT NULL DEFAULT 'guest'
AFTER id;
-- 修改列数据类型(这里没有使用关键字 COLUMN )
ALTER TABLE orders
CHANGE order_date order_date DATETIME NOT NULL;
-- 调整列位置,这里使用了关键字 COLUMN 和 if exists
ALTER TABLE products
CHANGE COLUMN if exists price price DECIMAL(10,2)
AFTER product_name;
-- 修改多列
ALTER TABLE legacy_data
CHANGE COLUMN name name VARCHAR(30) NOT NULL,
CHANGE COLUMN id id INT DEFAULT 0 COMMENT '年龄'
AFTER name;
-- 修改列属性增加 ZEROFILL
ALTER TABLE test_table
CHANGE COLUMN id id INT ZEROFILL;
-- 修改列属性 CURRENT_TIMESTAMP 带精度
ALTER TABLE test_table
CHANGE COLUMN order_date order_date TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3);
转换后 SQL 语句:
ALTER TABLE `users` CHANGE COLUMN `old_username` `new_username` varchar(50) NOT NULL DEFAULT 'guest' AFTER `id`
ALTER TABLE `orders` CHANGE COLUMN `order_date` `order_date` datetime NOT NULL
ALTER TABLE `products` CHANGE COLUMN `price` `price` decimal(10,2) AFTER `product_name`
ALTER TABLE `legacy_data` CHANGE COLUMN `name` `name` varchar(30) NOT NULL, CHANGE COLUMN `id` `id` bigint DEFAULT 0 COMMENT '年龄' AFTER `name`
ALTER TABLE `test_table` CHANGE COLUMN `id` `id` bigint
ALTER TABLE `test_table` CHANGE COLUMN `order_date` `order_date` timestamp(3) ON UPDATE CURRENT_TIMESTAMP(3)
1.3.3.4.4.17. 修改表给表加注释
语法
ALTER TABLE table_name COMMENT [=] xxx; -- xxx表示注释内容
警告
GaussDB MySQL 505.2 版本支持的表注释的内容长度<=2048
GaussDB MySQL 505.2 版本支持的表注释的内容支持常见的特殊字符,比如COMMENT = ‘表!@#$%^&*()_+-=[]{}| ;:”,.<>?/~’
GaussDB MySQL 505.2 版本支持的表注释的内容支持多语言字符,比如 COMMENT ‘员工表(中文) 테이블(韩文) テーブル(日文) Таблица(俄文)’
GaussDB MySQL 505.2 版本支持的表注释的内容支持Emoji 表情,比如 COMMENT = ‘员工信息表 😊👍🌟’
示例
-- 包含转义字符
ALTER TABLE employees COMMENT 'Line1\nLine2\tTab\\Backslash';
--转换后
ALTER TABLE `employees` COMMENT = 'Line1\nLine2\tTab\\Backslash'
-- 包含Emoji表情
ALTER TABLE employees COMMENT '员工信息表 😊👍🌟';
--转换后
ALTER TABLE `employees` COMMENT = '员工信息表 😊👍🌟'
-- 包含常见特殊字符
ALTER TABLE employees COMMENT = '表!@#$%^&*()_+-=[]{}|;:",.<>?/`~';
-- 转换后
ALTER TABLE `employees` COMMENT = '表!@#$%^&*()_+-=[]{}| ;:",.<>?/~'
-- 多语言字符
ALTER TABLE employees COMMENT '员工表(中文) 테이블(韩文) テーブル(日文) Таблица(俄文)';
--转换后
ALTER TABLE `employees` COMMENT = '员工表(中文) 테이블(韩文) テーブル(日文) Таблица(俄文)'
-- 包含SQL特殊字符
ALTER TABLE employees COMMENT 'DROP TABLE users; -- 测试注入';
-- 转换后
ALTER TABLE `employees` COMMENT = 'DROP TABLE users; -- 测试注入'
-- 缺少引号
ALTER TABLE employees COMMENT abcdef;
-- 转换后
ALTER TABLE `employees` COMMENT = 'abcdef'
1.3.3.4.4.18. 修改索引名称
语法
ALTER TABLE [IF EXISTS] schema_name.tbl_name
RENAME {INDEX|KEY} old_index_name TO new_index_name
警告
索引名称长度限制:GaussDB MySQL 505.2 版本的索引名称最大支持 63 个字符。若源 SQL(MariaDB)中索引名称为 64 个字符(其最大支持长度为 64),导入至 GaussDB MySQL 505.2 时会自动截取前 63 个字符,超出部分将被截断。
特殊字符处理:GaussDB MySQL 505.2 版本不支持直接使用
!@#$%^&*
等特殊字符作为标识符。若需使用,需用反引号(`)包裹转义。- M 模式语法兼容性:
GaussDB MySQL 505.2 版本的 M 模式,
不支持
ALTER TABLE 后有关键字IF EXISTS
。SQL 转换时会统一处理此类语法糖,源 SQL 中的IF EXISTS
语句转换后将被移除。依赖统一 SQL 配置项
unisql.target.database.version
,例如设置为5050200
表示目标数据库版本为 505.2。
- B 模式语法兼容性:
- GaussDB MySQL 505.2 版本的 B 模式(默认版本505.2), 源SQL语法 ALTER TABLE [IF EXISTS] schema_name.tbl_name RENAME {INDEX|KEY} old_index_name TO new_index_name 转换后语法是 ALTER INDEX schema_name.old_index_name RENAME TO new_index_name;
进一步解释 ALTER INDEX schema_name.old_index_name RENAME TO new_index_name; 这种语法,明确指定了要重命名的索引 old_index_name 所在的模式为 schema_name。重命名操作仅仅是改变索引的名称,并不会改变索引所属的模式(schema_name)。
GaussDB MySQL 505.2 版本的 B 模式(默认版本505.2),
不支持
在一个ALTER TABLE语句中混合操作,具体举例,alter table 语句同时进行修改索引名称和添加列,ALTER TABLE rename_index_55716 RENAME INDEX idx_name_no TO idx_name_new,ADD COLUMN age INT;
B 模式索引规则:GaussDB MySQL B 模式(默认版本505.2),索引名称在具体数据库下同一 Schema(模式)内需唯一。
如何判断gaussdb mysql 是否是B 模式:可通过以下 SQL 查看当前gaussdb mysql的模式:
SHOW SQL_COMPATIBILITY;
示例输出:
+-------------------+ | sql_compatibility | +-------------------+ | B | +-------------------+
若使用 GaussDB MySQL 505.2 版本的 B 模式,需配置以下参数(最好配置到gaussdb mysql实例的配置文件中),下面以当前会话级别设置参数为例:
SET b_format_version = '5.7'; SET b_format_dev_version = 's1';
GaussDB MySQL 505.2 版本 M模式 示例
-- 转换前
ALTER TABLE customers RENAME INDEX idx_customer_name TO idx_customer_fullname;
-- 转换后
ALTER TABLE `customers` RENAME INDEX `idx_customer_name` TO `idx_customer_fullname`
-- 转换前
ALTER TABLE customers RENAME KEY `idx-customer.email` TO `idx-customer-email`;
-- 转换后
ALTER TABLE `customers` RENAME INDEX `idx-customer.email` TO `idx-customer-email`
-- 转换前
ALTER TABLE IF EXISTS non_existent_table RENAME INDEX invalid_index TO new_index;
-- 转换后
ALTER TABLE `non_existent_table` RENAME INDEX `invalid_index` TO `new_index`
-- 转换前
ALTER TABLE orders RENAME INDEX `select` TO idx_order_date;
-- 转换后
ALTER TABLE `orders` RENAME INDEX `select` TO `idx_order_date`
GaussDB MySQL 505.2 版本 B模式 示例
-- 转换前
ALTER TABLE customers RENAME INDEX idx_customer_name TO idx_customer_fullname;
ALTER TABLE customers RENAME KEY `idx-customer.email` TO `idx-customer-email`;
ALTER TABLE IF EXISTS non_existent_table RENAME INDEX invalid_index TO new_index;
ALTER TABLE orders RENAME INDEX `select` TO idx_order_date;
ALTER TABLE my_database.orders RENAME INDEX idx_id TO idx_id_test;
-- 转换后
ALTER INDEX `idx_customer_name` RENAME TO `idx_customer_fullname`;
ALTER INDEX `idx-customer.email` RENAME TO `idx-customer-email`;
ALTER INDEX `invalid_index` RENAME TO `new_index`;
ALTER INDEX `select` RENAME TO `idx_order_date`;
ALTER INDEX `my_database`.`idx_id` RENAME TO `idx_id_test`
1.3.3.4.4.19. 创建表支持普通索引和唯一索引
语法
CREATE TABLE TABLE_NAME(
COLUMN_NAME1 DATATYPE
[, ...]
[, INDEX INDEX_NAME(COLUMN_NAME [, ...])]
[, KEY INDEX_NAME(COLUMN_NAME [, ...])]
[, UNIQUE [KEY|INDEX] INDEX_NAME(COLUMN_NAME [, ...])]
)
警告
索引名称长度限制:GaussDB MySQL 505.2 版本的索引名称最大支持 63 个字符。若源 SQL(MariaDB)中索引名称为 64 个字符(其最大支持长度为 64),导入至 GaussDB MySQL 505.2 时会自动截取前 63 个字符,超出部分将被截断。
特殊字符处理:GaussDB MySQL 505.2 版本不支持直接使用
!@#$%^&*
等特殊字符作为标识符。若需使用,需用反引号(`)包裹转义。B 模式索引规则:GaussDB MySQL B 模式(默认版本505.2),索引名称在具体数据库下同一 Schema(模式)内需唯一。
GaussDB MySQL 505.2 版本 B模式 示例
-- 转换前
CREATE TABLE t1(id int, c1 varchar(20), c2 int, index(id), key(c1), unique index(c2));
CREATE TABLE t1(id int, c1 varchar(20), c2 int, index idx_id(id), key idx_c1(c1), unique key uni_idx_c2 (c2));
CREATE TABLE t1(id int, c1 varchar(20), c2 int, index idx_id(id), key idx_c1(c1), unique index uni_idx_c2 (c2));
-- 转换后
CREATE TABLE `t1` (`id` int,`c1` varchar(20),`c2` int,UNIQUE(`c2`));CREATE INDEX `t1_id_idx` ON `t1` (`id`);CREATE INDEX `t1_c1_idx` ON `t1` (`c1`);
CREATE TABLE `t1` (`id` int,`c1` varchar(20),`c2` int,UNIQUE `uni_idx_c2`(`c2`));CREATE INDEX `idx_id` ON `t1` (`id`);CREATE INDEX `idx_c1` ON `t1` (`c1`);
CREATE TABLE `t1` (`id` int,`c1` varchar(20),`c2` int,UNIQUE `uni_idx_c2`(`c2`));CREATE INDEX `idx_id` ON `t1` (`id`);CREATE INDEX `idx_c1` ON `t1` (`c1`);
1.3.3.4.4.20. 删除表
语法
DROP TABLE [IF EXISTS] table_name
GaussDB MySQL 505.2 版本 B模式 示例
-- 转换前
DROP TABLE test_t1;
DROP TABLE IF EXISTS test_t1;
-- 转换后
DROP TABLE `test_t1`;
DROP TABLE IF EXISTS `test_t1`;
1.3.3.4.4.21. 建表语句指定索引存储结构
语法
CREATE TABLE TABLE_NAME(
COLUMN_NAME1 DATATYPE
[, ...]
[, INDEX INDEX_NAME(COLUMN_NAME [, ...]) [USING BTREE]]
[, KEY INDEX_NAME(COLUMN_NAME [, ...]) [USING BTREE]]
[, UNIQUE [KEY|INDEX] INDEX_NAME(COLUMN_NAME [, ...]) [USING BTREE]]
)
警告
B模式中USING BTREE做语法糖处理
GaussDB MySQL 505.2 版本 B模式 示例
-- 转换前
CREATE TABLE t1(id int, PRIMARY KEY(id) USING BTREE);
-- 转换后
CREATE TABLE `t1` (`id` int,PRIMARY KEY(`id`) )
1.3.3.4.4.22. 修改表删除索引
语法
ALTER TABLE table_name DROP [CONSTRAINT] PRIMARY KEY;
ALTER TABLE table_name DROP INDEX|KEY [IF EXISTS] idx_name;
ALTER TABLE table_name DROP CONSTRAINT [IF EXISTS] cons_name;
警告
B模式中ALTER TABLE DROP INDEX|KEY 只支持单语句, 不支持和其他的修改项组合起来使用
GaussDB MySQL 505.2 版本 B模式 示例
-- 转换前
alter table t1 drop constraint primary key;
alter table t1 drop primary key;
alter table t1 drop index idx_123;
alter table t1 drop key idx_123;
alter table t1 drop index if exists idx_123;
alter table t1 drop key if exists idx_123;
alter table t1 drop constraint cons_123;
alter table t1 drop constraint if exists cons_123;
-- 转换后
ALTER TABLE `t1` DROP PRIMARY KEY;
ALTER TABLE `t1` DROP PRIMARY KEY;
DROP INDEX `idx_123`;
DROP INDEX `idx_123`;
DROP INDEX IF EXISTS `idx_123`;
DROP INDEX IF EXISTS `idx_123`;
ALTER TABLE `t1` DROP CONSTRAINT `cons_123`;
ALTER TABLE `t1` DROP CONSTRAINT IF EXISTS `cons_123`;
1.3.3.4.5. OceanBase-Mysql
1.3.3.4.5.1. 建表语句字符集和排序规则转换
语法
CREATE TABLE [IF NOT EXISTS] TABLE_NAME(
...
)
[[DEFAULT] CHARSET | CHARACTER SET [=] CHARSET_NAME]
[[DEFAULT] COLLATE [=] COLLATION_NAME]
...
警告
目前建表语句中支持的字符集为utf8、utf8mb4、utf8mb3、latin1、binary和gbk;
示例
-- 转换前MySQL SQL:
CREATE TABLE IF NOT EXISTS test_table (
id int,
co1 varchar(20),
co2 text,
co3 timestamp,
co4 numeric(5, 3),
co5 varchar(200),
co6 varchar(20)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET utf8mb4
DEFAULT COLLATE=utf8mb4_0900_ai_ci;
-- 转换后OceanBase-Mysql SQL:
CREATE TABLE IF NOT EXISTS `test_table` (`id` int,
`co1` varchar(20),
`co2` text,
`co3` timestamp(6),
`co4` numeric(5, 3),
`co5` varchar(200),
`co6` varchar(20)
);
1.3.3.4.6. DM
1.3.3.4.6.1. 建库语句
语法
-- MariaDB 原生语法
CREATE [OR REPLACE] {DATABASE | SCHEMA} [IF NOT EXISTS] db_name;
-- 示例
CREATE DATABASE IF NOT EXISTS db_name;
警告
DM兼容性说明
语法替换要求:将
CREATE DATABASE
替换为CREATE SCHEMA
不支持语法:不支持
IF NOT EXISTS
和OR REPLACE
子句,转换后的SQL会移除这些语法糖
- 库名命名规范
禁止使用引号包裹库名(双引号/单引号/反引号均不支持)
允许字符:字母、数字、下划线
禁止字符:直接使用特殊符号(如@、%等会报错)
- 长度限制:
MariaDB:最大64字符
DM:最大128字节
禁止使用保留字(如`create database select`会报错)
- DM执行特性
允许重复创建用户下同名模式(schema),举例多次执行`create schema abc`不报错
- 权限要求:
需DBA角色用户
或拥有CREATE SCHEMA权限的用户
- 语句隔离要求:
禁止与其他SQL混用(如`create schema abc;SELECT 1`不支持)
- disql命令行特殊要求:
语句必须以`/结尾(例:`create schema abc/)
示例
-- 转换前MySQL SQL:
CREATE DATABASE czech_slovak_names
create or replace database if not exists abc
-- 转换后DM SQL:
create schema czech_slovak_names
create schema abc
1.3.3.4.6.2. 切库语句
语法
-- mariadb语法
USE db_name;
-- 对应dm语法如下
SET SCHEMA db_name;
警告
- 库名命名规范
禁止使用引号包裹库名(双引号/单引号/反引号均不支持)
允许字符:字母、数字、下划线
禁止字符:直接使用特殊符号(如@、%等会报错)
- 长度限制:
MariaDB:最大64字符
DM:最大128字节
禁止使用保留字(如`use select`会报错)
- DM执行特性
不支持切换到不存在的模式(schema)。
权限要求:供具有DBA权限的用户设置当前模式语句。
示例
-- 转换前MySQL SQL:
use abc
-- 转换后DM SQL:
SET SCHEMA abc
1.3.3.4.6.3. 删库语句
语法
-- MariaDB 删库语法(支持 DATABASE/SCHEMA 关键字)
DROP {DATABASE | SCHEMA} [IF EXISTS] db_name;
-- 转换后DM 删除模式(schema)语法(仅支持 SCHEMA 关键字)
DROP SCHEMA [IF EXISTS] db_name CASCADE;
警告
- 库名命名规范
禁止使用引号包裹库名(双引号/单引号/反引号均不支持)
允许字符:字母、数字、下划线
禁止字符:直接使用特殊符号(如@、%等会报错)
- 长度限制:
MariaDB:最大64字符
DM:最大128字节
禁止使用保留字(如`drop database select`会报错)
- DM执行特性
有权限的用户才能执行删除库操作,具体权限:有dba角色权限或者有drop any schema 权限的用户
删除不存在的模式会报错,指定if exists 关键字可以避免这个报错。
使用CASCADE选项时,会删除整个模式,模式中的对象以及相关依赖关系。使用RESTRICT选项(默认)时,模式必须为空才能删除成功。
示例
-- 转换前MySQL SQL:
DROP DATABASE IF EXISTS db_name
DROP DATABASE db_name
DROP SCHEMA db_name
-- 转换后DM SQL:
DROP SCHEMA IF EXISTS db_name CASCADE
DROP SCHEMA db_name CASCADE
DROP SCHEMA db_name CASCADE
1.3.3.4.6.4. 支持表列ON UPDATE CURRENT_TIMESTAMP
语法
CREATE TABLE TABLE_NAME(
COLUMN_NAME1 DATATYPE
[ON UPDATE CURRENT_TIMESTAMP[(n)]]
)
ALTER TABLE TABLE_NAME
| ADD [COLUMN] col_name column_definition [ON UPDATE CURRENT_TIMESTAMP[(n)]]
| CHANGE [COLUMN] OLD_COL_NAME NEW_COL_NAME COLUMN_DEFINITION [ON UPDATE CURRENT_TIMESTAMP[(n)]]
警告
DATATYPE 只支持 timestamp 和 datetime 类型;
timestamp(n) n 的长度,MariaDB 小于7, DM 小于10,按照 MariaDB 约束为主;
datetime(n) n 的长度,MariaDB 小于7, DM 小于10,按照 MariaDB 约束为主;
CURRENT_TIMESTAMP(n) n 的长度,MariaDB 小于18446744073709551616(UNSIGNED BIGINT 的最大值), DM 小于10,按照 DM 约束为主;
多表关联更新时,所有被修改的列必须属于同一张表;
DM timestamp 和 datetime 类型默认带毫秒,MariaDB timestamp 和 datetime 类型默认不带毫秒,查询结果不同;
同一列不允许使用多个on update current_timestamp属性;
MariaDB 表名和字段名相加不能超过112,转换之后 DM 执行报错;
不支持涉及修改表名的场景;
alter change 将字段 timestamp 类型从精度0改成6,在精度为0时插入的数据,DM 会将0去掉,MariaDB 会保留。
示例
-- 转换前
CREATE TABLE unisql.ustomers1 (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
email VARCHAR(100),
last_updated datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(6)
);
-- 转换后
BEGIN
EXECUTE IMMEDIATE q'[CREATE TABLE unisql.ustomers1 (id int PRIMARY KEY,name varchar(50) NOT NULL,email varchar(100),last_updated datetime NOT NULL DEFAULT CURRENT_TIMESTAMP(0))]';
EXECUTE IMMEDIATE q'[DROP TRIGGER IF EXISTS unisql.unisql_trigger_onupdate_currenttimmestamp_ustomers1_last_updated;]';
EXECUTE IMMEDIATE q'[CREATE TRIGGER unisql.unisql_trigger_onupdate_currenttimmestamp_ustomers1_last_updated BEFORE UPDATE ON unisql.ustomers1 FOR EACH ROW BEGIN IF NOT UPDATING('last_updated') THEN :NEW.last_updated = CURRENT_TIMESTAMP(6); END IF; END;]';
END;
/
-- 转换前
ALTER TABLE test_alter_onupdate_20250825_45023 ADD COLUMN ts_col0 TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0);
-- 转换后
BEGIN
EXECUTE IMMEDIATE q'[ALTER TABLE test_alter_onupdate_20250825_45023 ADD ts_col0 timestamp(0) DEFAULT CURRENT_TIMESTAMP(0) ]';
EXECUTE IMMEDIATE q'[DROP TRIGGER IF EXISTS unisql_trigger_test_alter_onupdate_20250825_45023_ts_col0;]';
EXECUTE IMMEDIATE q'[CREATE TRIGGER unisql_trigger_test_alter_onupdate_20250825_45023_ts_col0 BEFORE UPDATE ON test_alter_onupdate_20250825_45023 FOR EACH ROW BEGIN IF NOT UPDATING('ts_col0') THEN :NEW.ts_col0 = CURRENT_TIMESTAMP(0); END IF; END;]';
END;
/
-- 转换前
ALTER TABLE test_alter_change_onupdate_20250825_45023 CHANGE COLUMN customer_id customer_id1 TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3);
-- 转换后
BEGIN
EXECUTE IMMEDIATE q'[DROP TRIGGER IF EXISTS unisql_trigger_test_alter_change_onupdate_20250825_45023_customer_id;]';
EXECUTE IMMEDIATE q'[ALTER TABLE test_alter_change_onupdate_20250825_45023 RENAME COLUMN customer_id TO customer_id1]';
EXECUTE IMMEDIATE q'[ALTER TABLE test_alter_change_onupdate_20250825_45023 MODIFY customer_id1 timestamp(3) DEFAULT CURRENT_TIMESTAMP(3)]';
EXECUTE IMMEDIATE q'[DROP TRIGGER IF EXISTS unisql_trigger_test_alter_change_onupdate_20250825_45023_customer_id1;]';
EXECUTE IMMEDIATE q'[CREATE TRIGGER unisql_trigger_test_alter_change_onupdate_20250825_45023_customer_id1 BEFORE UPDATE ON test_alter_change_onupdate_20250825_45023 FOR EACH ROW BEGIN IF NOT UPDATING('customer_id1') THEN :NEW.customer_id1 = CURRENT_TIMESTAMP(3); END IF; END;]';
END;
/
1.3.3.4.6.5. 创建表支持普通索引和唯一索引
语法
CREATE TABLE TABLE_NAME(
COLUMN_NAME1 DATATYPE
[, ...]
[, INDEX INDEX_NAME(COLUMN_NAME [, ...])]
[, KEY INDEX_NAME(COLUMN_NAME [, ...])]
[, UNIQUE [KEY|INDEX] INDEX_NAME(COLUMN_NAME [, ...])]
)
警告
不支持前缀索引;
不支持索引属性选项;
索引名称最大长度128字节;
示例
-- 转换前
CREATE TABLE t1(id int, c1 varchar(20), c2 int, index(id), key(c1), unique index(c2));
CREATE TABLE t1(id int, c1 varchar(20), c2 int, index idx_id(id), key idx_c1(c1), unique key uni_idx_c2 (c2));
CREATE TABLE t1(id int, c1 varchar(20), c2 int, index idx_id(id), key idx_c1(c1), unique index uni_idx_c2 (c2));
-- 转换后
BEGIN
EXECUTE IMMEDIATE q'[CREATE TABLE t1 (id int,c1 varchar(20),c2 int,CONSTRAINT t1_c2_key UNIQUE(c2))]';
EXECUTE IMMEDIATE q'[CREATE INDEX t1_id_idx ON t1 (id)]';
EXECUTE IMMEDIATE q'[CREATE INDEX t1_c1_idx ON t1 (c1)]';
end;
/
BEGIN
EXECUTE IMMEDIATE q'[CREATE TABLE t1 (id int,c1 varchar(20),c2 int,CONSTRAINT uni_idx_c2 UNIQUE(c2))]';
EXECUTE IMMEDIATE q'[CREATE INDEX idx_id ON t1 (id)]';
EXECUTE IMMEDIATE q'[CREATE INDEX idx_c1 ON t1 (c1)]';
end;
/
BEGIN
EXECUTE IMMEDIATE q'[CREATE TABLE t1 (id int,c1 varchar(20),c2 int,CONSTRAINT uni_idx_c2 UNIQUE(c2))]';
EXECUTE IMMEDIATE q'[CREATE INDEX idx_id ON t1 (id)]';
EXECUTE IMMEDIATE q'[CREATE INDEX idx_c1 ON t1 (c1)]';
end;
/
1.3.3.4.6.6. 创建表时指定表选项
语法
CREATE TABLE [IF NOT EXISTS] TABLE_NAME (
COLUMN_NAME DATATYPE
)
| ENGINE = ENGINE_NAME
| [DEFAULT] CHARSET | CHARACTER SET [=] CHARSET_NAME
| [DEFAULT] COLLATE [=] COLLATION_NAME
| ROW_FORMAT [=] {DEFAULT|DYNAMIC|COMPRESSED|REDUNDANT|COMPACT}
| COMMENT [=] COMMENT_STRING
| DELAY_KEY_WRITE [=] {0|1}
| AUTO_INCREMENT [=] NUMBER
警告
当存在多个表选项时,某些表选项会被转换为目标数据库的其他语句(例如表注释COMMENT) 。因此部分建表语句会被转为匿名块,以确保在目标数据库中正确执行。
CHARSET_NAME 支持的字符集包括 utf8、utf8mb4、ascii、latin1、binary 和 gbk。对于不支持的字符集,统一 SQL 解析会报错。
ENGINE、COLLATE、CHARSET、ROW_FORMAT 和 DELAY_KEY_WRITE 选项仅作为语法糖存在,仅支持语法转换,并无法实现实际功能。
注意:在为表添加注释时,MySQL 和 DM 数据库在处理注释内容上的支持范围不同。某些特殊字符(如 \\n 和 &*)可能在两个数据库中产生不同的含义,从而影响执行结果和显示效果。
示例
-- 转换前 MySQL SQL:
CREATE TABLE table_unisql_1 (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50)
) ENGINE = InnoDB COMMENT = '统一SQL表选项测试表'
ROW_FORMAT = DYNAMIC
COLLATE = utf8mb4_unicode_ci
CHARACTER SET = utf8mb4
DELAY_KEY_WRITE = 1
AUTO_INCREMENT = 100;
CREATE TABLE table_unisql_2 (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50)
) ENGINE = InnoDB
ROW_FORMAT = DYNAMIC
COLLATE = utf8mb4_unicode_ci
CHARACTER SET = utf8mb4
DELAY_KEY_WRITE = 1
AUTO_INCREMENT = 100;
-- 转换后 DM SQL:
BEGIN
EXECUTE IMMEDIATE q'[CREATE TABLE table_unisql_1 (id int AUTO_INCREMENT PRIMARY KEY, name varchar(50)) AUTO_INCREMENT = 100]';
EXECUTE IMMEDIATE q'[COMMENT ON TABLE table_unisql_1 IS '统一SQL表选项测试表']';
END;
/
CREATE TABLE table_unisql_2 (id int AUTO_INCREMENT PRIMARY KEY, name varchar(50)) AUTO_INCREMENT = 100;
1.3.3.4.6.7. 修改普通表
语法
ALTER TABLE [IF EXISTS] TABLE_NAME
| CONVERT TO CHARACTER SET CHARSET_NAME
| COMMENT COMMENT_STRING
| DROP [CONSTRAINT] PRIMARY KEY
| DROP {INDEX|KEY} [IF EXISTS] index_name
| DROP CONSTRAINT [IF EXISTS] constraint_name
| CHANGE [COLUMN] [IF EXISTS] OLD_COL_NAME NEW_COL_NAME COLUMN_DEFINITION [FIRST | AFTER col_name]
| RENAME INDEX | KEY INDEX_OLD_NAME TO INDEX_NEW_NAME
| MODIFY [COLUMN] [IF EXISTS] COLUMN_NAME COLUMN_DEFINITION [FIRST | AFTER col_name]
COLUMN_DEFINITION:
[NULL|NOT NULL] [DEFAULT DEFAULT_VALUE] [AUTO_INCREMENT] [ZEROFILL] [UNIQUE [KEY]] [PRIMARY [KEY]] [CHARACTER SET CHARSET_NAME] [COLLATE COLLATE_NAME] [COMMENT COMMENT_STRING]
警告
当存在多个语句时,会被转换为匿名块,以便在目标库中执行。
ALTER TABLE…CONVERT TO CHARACTER SET…仅支持语法转换,无实际功能,且受配置参数控制。可以通过 config/unisql.conf 文件中的 unisql.global.replace.sql 参数来配置需要替换的 SQL 语句。目前,支持的字符集有 utf8、utf8mb4、ascii、latin1、binary 和 gbk,对于其他不支持的字符集,统一 SQL 解析将会报错。
当使用ALTER TABLE语句的COMMENT选项为表添加COMMENT_STRING类型的注释时,请注意,MySQL和DM数据库在处理注释内容上的支持范围不同。某些特殊字符(如 \\n 和 &*)在两个数据库中被识别为不同的含义,从而导致执行行为和结果显示上存在差异。
alter table drop index依赖元数据信息,如果index_name是约束,则转成alter table drop constraint, 否则转成单独一条drop index语句。不支持在同一张表中索引名相同(包括忽略大小写的情况下)
使用 CHANGE 语法时,列名不区分大小写。当数据类型发生变化时,由于数据库间的差异,可能导致执行结果不一致(例如,MySQL 支持将日期类型转换为 int,而 DM 不支持)。DM 不支持对已经是主键的列修改成新的主键列,会报错主键冲突并执行失败。AFTER、FIRST、ZEROFILL 和 AUTO_INCREMENT 选项仅作为语法糖存在,无实际功能。
使用 RENAME 语法时,索引名仅支持英文字母、下划线、数字和$,其他字符会导致DM数据库执行报错。目前,RENAME INDEX仅支持修改普通索引、唯一索引和唯一约束。 转化需要开启元数据功能,如果由约束自动创建的索引,那么会转化成重命名约束,否则会转化成重命名索引;
使用 MODIFY 语法时,不同数据库间的差异可能导致数据类型更改的执行结果不一致(例如,MySQL 支持将日期类型转换为 int,而 DM 不支持)。DM 不支持对已经是主键的列修改成新的主键列,会报错主键冲突并执行失败。AFTER、FIRST、ZEROFILL 和 AUTO_INCREMENT 选项仅作为语法糖存在,无实际功能。
COLUMN_DEFINITION 支持的字符集有 utf8、utf8mb4、ascii、latin1、binary 和 gbk,对于其他不支持的字符集,统一 SQL 解析将会报错。其中binary仅支持语法转换支持。
示例
-- 多语句转换逻辑
-- 转换前 MySQL 语法:
ALTER TABLE tablename stmt1, stmt2
-- 转换后 DM SQL:
BEGIN
EXECUTE IMMEDIATE q'[第一个目标 SQL 语句]';
EXECUTE IMMEDIATE q'[第二个目标 SQL 语句]';
END;
/
-- 转换前 MySQL SQL:
ALTER TABLE test_table CONVERT TO CHARACTER SET utf8;
-- 转换后 DM SQL:
-- 通过配置参数 unisql.global.replace.sql = 'select 1'
SELECT 1;
-- 转换前SQL
alter table test_table drop constraint primary key;
-- 转换后SQL
ALTER TABLE test_table DROP PRIMARY KEY
-- 转换前SQL, index_name不在元数据的约束信息中
alter table test_table drop index if exists aaa;
-- 转换后SQL
DROP INDEX aaa
-- 转换前SQL, index_name在元数据的约束信息中
alter table test_table drop index if exists aaa;
-- 转换后SQL
ALTER TABLE test_table DROP CONSTRAINT AAA;
-- 转换前SQL
alter table test_table drop constraint if exists bbb;
-- 转换后SQL
ALTER TABLE test_table DROP CONSTRAINT bbb;
-- COMMENT添加表级别注释
-- 转换前 MySQL SQL:
ALTER TABLE test_table COMMENT '统一SQL';
-- 转换后 DM SQL:
COMMENT ON TABLE test_table IS '统一SQL';
-- CAHNGE 语法修改列定义
-- 转换前 MySQL SQL:
ALTER TABLE test_table CHANGE COLUMN old_col new_col INT ZEROFILL NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '统一SQL';
-- 转换后 DM SQL:
BEGIN
EXECUTE IMMEDIATE q'[ALTER TABLE test_table RENAME COLUMN old_col TO new_col]';
EXECUTE IMMEDIATE q'[COMMENT ON COLUMN test_table.new_col IS '统一SQL']';
EXECUTE IMMEDIATE q'[ALTER TABLE test_table MODIFY new_col bigint NOT NULL PRIMARY KEY]';
END;
/
-- RENAME INDEX | KEY 语法修改索引名
-- 转换前 MySQL SQL:
ALTER TABLE test_table RENAME KEY idx_id TO idx_customer_id;
-- rename_unique_idx_id在mysql是唯一索引
ALTER TABLE test_table RENAME INDEX rename_unique_idx_id TO alter_rename_unique_idx_id_last;
-- 转换后 DM SQL:
ALTER INDEX idx_id RENAME TO idx_customer_id;
-- rename_unique_idx_id在dm是唯一约束,在元数据中查到
ALTER TABLE test_table RENAME CONSTRAINT rename_unique_idx_id TO alter_rename_unique_idx_id_last;
-- MODIFY 语法修改列定义
-- 转换前 MySQL SQL:
ALTER TABLE test_table MODIFY COLUMN IF EXISTS col_name INT ZEROFILL NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '统一SQL';
-- 转换后 DM SQL:
BEGIN
EXECUTE IMMEDIATE q'[COMMENT ON COLUMN test_table.col_name IS '统一SQL']';
EXECUTE IMMEDIATE q'[ALTER TABLE test_table MODIFY col_name bigint NOT NULL PRIMARY KEY]';
END;
/
1.3.3.4.6.8. 创建分区表
语法
CREATE TABLE [IF NOT EXISTS] TABLE_NAME(
COLUMN_NAME1 DATATYPE
[, ...]
[, PRIMARY KEY(COLUMN_NAME [, ...])]
[, INDEX INDEX_NAME(COLUMN_NAME [, ...])]
)
| PARTITION BY RANGE [COLUMNS](COLUMN_NAME)(
PARTITION PARTITION_NAME VALUES LESS THAN (VALUE_1)
[, ...]
)
| PARTITION BY LIST (COLUMN_NAME) (
PARTITION PARTITION_NAME VALUES IN (VALUE_1)
[, ...]
)
| PARTITION BY HASH (COLUMN_NAME) PARTITIONS PARTITION_NUM
警告
COLUMN_NAME支持的数据类型有int,tinyint,bigint,mediumint,date,datetime,char,varchar类型,其它数据类型不做处理
mysql数据库COLUMN_NAME支持函数,统一sql不支持
mysql数据库VALUE_1支持函数,统一sql透传
分区表分区名称,分区列名称不支持大小写敏感,特殊字符
不支持二级分区,不支持混合分区
示例
-- 转换前 SQL:
CREATE TABLE test_table (
id INT NOT NULL,
name VARCHAR(50),
salary DECIMAL(10,2),
hire_date DATE
)
PARTITION BY RANGE COLUMNS (hire_date) (
PARTITION p0 VALUES LESS THAN ('2000-01-01'),
PARTITION p1 VALUES LESS THAN ('2010-01-01'),
PARTITION p2 VALUES LESS THAN ('2020-01-01'),
PARTITION p3 VALUES LESS THAN MAXVALUE
);
-- 转换后 SQL:
CREATE TABLE test_table (
id INT NOT NULL,
name VARCHAR(50),
salary DECIMAL(10,2),
hire_date DATE
)
PARTITION BY RANGE (hire_date) (
PARTITION p0 VALUES LESS THAN ('2000-01-01'),
PARTITION p1 VALUES LESS THAN ('2010-01-01'),
PARTITION p2 VALUES LESS THAN ('2020-01-01'),
PARTITION p3 VALUES LESS THAN (MAXVALUE)
);
-- 转换前 SQL:
CREATE TABLE test_table (
id INT NOT NULL,
name VARCHAR(50),
department_id INT,
salary DECIMAL(10,2)
)
PARTITION BY LIST (department_id) (
PARTITION dept1 VALUES IN (1, 3, 5),
PARTITION dept2 VALUES IN (2, 4, 6),
PARTITION dept_other VALUES IN (7, 8, 9, NULL)
);
-- 转换后 SQL:
CREATE TABLE test_table (
id int NOT NULL,
name varchar(50),
department_id int,
salary decimal(10,2)
)
PARTITION BY LIST (department_id) (
PARTITION dept1 VALUES (1, 3, 5),
PARTITION dept2 VALUES (2, 4, 6),
PARTITION dept_other VALUES (7, 8, 9, NULL)
);
-- 转换前 SQL:
CREATE TABLE test_table (
id INT NOT NULL,
name VARCHAR(50),
department_id INT,
salary DECIMAL(10,2)
)
PARTITION BY HASH(department_id)
PARTITIONS 4;
-- 转换后 SQL:
CREATE TABLE test_table (
id int NOT NULL,
name varchar(50),
department_id int,
salary decimal(10,2)
)
PARTITION BY HASH (department_id)
PARTITIONS 4;
1.3.3.4.6.9. 为表添加列
语法
ALTER TABLE table_name
ADD [COLUMN] [IF NOT EXISTS] col_name column_definition [ FIRST | AFTER existing_column]
| ADD [COLUMN] [IF NOT EXISTS] (col_name column_definition, [...])
解释如下
col_name表示列名称
column_definition表示列定义:
- data_type
- [NOT NULL | NULL] [DEFAULT default_value]
- [AUTO_INCREMENT] [ZEROFILL] [UNIQUE [KEY]] [PRIMARY KEY]
- comment 'string'
existing_column表示表中已存在的列名称
警告
添加列,数据类型,函数以当前统一sql转换的实现为主。
添加列,在dm不支持列位置关键字,FIRST | AFTER,统一sql语法糖处理,转换后没有。
添加列,在dm不支持if not exists,统一sql语法糖处理,转换后没有。
添加列,在dm不支持zerofill,统一sql语法糖处理,转换后没有。
示例
-- 转换前,添加单列(带默认值,非空约束和位置信息)
ALTER TABLE user_info
ADD COLUMN email VARCHAR(100) NOT NULL DEFAULT 'unknown@example.com' AFTER username;
-- 转换前,添加多列(含不同属性)
ALTER TABLE user_info
ADD (
age TINYINT UNSIGNED ZEROFILL NULL DEFAULT 18,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 转换前,if not exists 防止重复添加
ALTER TABLE user_info
ADD COLUMN IF NOT EXISTS mobile CHAR(11) AFTER age;
-- 转换前,列注释
ALTER TABLE add_column_55716 ADD orderno varchar(20) NOT NULL DEFAULT '2025-05-XXX' COMMENT '订单号'
-- 转换后
ALTER TABLE user_info ADD email varchar(100) NOT NULL DEFAULT 'unknown@example.com'
-- 转换后,添加多列(含不同属性)
ALTER TABLE user_info ADD (age int NULL DEFAULT 18, created_at datetime DEFAULT CURRENT_TIMESTAMP(0), updated_at timestamp DEFAULT CURRENT_TIMESTAMP(0))
-- 转换后
ALTER TABLE user_info ADD mobile char(11)
-- 转换后
BEGIN
EXECUTE IMMEDIATE q'[ALTER TABLE add_column_55716 ADD orderno varchar(20) NOT NULL DEFAULT '2025-05-XXX' ]';
EXECUTE IMMEDIATE q'[COMMENT ON COLUMN add_column_55716.orderno IS '订单号']';
end;
/
1.3.3.4.6.10. 为表添加索引
语法
ALTER TABLE table_name
| ADD [UNIQUE] [INDEX|KEY] [IF NOT EXISTS] [index_name] [index_type] (index_col_name,...) [index_option] ...
| ADD PRIMARY KEY [IF NOT EXISTS] [index_type] (index_col_name,...) [index_option]
解释:
[index_name]表示索引名称
[index_type]表示索引类型
index_type:
USING {BTREE}
(index_col_name,...)表示表中索引的列
[index_option]表示其他索引选项
index_option:
COMMENT 'string'
VISIBLE
INVISIBLE
警告
dm限制
索引名称长度不超过128字符。
创建普通索引,支持if not exists,举例CREATE INDEX IF NOT EXISTS idx_employees_name ON employees (name)
添加唯一约束或者主键,不支持if not exists,唯一约束举例ALTER TABLE employees ADD CONSTRAINT IF NOT EXISTS sss UNIQUE (name);
在dm中不可以给表字段重复创建索引,普通索引举例CREATE INDEX idx_employees_name ON employees (name),报错,此列列表已索引
在dm中同样不可以为表字段重复创建唯一约束,具体举例ALTER TABLE employees ADD CONSTRAINT idx_employees_email UNIQUE(email),报错,表中已存在这样的唯一关键字或主键
在dm中修改表添加列带自增属性(AUTO_INCREMENT),dm要求AUTO_INCREMENT列必须为主键约束的一部分,报错sql举例ALTER TABLE tb_job_statistic ADD id bigint NOT NULL AUTO_INCREMENT
在dm中修改表添加索引,不支持索引前缀,举例CREATE INDEX idx_name5 ON add_index_55716 (name(30));
在dm中修改表添加唯一约束或者添加主键,不支持支持直接在列名后使用 DESC 来指定降序排序,举例ALTER TABLE add_index_55716 ADD CONSTRAINT unique_idx_name2 UNIQUE(name DESC);
索引的功能和用途限制:
支持普通索引(INDEX|KEY)、唯一索引(UNIQUE INDEX)、主键索引( primary key)
全文索引(Fulltext)经过统一SQL转换后在目标库dm执行报错。
其他索引(如空间索引(Spatial)),统一SQL解析报错。
索引类型限制:
仅支持
BTREE
索引类型,统一SQL语法糖处理,转换后没有。尝试使用
HASH
或其他索引类型,统一SQL解析报错。
索引选项处理规则:
索引选项
COMMENT
、VISIBLE
、INVISIBLE
统一SQL语法糖处理。不支持以下索引选项,使用会导致SQL解析报错:
KEY_BLOCK_SIZE
WITH PARSER
CLUSTERING
IGNORED
NOT IGNORED
示例
-- 转换前
-- 1. 添加普通索引(使用INDEX关键字)
ALTER TABLE employees
ADD INDEX idx_employees_name (name);
-- 2. 添加普通索引(使用KEY关键字,与INDEX等效)
ALTER TABLE employees
ADD KEY idx_employees_department (department_id);
-- 3. 添加唯一索引
ALTER TABLE employees
ADD UNIQUE INDEX idx_employees_email (email);
-- 4. 添加带IF NOT EXISTS的索引(防止重复创建错误)
ALTER TABLE employees
ADD INDEX IF NOT EXISTS idx_employees_hire_date (hire_date);
-- 5. 添加指定BTREE类型的索引(语法糖,实际执行会忽略类型)
ALTER TABLE employees
ADD INDEX idx_employees_salary (salary) USING BTREE;
-- 6. 添加带COMMENT选项的索引
ALTER TABLE employees
ADD INDEX idx_employees_dept_salary (department_id, salary)
COMMENT '索引部门和薪资,用于查询部门薪资分布';
-- 7. 添加VISIBLE索引(默认可见,显式指定)
ALTER TABLE employees
ADD INDEX if not exists idx_employees_name_visible (name) VISIBLE;
-- 不支持HASH索引类型
ALTER TABLE employees
ADD INDEX idx_hash_example (id) USING HASH;
-- 不支持KEY_BLOCK_SIZE选项
ALTER TABLE employees
ADD INDEX idx_unsupported_option (department_id)
KEY_BLOCK_SIZE = 1024;
-- 转换后
CREATE INDEX idx_employees_name ON employees (name)
CREATE INDEX idx_employees_department ON employees (department_id)
ALTER TABLE employees ADD CONSTRAINT idx_employees_email UNIQUE(email)
CREATE INDEX IF NOT EXISTS idx_employees_hire_date ON employees (hire_date)
CREATE INDEX idx_employees_salary ON employees (salary)
CREATE INDEX idx_employees_dept_salary ON employees (department_id, salary)
CREATE INDEX IF NOT EXISTS idx_employees_name_visible ON employees (name)
解析失败(EXTRA string=错误信息[在第 2 行,第 47 列附近 "HASH;" ]
解析失败(EXTRA string=错误信息[在第 3 行,第 20 列附近 "KEY_BLOCK_SIZE = 1024;" ]
1.3.3.4.6.11. 建表时指定列注释
语法
CREATE TABLE TABLE_NAME(
COLUMN_NAME1 DATATYPE [COMMENT 'comment_string']
)
警告
注释不支持使用双引号括起来
示例
-- 转换前
create table test_table
(
id int comment '用户唯一表示',
name varchar(50) comment '用户名',
create_time date comment '创建时间',
status char(1) comment '状态(0-禁用,1-启用)'
);
-- 转换后
CREATE TABLE test_table
(
id int COMMENT '用户唯一表示',
name varchar(50) COMMENT '用户名',
create_time date COMMENT '创建时间',
status char(1) COMMENT '状态(0-禁用,1-启用)'
)
1.3.3.4.7. 通用
1.3.3.4.7.1. 建表语句中去除创建主键外键和索引
语法
CREATE TABLE [IF NOT EXISTS] TABLE_NAME(
COLUMN_NAME1 DATATYPE [AUTO_INCREMENT] [DEFAULT ...] [ON UPDATE CURRENT_TIMESTAMP] [ZEROFILL]
[CHARSET | CHARACTER SET CHARSET_NAME] [COLLATE COLLATION_NAME] [COMMENT COMMENT_STRING]
[, ...]
[, PRIMARY KEY(COLUMN_NAME [, ...] [USING BTREE])]
[, INDEX INDEX_NAME(COLUMN_NAME [, ...] [USING BTREE])]
[, CONSTRAINT [symbol]] FOREIGN KEY [index_name] (col_name,...) reference_definition
)
...
警告
需配合配置参数unisql.transform.createstmt.mode才能正常工作:0:建表语句转换时保留主键、外键和索引;1:建表语句转换时仅保留主键,去除外键和索引;2-建表语句转换时去除主键、外键和索引;
示例
-- unisql.transform.createstmt.mode设置为2
-- 转换前MySQL SQL:
CREATE TABLE test_tbl (
a INT primary key,
b int,
c int,
d int,
e int,
f int,
foreign key (b) references test_create_table_mode_fk_34085(aa),
key(d),
unique key(e, f)
);
-- 转换后OceanBase-Mysql SQL:
CREATE TABLE `test_tbl` (
`a` int,
`b` int,
`c` int,
`d` int,
`e` int,
`f` int
);