文章目录
- 0. 前言
- 1. 数据库模式选择(B/PG)
- 2.驱动选择
- 2.1. 使用postgresql驱动
- 2.1. 使用opengaussjdbc驱动
- 3. 其他考虑因素
- 4. PG模式
- 4.1 MySQL和OpenGauss不兼容的语法处理建议
- 4.2 语法差异
- 6. 高斯数据库 PG模式JDBC 使用示例验证
- 6. 参考资料
本章节主要介绍MySQL项目迁移华为GaussDB PG模式指南
0. 前言
本文是关于如何将MySQL项目迁移到华为GaussDB PG模式的详细教程。
背景:在当今的国际形势严峻,很多卡脖子的技术搞得我们国内奋发图强,以华为为代表的国产数据库。在很多国企的系统中已经开始迁移。国产数据库的重要性不言而喻。
本文整理总计了一下从MySQL迁移到华为的GaussDB PG模式。这两种数据库在核心上有很大的不同,因此这个迁移过程可能会遇到一些困难。本文将详细介绍如何进行这种迁移,包括数据迁移,表结构迁移,以及索引、触发器、存储过程和函数的迁移等步骤。无论你是数据库管理员,还是只是想要了解这个过程的人,都可以从本文中获得有用的信息。
1. 数据库模式选择(B/PG)
GaussDB 是华为提供的一种数据库解决方案,它支持多种存储引擎和数据库模式。在 GaussDB 中,B 和 PG 分别是两种不同的数据库模式。
-
B 模式:这通常是基于 GaussDB 自己的原生存储引擎。这种模式可能提供更多的高级特性和优化,特别是针对大规模、高并发的环境。
-
PG 模式:这是基于 PostgreSQL 的模式。如果你的应用或系统已经在使用 PostgreSQL,或者你需要一个与 PostgreSQL 兼容的解决方案,那么这可能是更好的选择。
2.驱动选择
2.1. 使用postgresql驱动
如果使用PG模式,在3.x版本可以直接使用pgSQL的驱动我们项目亲测
在代码中创建连接之前任意位置隐含装载:Class.forName(“org.postgresql.Driver”);
在JVM启动时参数传递:java -Djdbc.drivers=org.postgresql.Driver jdbctest
这些文件都是不同版本的OpenGauss JDBC驱动,用于Java应用程序连接到OpenGauss数据库。
2.1. 使用opengaussjdbc驱动
当使用opengaussjdbc.jar时,上面的Driver类名相应修改为“com.huawei.opengauss.jdbc.Driver”。
文件名称 | 说明 | 文件大小 | 最后修改时间 |
---|---|---|---|
gsjdbc200.jar | 针对某些版本的Java(如Java 2.0)的OpenGauss JDBC驱动 | 909 kB | 2023/3/27 00:43:23 |
gsjdbc4.jar | 针对Java 4或更高版本的OpenGauss JDBC驱动 | 896 kB | 2023/3/27 00:43:23 |
opengaussjdbc.jar | 通用的OpenGauss JDBC驱动 | 909 kB | 2023/3/27 00:43:23 |
3. 其他考虑因素
-
兼容性:
如果你需要与 PostgreSQL 兼容,那么 PG 模式可能是更好的选择。
-
性能需求:
对于特定的高性能或大规模需求,B 模式可能提供更多的优化选项。
-
特性需求:
某些高级功能可能只在特定的模式下可用。
-
团队经验:
如果你的团队有更多的 PostgreSQL 经验,那么 PG 模式可能更适合;反之亦然。
-
迁移和集成:
考虑到数据迁移和系统集成的复杂性和成本,选择一个与现有系统更兼容的模式。
-
成本:
不同的模式可能有不同的成本结构,包括授权费用和运维成本。
项目迁移数据库类型可是一个大工程,在迁移之初一定要做好充分的调研。建议在确定模式之前,进行性能和兼容性测试,以确保你的选择能满足业务和技术需求。
在 GaussDB 的 PG 模式下,虽然它已经做出了很大的努力来实现对 PostgreSQL 的兼容,但仍然可能存在一些与 MySQL 不兼容的情况。如果你在迁移过程中遇到了这样的问题,以下是一些处理建议:
-
了解两种数据库的差异:首先,你需要理解 MySQL 和 OpenGauss(GaussDB 的 PG 模式)在 SQL 语法、数据类型、函数、存储过程等方面的差异。这将帮助你更好地理解迁移过程中可能出现的问题。
-
使用数据库迁移工具:对于大规模的数据库迁移,手动修改 SQL 语句可能并不现实。你可以考虑使用数据库迁移工具,如 AWS DMS(Database Migration Service)或 Azure Database Migration Service,这些工具可以自动处理一些常见的不兼容问题。
-
手动修改 SQL 语句:对于一些特定的不兼容问题,你可能需要手动修改你的 SQL 语句。例如,MySQL 使用
AUTO_INCREMENT
在表定义中创建自增字段,而 OpenGauss 使用SERIAL
数据类型。对于这样的差异,你需要手动修改你的表定义。 -
修改应用代码:在某些情况下,你可能需要修改你的应用代码来适应新的数据库。例如,如果你的应用依赖于 MySQL 的特定功能(如全文搜索或地理空间查询),你可能需要重新实现这些功能以使用 OpenGauss 的等价功能。
4. PG模式
4.1 MySQL和OpenGauss不兼容的语法处理建议
以下是在GaussDB PG(OpenGauss)和MySQL之间的一些主要的SQL语法不兼容性。这个列表包含了一些主要的不同之处,但并不是全部的不兼容性。在进行迁移之前,建议深入对比和测试以确保兼容性。
MySQL | OpenGauss | 备注 |
---|---|---|
AUTO_INCREMENT | SERIAL | 序列生成器 |
SHOW TABLES | \dt | 查看所有表 |
SHOW DATABASES | \l | 查看所有数据库 |
LIMIT n OFFSET m | LIMIT n OFFSET m 或 FETCH FIRST n ROWS ONLY OFFSET m | 分页查询 |
DESCRIBE table or DESC table | \d table | 描述表结构 |
CONCAT(str1, str2, ...) | `str1 | |
SUBSTRING(str, pos, len) | SUBSTRING(str FROM pos FOR len) | 子字符串 |
LENGTH(str) | LENGTH(str) 或CHAR_LENGTH(str) | 字符串长度 |
CURDATE() | CURRENT_DATE | 当前日期 |
NOW() | CURRENT_TIMESTAMP | 当前时间 |
RAND() | RANDOM() | 生成随机数 |
IFNULL(exp, replace_exp) | COALESCE(exp, replace_exp) | 判断表达式是否为空 |
ISNULL(exp) | exp IS NULL | 判断表达式是否为空 |
` 作为标识符引用符 | " 作为标识符引用符 | 标识符引用符 |
存储过程使用 BEGIN 和 END | 存储过程使用 $$ | 存储过程定义 |
TRUNCATE TABLE 不可在事务中 | TRUNCATE TABLE 可在事务中 | 清空表数据 |
REPLACE INTO | INSERT ... ON CONFLICT DO UPDATE | 插入冲突更新 |
REGEXP | ~ | 正则表达式搜索 |
CREATE DATABASE 不支持所有者 | CREATE DATABASE 支持所有者 | 创建数据库 |
ENUM 类型 | 无对应,可用 CHECK 约束代替 | 类型不一致 |
SET 类型 | 无对应,可用 ARRAY 类型代替 | 类型不一致 |
YEAR 类型 | 无对应,可用 INTERVAL YEAR 或 DATE 类型代替 | 类型不一致 |
UNSIGNED 类型 | 无对应,需注意数值范围 | 类型不一致 |
ZEROFILL 类型 | 无对应,需在应用层处理 | 类型不一致 |
SHOW CREATE TABLE | pg_dump -t table -s | 查看表创建语句 |
ENGINE = InnoDB | 无对应 | 存储引擎 |
CHARSET = utf8mb4 | ENCODING = UTF8 | 字符集 |
COLLATE = utf8mb4_bin | COLLATE "C" | 排序规则 |
分区表 | 分区表 | 分区定义语法不同 |
CREATE USER | CREATE ROLE | 创建用户 |
REVOKE ALL PRIVILEGES | REVOKE ALL | 撤销权限 |
GRANT SELECT ON *.* | GRANT SELECT ON ALL TABLES IN SCHEMA | 授予权限 |
/*!50003 CREATE*/ | CREATE OR REPLACE | 创建或替换 |
LOCK TABLES | LOCK TABLE | 锁表 |
UNLOCK TABLES | COMMIT | 解锁 |
KILL QUERY | CANCEL | 取消查询 |
SHOW PROCESSLIST | SELECT * FROM pg_stat_activity | 查看进程列表 |
LOAD DATA INFILE | COPY | 数据导入 |
SELECT INTO OUTFILE | COPY TO | 数据导出 |
RENAME COLUMN | ALTER COLUMN RENAME | 重命名列 |
RENAME INDEX | ALTER INDEX RENAME | 重命名索引 |
RENAME DATABASE | 无对应 | 重命名数据库 |
ALTER DATABASE 不支持修改所有者 | ALTER DATABASE 支持修改所有者 | 修改数据库所有者 |
ALTER DATABASE 支持修改字符集和排序规则 | ALTER DATABASE 不支持修改字符集和排序规则 | 修改数据库字符集和排序规则 |
ALTER TABLE 支持一次修改多个列 | ALTER TABLE 一次只能修改一个列 | 修改表列 |
ALTER TABLE 支持一次添加多个索引 | ALTER TABLE 一次只能添加一个索引 | 添加表索引 |
ALTER TABLE 支持一次删除多个索引 | ALTER TABLE 一次只能删除一个索引 | 删除表索引 |
ALTER TABLE 支持修改存储引擎 | ALTER TABLE 不支持修改存储引擎 | 修改表存储引擎 |
ALTER TABLE 支持修改字符集和排序规则 | ALTER TABLE 不支持修改字符集和排序规则 | 修改表字符集和排序规则 |
ALTER TABLE 支持修改自增值 | ALTER TABLE 不支持修改自增值 | 修改表自增值 |
4.2 语法差异
序号 | 描述 | MySQL | GaussDB PG |
---|---|---|---|
1 | 插入并在存在时更新 | REPLACE INTO 或 INSERT … ON DUPLICATE KEY UPDATE … | INSERT … ON CONFLICT DO UPDATE … |
2 | 使用 LIMIT 进行分页查询 | SELECT … LIMIT offset, count | SELECT … LIMIT count OFFSET offset |
3 | 单行插入返回插入的 ID | INSERT INTO …; SELECT LAST_INSERT_ID(); | INSERT INTO … RETURNING id; |
4 | 单行更新返回更新的行 | UPDATE …; SELECT …; | UPDATE … RETURNING *; |
5 | 单行删除返回删除的行 | DELETE …; SELECT …; | DELETE … RETURNING *; |
6 | 随机获取一行记录 | SELECT … ORDER BY RAND() LIMIT 1 | SELECT … ORDER BY RANDOM() LIMIT 1 |
7 | 索引字段查询优化 | SELECT * FROM table USE INDEX(index) WHERE column = value | SET enable_seqscan TO OFF; SELECT * FROM table WHERE column = value; SET enable_seqscan TO ON; |
8 | 使用全文索引搜索 | MATCH(column) AGAINST(‘text’) | to_tsvector(column) @@ to_tsquery(‘text’) |
9 | 查询特定范围的行 | SELECT * FROM table LIMIT x, y | SELECT * FROM table LIMIT y OFFSET x |
10 | 使用存储过程 | CALL procedure_name() | SELECT * FROM procedure_name() |
11 | 事务处理 | START TRANSACTION; COMMIT; ROLLBACK; | BEGIN; COMMIT; ROLLBACK; |
12 | 创建临时表 | CREATE TEMPORARY TABLE table_name | CREATE TEMP TABLE table_name |
13 | MySQL使用反引号(``)引用表名和列名 | SELECT column FROM table | SELECT “column” FROM “table” |
14 | 时间和日期函数 | DATE(), NOW(), YEAR(), MONTH(), DAY(), HOUR(), MINUTE(), SECOND() | CURRENT_DATE, CURRENT_TIME, DATE_PART(‘year’, column), DATE_PART(‘month’, column), DATE_PART(‘day’, column), DATE_PART(‘hour’, column), DATE_PART(‘minute’, column), DATE_PART(‘second’, column) |
15 | 字符串连接函数 | CONCAT(column1, column2) | column1 |
16 | 对分组的限制 | SELECT … FROM … GROUP BY … WITH ROLLUP | SELECT … FROM … GROUP BY … ROLLUP(…) |
17 | 对NULL的处理 | SELECT IFNULL(column, 0) FROM table | SELECT COALESCE(column, 0) FROM table |
18 | 判断是否为空 | SELECT column IS NULL FROM table | SELECT column IS NULL FROM table |
19 | 日期加减操作 | SELECT DATE_ADD(date, INTERVAL 1 DAY) FROM table | SELECT date + INTERVAL ‘1 day’ FROM table |
20 | 创建自增主键 | CREATE TABLE table (id INT AUTO_INCREMENT, PRIMARY KEY (id)) | CREATE TABLE table (id SERIAL PRIMARY KEY) |
21 | 使用正则表达式匹配数据 | SELECT column REGEXP ‘pattern’ FROM table | SELECT column ~ ‘pattern’ FROM table |
22 | 计算平均值 | SELECT AVG(column) FROM table | SELECT AVG(column) FROM table |
23 | 计算最大值 | SELECT MAX(column) FROM table | SELECT MAX(column) FROM table |
24 | 计算最小值 | SELECT MIN(column) FROM table | SELECT MIN(column) FROM table |
25 | 计算总和 | SELECT SUM(column) FROM table | SELECT SUM(column) FROM table |
26 | 计算记录数 | SELECT COUNT(column) FROM table | SELECT COUNT(column) FROM table |
27 | 使用内置数学函数 | SELECT ABS(column), CEIL(column), FLOOR(column), ROUND(column) FROM table | SELECT ABS(column), CEILING(column), FLOOR(column), ROUND(column) FROM table |
28 | 使用内置字符串函数 | SELECT CHAR_LENGTH(column), LOWER(column), UPPER(column), REVERSE(column) FROM table | SELECT LENGTH(column), LOWER(column), UPPER(column), REVERSE(column) FROM table |
29 | 使用内置日期函数 | SELECT CURRENT_DATE(), CURRENT_TIME(), DATE_FORMAT(date, ‘format’) FROM table | SELECT CURRENT_DATE, CURRENT_TIME, TO_CHAR(date, ‘format’) FROM table |
30 | 使用内置转换函数 | SELECT CAST(column AS type) FROM table | SELECT CAST(column AS type) FROM table |
在华为GaussDB PG模式迁移MySQL项目中,这个过程可能会涉及到数据、表结构、索引、触发器、存储过程和函数的迁移。以下是一些具体步骤:
准备工作:
- 确保MySQL和GaussDB PG版本所支持的功能是兼容的。
- 在GaussDB PG创建一个新的数据库来保存迁移过来的数据。
- 确保你的MySQL数据已经被备份。
步骤1: 数据迁移
- 使用mysqldump工具导出MySQL数据库的数据。例如:mysqldump -u [username] -p [password] [database_name] > [dump_file.sql]
- 使用pgloader工具将MySQL数据导入到GaussDB PG中。例如:pgloader mysql://[username]:[password]@localhost/[database_name] postgresql:///new_database
步骤2: 表结构迁移
- 使用MySQL 客户端等工具查看MySQL的表结构。
- 根据MySQL的表结构,在GaussDB PG中创建相应的表结构,也可以在找找其他工具是否可以批量同步生成。
- 请注意,MySQL和GaussDB PG中的数据类型可能是不一样的,所以在创建表结构时,需要做相应的类型转换。
步骤3: 索引、触发器、存储过程和函数的迁移
- 通过SHOW INDEX FROM [table_name]在MySQL中查看索引。
- 在GaussDB PG中创建相应的索引。
- 通过SHOW TRIGGERS在MySQL中查看触发器。
- 在GaussDB PG中创建相应的触发器。
- 使用SHOW PROCEDURE STATUS和SHOW FUNCTION STATUS在MySQL中查看存储过程和函数。
- 在GaussDB PG中创建相应的存储过程和函数。
注意:这些步骤可能需要一些SQL知识,并且在迁移过程中可能会遇到一些问题,比如数据类型不匹配、编码问题等,需要根据实际情况进行调整。
6. 高斯数据库 PG模式JDBC 使用示例验证
高斯数据库(GaussDB)。对于PG模式,可以使用PostgreSQL JDBC驱动来连接。
添加PostgreSQL JDBC驱动的Maven依赖:
<dependencies><!-- PostgreSQL JDBC driver --><dependency><groupId>org.postgresql</groupId><artifactId>postgresql</artifactId><version>42.3.1</version> <!-- 这里的版本号根据实际情况更改 --></dependency>
</dependencies>
可以使用以下Java代码来连接到GaussDB并执行查询。如果是使用持久化框架,比如MyBatis 或者MP 或者JPA hbernate 等就不需要手动创建连接。只需要换一下配置中的jdbc连接串
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;public class Main {public static void main(String[] args) {try {// 加载驱动Class.forName("org.postgresql.Driver");// 连接数据库,注意URL的格式,包括服务器地址、端口、数据库名、SSL和其他参数String url = "jdbc:postgresql://your_server:your_port/your_database?ssl=true&"+ "sslfactory=org.postgresql.ssl.NonValidatingFactory";Connection conn = DriverManager.getConnection(url, "your_user", "your_password");// 创建一个Statement对象并执行SQL查询Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery("SELECT * FROM your_table");// 处理查询结果while (rs.next()) {System.out.println(rs.getString("your_column"));}// 关闭连接rs.close();stmt.close();conn.close();} catch (Exception e) {e.printStackTrace();}}
}
6. 参考资料
- GaussDB官方文档:https://support.huaweicloud.com/intl/zh-cn/opengauss/index.html
- PostgreSQL JDBC驱动的官方文档:https://www.postgresql.org/