从 MySQL 迁移到 ProtonBase 指南
ProtonBase 提供数据同步服务,可以方便、快捷的将 MySQL 数据一站式迁移至 ProtonBase。
- 如何同步 MySQL 数据参考文档Teleport 同步 MySQL 数据
字段类型映射
MySQL 数据类型 | ProtonBase 数据类型 | 备注 |
TINYINT | SMALLINT | 范围不同,MySQL: -128 到 127, ProtonBase: -32768 到 32767 |
BOOL / BOOLEAN | BOOLEAN | ProtonBase 使用 BOOLEAN,值为 TRUE 或 FALSE |
SMALLINT | SMALLINT | 一致 |
MEDIUMINT | INTEGER | ProtonBase 无 MEDIUMINT,通常用 INTEGER 替代 |
INT / INTEGER | INTEGER | 一致 |
BIGINT | BIGINT | 一致 |
FLOAT | REAL | 精度略有不同 |
DOUBLE | DOUBLE PRECISION | 一致 |
DECIMAL(p, s) | NUMERIC(p, s) | 一致,精度和范围相同 |
DATE | DATE | 一致 |
DATETIME | TIMESTAMP [WITHOUT TIME ZONE] | ProtonBase 使用 TIMESTAMP,并支持时区 |
TIMESTAMP | TIMESTAMP | 一致 |
TIME | TIME | 一致 |
YEAR | SMALLINT / INTEGER | ProtonBase 无 YEAR 类型,需转换为整数表示 |
CHAR(n) | CHAR(n) | 一致 |
VARCHAR(n) | VARCHAR(n) | 一致 |
TINYTEXT | VARCHAR | ProtonBase 无 TINYTEXT,用 VARCHAR 替代 |
TEXT | TEXT | 一致 |
MEDIUMTEXT | TEXT | ProtonBase 无 MEDIUMTEXT,用 TEXT 替代 |
LONGTEXT | TEXT | ProtonBase 无 LONGTEXT,用 TEXT 替代 |
BINARY(n) | BYTEA | ProtonBase 无 BINARY,用 BYTEA 处理二进制数据 |
VARBINARY(n) | BYTEA | 同上 |
TINYBLOB | BYTEA | ProtonBase 无 TINYBLOB,用 BYTEA 替代 |
BLOB | BYTEA | 一致 |
MEDIUMBLOB | BYTEA | ProtonBase 无 MEDIUMBLOB,用 BYTEA 替代 |
LONGBLOB | BYTEA | ProtonBase 无 LONGBLOB,用 BYTEA 替代 |
ENUM | VARCHAR / CHECK 约束 | ProtonBase 无 ENUM,通常用 VARCHAR 并添加 CHECK 约束实现 |
SET | 无直接对应 | 可以用 ARRAY 或通过表关联来实现 |
JSON | JSONB | ProtonBase 推荐使用 JSONB,支持更高效的操作 |
查询语法
如果你使用的是 ORM(Object-Relational Mapping) 框架,例如 Java 的 Hibernate、Python 的 SQLAlchemy 等,那么迁移过程会相对简单。你只需要修改 ORM 配置中的数据库驱动和连接字符串,切换到 ProtonBase 的驱动程序,大部分查询语句都无需改动,因为 ORM 会根据目标数据库自动生成正确的 SQL 语法。
当然,仍然可能存在一些 ORM 不能很好地抽象和转换的数据库特有语法和功能,这些你可能仍需要手动调整。下面是一些常见的语法差异:
标识符引号
MySQL中使用反引号``来引用数据库、表、列等标识符。ProtonBase 使用双引号"
来引用标识符。
字符串引号
MySQL中使用单引号'
和双引号"
来引用字符串。ProtonBase只使用单引号'
来引用字符串。
LIMIT分页语法
MySQL支持LIMIT {偏移量}, {行数}
的语法进行分页,如 limit 20, 10。ProtonBase使用OFFSET {偏移量} LIMIT {行数}
的语法进行分页,如 offset 20 limit 10。
NULL
判断
MySQL 使用= NULL
或 != NULL
判断是否等于 NULL。ProtonBase 则是 IS NULL 或 IS NOT NULL。必须使用 IS NULL
,不能使用 =
或 !=
比较。
字符串拼接
MySQL 使用 CONCAT() 函数。ProtonBase 可以使用 ||
,如 'aa' || 'bb'。
Column must appear in the GROUP BY clause or be used in an aggregate
MySQL 里允许查询 ungrouped 字段,ProtonBase 里会报错,如下:
=> create table t(a int, b int, c int);
CREATE TABLE
=> select a, b, sum(c) from t group by a;
ERROR: column "t.b" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: select a, b, sum(c) from t group by a;
select 中的字段必须在 group by 中或者参与聚合操作。
Union/Union all 不同字段类型
MySQL在UNION查询中,不同字段类型会被自动转换为相容类型。ProtonBase在UNION查询中,如果字段类型不完全匹配,需要做类型转换。
=> create table t1(a int);
=> create table t2(b text);
=> select a from t1 union all select b from t2;
在MySQL中,虽然a和b类型不同,会自动进行类型转换。但在ProtonBase中,默认会报错,需要显式进行类型转换:
=> create table t2(b text);
=> select a from t1 union all select b from t2;
ERROR: UNION types integer and text cannot be matched
-- 转换 a 的类型为 text
=> select a::text from t1 union all select b from t2;
常见函数
MySQL 函数 | ProtonBase 函数 | 备注 |
CURDATE() | CURRENT_DATE | 返回当前日期,没有时间部分 |
DATABASE() | CURRENT_DATABASE() | ProtonBase 使用 CURRENT_DATABASE() 返回当前数据库名称 |
DATE_ADD(date, interval) | date + INTERVAL 'n unit' | ProtonBase 使用 INTERVAL 语法,支持日期加法 |
DATE_FORMAT(date, format) | TO_CHAR(date, format) | ProtonBase 使用 TO_CHAR 格式化日期 |
DATE_SUB(date, interval) | date - INTERVAL 'n unit' | ProtonBase 使用 INTERVAL 语法,支持日期减法 |
DATEDIFF(date1, date2) | date1 - date2 | ProtonBase 使用日期减法运算,返回天数差值 |
FORMAT(number, decimals) | TO_CHAR(number, 'FM999999.00') | ProtonBase 使用 TO_CHAR 格式化数字 |
FROM_UNIXTIME(unix_timestamp) | TO_TIMESTAMP(unix_timestamp) | TO_TIMESTAMP 将 UNIX 时间戳转换为时间 |
IF(condition, true_val, false_val) | CASE WHEN condition THEN true_val ELSE false_val END | ProtonBase 使用 CASE 语句代替 IF 函数 |
IFNULL(expr1, expr2) | COALESCE(expr1, expr2) | COALESCE 返回第一个非 NULL 的值 |
INSTR(str, substr) | POSITION(substr IN str) | ProtonBase 使用 POSITION 查找子串的位置 |
JSON_EXTRACT(json, path) | jsonb_extract_path(json, path) | ProtonBase 使用 jsonb_extract_path 提取 JSON 对象的值 |
JSON_UNQUOTE(json) | jsonb_extract_path_text(json, path) | ProtonBase 使用 jsonb_extract_path_text 提取 JSON 文本值 |
LAST_INSERT_ID() | RETURNING id 或 CURRVAL('seq_name') | ProtonBase 使用 RETURNING 返回插入后的自动增量主键值 |
MONTH(date) | EXTRACT(MONTH FROM date) | ProtonBase 使用 EXTRACT 获取日期的月份部分 |
RAND() | RANDOM() | ProtonBase 使用 RANDOM() 生成随机数 |
STR_TO_DATE(str, format) | TO_TIMESTAMP(str, format) | ProtonBase 使用 TO_TIMESTAMP 转换字符串为时间类型 |
UNIX_TIMESTAMP() | EXTRACT(EPOCH FROM NOW()) | ProtonBase 使用 EXTRACT(EPOCH FROM timestamp) 获取 UNIX 时间戳 |
YEAR(date) | EXTRACT(YEAR FROM date) | ProtonBase 使用 EXTRACT 获取日期的年份部分 |