引言

选择数据存储是构建软件应用时最关键的决策之一。根据具体应用的需求,您可以选择关系型数据库(如 MySQL 或 Postgres)、非关系型数据库(如 MongoDB 或 CouchDB)、图数据库(如 Neo4j)或其他各种选项。

尽管初始选择数据库时可能适合,现在却发现无法满足应用需求,您可能需要迁移数据库。在本文中,我们探讨如何从 PostgreSQL 迁移到 MySQL。MySQL 和 PostgreSQL 都是关系型数据库,存在许多相似之处,但也有一些显著的差异,使迁移充满挑战。


PostgreSQL 和 MySQL 的差异

以下表格列出两者之间的一些关键差异:

指标PostgreSQLMySQL
许可PostgreSQL 自由开源许可(类似 BSD/MIT)GNU 通用公共许可协议 (GPL)
ACID 支持支持支持
触发器支持INSERT/UPDATE/DELETE 有 AFTER/BEFORE/INSTEAD OF 支持INSERT/UPDATE/DELETE 仅支持 AFTER/BEFORE
无符号整数支持不支持支持
物化视图支持不支持
ANSI/ISO SQL 合规性完全合规大致合规
DROP TEMP TABLE 语法不支持 TEMP/TEMPORARY 关键字支持 TEMP/TEMPORARY 关键字
表分区支持 RANGE/LIST/HASH支持 RANGE/COLUMN/LIST/HASH/KEY 等
这些差异在决定迁移时需要慎重考虑。

示例迁移:从 PostgreSQL 到 MySQL

以下我们手动迁移 PostgreSQL 数据库至 MySQL,探讨迁移的底层考虑:

PostgreSQL 数据库概述

假设有以下数据库架构:

products 表

SQLCREATE TABLE products
(
    id SERIAL,
    name VARCHAR,
    description VARCHAR,
    price INTEGER
);

数据类型分析

  • VARCHAR:Postgres 中不需要设置最大长度值,而 MySQL 的 VARCHAR 类型需要指定最大长度或使用 TEXT 类型以避免迁移问题。
  • SERIAL:Postgres 会将 SERIAL 转换为递增整数类型,而 MySQL 则默认转换为 bigint unsigned auto_increment。
    将 products 表迁移至 MySQL:
SQLCREATE TABLE products
(
    id BIGINT UNSIGNED AUTO_INCREMENT,
    name TEXT,
    description TEXT,
    price INT,
    PRIMARY KEY (id)
);

customers 表

PostgreSQL 定义如下:

SQLCREATE TABLE customers
(
    id SERIAL,
    full_name VARCHAR,
    address VARCHAR,
    location POINT
);

迁移至 MySQL:

SQLCREATE TABLE customers
(
    id INT NOT NULL AUTO_INCREMENT,
    full_name TEXT,
    address TEXT,
    location POINT,
    PRIMARY KEY (id)
);

注意:

  1. MySQL 中的 POINT 类型需要利用函数如 ST_AsText() 解读存储的坐标数据。
  2. 如不希望依赖函数,可将坐标拆分为两个列定义为 DECIMAL,例如 location_latitude 和 location_longitude

orders 表

PostgreSQL 定义如下:

SQLCREATE TABLE orders
(
    id UUID default gen_random_uuid(),
    customer INTEGER,
    products JSONB
);

迁移至 MySQL:

SQLCREATE TABLE orders
(
    id VARCHAR(36) DEFAULT UUID(),
    customer INT,
    products JSON,
    PRIMARY KEY (id)
);

注意:

  1. UUID 类型可以用 MySQL 的 UUID() 函数生成,与 Postgres 的 gen_random_uuid() 类似。
  2. JSONB 类型在 MySQL 中可以用 JSON 类型代替,用于存储和查询结构化数据。

其他迁移注意事项

在从 PostgreSQL 至 MySQL 迁移时,还需考虑以下因素:

数据模型复杂性

尽管 MySQL 和 Postgres 支持多种传统 SQL 数据类型(如 String、Boolean、Integer、Timestamp),但 Postgres 支持的一些高级类型可能不存在于 MySQL 中。因此在迁移复杂数据结构时可能会遇到问题。

SQL 特性差异

  1. 临时表删除差异:Postgres 无法通过 TEMP/TEMPORARY 删除临时表,而 MySQL 可以。
  2. CASCADE:Postgres 的 TRUNCATE TABLE 支持 CASCADE、RESTART IDENTITY 等特性,而 MySQL 不支持。
  3. 存储过程写法:Postgres 支持多种语言编写(如 Python、Ruby),而 MySQL 只支持标准 SQL。
  4. 扩展功能:Postgres 的扩展可能会为迁移带来额外复杂性。

结论

从 PostgreSQL 到 MySQL 的迁移并非难以实现,但需要充分了解两者之间的差异,并根据具体的应用场景选择优化的解决方案。

MySQL 在常见场景下通常更具性能优势,同时拥有强大的扩展工具(如 Vitess 和 PlanetScale)来支持大规模数据库。了解两种技术的特点和适配场景,是选择数据库或迁移时最重要的考虑因素。希望本文能帮助您对迁移的过程和细节有更清晰的认知。



从 PostgreSQL 迁移至 MySQL插图

关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台

除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接

本文链接:http://choupangxia.cn/2025/09/11/postgresql-migrate-mysql/