跳到正文
IntoSQL 首页

将 MySQL 转储迁移到更旧或更新的 MySQL

拖入 MySQL 5.5 到 9 由 mysqldump、mysqlpump、phpMyAdmin 或 Adminer 生成的转储,格式为 .sql 或 .sql.gz,即可下载可在 MySQL 5.7 及以上导入的脚本。只有 MySQL 8 及以上才有的排序规则,例如 utf8mb4_0900_ai_ci,会变为 utf8mb4_unicode_520_ci,每项更改都会列在报告中。

你的文件
sqlshop_2024.sql示例文件,5.1 kB
你的数据库

已转换 18 行,2 处修正,无拒绝

显示

shop_2024.sql 中的表MySQL 8.0.46 转储 · 由 mysqldump 写出 · utf8mb4

  • customers8 行1
    7 列
    idint unsigned not null
    namevarchar(100) not null
    emailvarchar(150) not null
    countrychar(2) not null
    is_activetinyint(1) not null
    signed_update not null
    created_attimestamp not null
  • orders10 行1
    9 列
    idint unsigned not null
    customer_idint unsigned not null
    statusenum('pending','paid','shipped','cancelled') not null
    totaldecimal(10,2) not null
    itemssmallint unsigned not null
    ordered_atdatetime not null
    shipped_atdatetime
    notevarchar(255)
    updated_attimestamp not null
-- Written by IntoSQL from a MySQL dump. Load it with: mysql --default-character-set=utf8mb4 <database> < <file>
SET NAMES utf8mb4;
SET TIME_ZONE = '+00:00';
SET FOREIGN_KEY_CHECKS = 0;
SET UNIQUE_CHECKS = 0;
SET SQL_MODE = 'NO_AUTO_VALUE_ON_ZERO,ALLOW_INVALID_DATES';

CREATE TABLE `customers` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `email` varchar(150) NOT NULL,
  `country` char(2) NOT NULL DEFAULT 'US',
  `is_active` tinyint(1) NOT NULL DEFAULT 1,
  `signed_up` date NOT NULL DEFAULT '0000-00-00',
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uq_email` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci COMMENT='People who bought at least once';

CREATE TABLE `orders` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `customer_id` int unsigned NOT NULL,
  `status` enum('pending','paid','shipped','cancelled') NOT NULL DEFAULT 'pending',
  `total` decimal(10,2) NOT NULL,
  `items` smallint unsigned NOT NULL DEFAULT 1,
  `ordered_at` datetime NOT NULL,
  `shipped_at` datetime DEFAULT NULL,
  `note` varchar(255) DEFAULT NULL,
  `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_customer` (`customer_id`),
  KEY `idx_status_date` (`status`,`ordered_at`),
  CONSTRAINT `fk_orders_customer` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;

INSERT INTO `customers` (`id`,`name`,`email`,`country`,`is_active`,`signed_up`,`created_at`) VALUES (1,'Ana Martínez','ana@example.com','MX',1,'2023-01-15','2023-01-15 10:24:00'),(2,'Zoë Müller','zoe@example.de','DE',1,'2023-02-03','2023-02-03 08:11:42'),(3,'José Peña','jose@example.es','ES',0,'2023-03-21','2023-03-21 19:05:17'),(4,'李雷','lilei@example.cn','CN',1,'2023-05-09','2023-05-09 02:40:00'),(5,'Noah O\'Brien','noah@example.ie','IE',1,'0000-00-00','2023-06-30 14:00:00'),(6,'Amélie Laurent','amelie@example.fr','FR',1,'2024-01-02','2024-01-02 09:30:00'),(7,'Ravi Patel','ravi@example.in','IN',0,'2024-02-29','2024-02-29 23:59:59'),(8,'Sofia Rossi 🌻','sofia@example.it','IT',1,'2024-04-12','2024-04-12 12:12:12');
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`updated_at`) VALUES (1,1,'shipped',129.90,3,'2024-03-01 10:00:00','2024-03-02 16:30:00',NULL,'2024-03-02 16:30:00'),(2,2,'paid',54.00,1,'2024-03-02 11:15:00',NULL,'Gift wrap 🎁','2024-03-02 11:20:00'),(3,1,'cancelled',12.50,1,'2024-03-03 09:45:00',NULL,'Customer changed their mind','2024-03-03 10:00:00'),(4,4,'shipped',980.00,12,'2024-03-05 02:10:00','2024-03-07 08:00:00','请小心轻放','2024-03-07 08:00:00'),(5,5,'pending',45.75,2,'2024-03-08 17:20:00',NULL,'Leave at the door; ring twice','2024-03-08 17:20:00'),(6,6,'shipped',310.40,5,'2024-03-10 13:00:00','2024-03-11 09:00:00','Fragile: \"glass\"','2024-03-11 09:00:00'),(7,8,'paid',76.20,2,'2024-03-11 18:45:00',NULL,NULL,'2024-03-11 18:46:00'),(8,2,'',19.99,1,'2024-03-12 08:00:00',NULL,'Status lost in an old import','2024-03-12 08:00:00'),(9,3,'shipped',64.00,2,'2024-03-14 15:30:00','0000-00-00 00:00:00','Shipping date never recorded','2024-03-15 10:00:00'),(10,7,'paid',1499.00,1,'2024-03-15 21:05:00',NULL,'C:\\Users\\ravi\\invoice.pdf','2024-03-15 21:05:00');

SET UNIQUE_CHECKS = 1;
SET FOREIGN_KEY_CHECKS = 1;

修正

  1. customers 使用排序规则 utf8mb4_0900_ai_ci,MySQL 没有该规则,因此使用 utf8mb4_unicode_520_ci;文本的排序和比较可能略有不同。
  2. orders 使用排序规则 utf8mb4_0900_ai_ci,MySQL 没有该规则,因此使用 utf8mb4_unicode_520_ci;文本的排序和比较可能略有不同。

文件在这台电脑上转换,永远不会上传。

其他示例:

文件与脚本之间的变化

每一行是转换器应用的一条规则,以及该规则更改你的数据时在报告中写入的记录。

  • utf8mb4_0900_* and utf8mb4_uca1400_* collations

    utf8mb4_unicode_520_ci(二进制排序规则用 utf8mb4_bin)

    MySQL 不认识较新的排序规则,这正是大多数 MySQL 8 转储在别处无法导入的原因。unicode_520 最接近相同的 Unicode 规则。

    报告记录: collation_replaced

  • zero, partial or impossible dates (0000-00-00, 2024-02-30)

    保留

    脚本以 ALLOW_INVALID_DATES 且不带 NO_ZERO_DATE 导入,因此 MySQL 保留与源数据相同的值。

  • TIME

    TIME,包括时长

    相同的类型,相同的范围。

  • TINYINT(1), BOOL

    TINYINT(1)

    相同的类型,相同的值。

  • UNSIGNED and ZEROFILL

    保留

    相同的类型。

  • ENUM and SET, the '' error value included

    保留

    相同的类型;脚本在非严格模式下导入,因此错误值按原样导入。

  • JSON

    JSON

    MySQL 读取相同的 JSON 文本。

  • NUL bytes in text

    保留

    值按源数据使用的相同转义复制。

  • AUTO_INCREMENT

    AUTO_INCREMENT,带表的计数器

    计数器从源数据停下的位置继续,包括 MyISAM 的分组计数器。

  • MyISAM AUTO_INCREMENT on the second column of a key, in a table that isn't MyISAM in the dump

    列上的一个索引,整个表一个计数器

    InnoDB 只在列位于索引首位时才为其计数,并且整个表只计一个。

    报告记录: myisam_group_autoincrement

  • ON UPDATE CURRENT_TIMESTAMP

    保留

    相同的子句,保留列的秒小数部分。

  • generated columns

    与源数据一样为 VIRTUAL 或 STORED

    相同的公式,逐项转换。

  • generated columns with functions IntoSQL doesn't read

    普通列

    IntoSQL 无法读取的公式会留下一个普通列和一条报告记录。

    报告记录: generated_not_translated

  • INVISIBLE columns

    普通列

    MySQL 从 8.0.23 起支持不可见列,MariaDB 从 10.3 起支持。

    报告记录: invisible_column

  • CHECK constraints

    保留(MySQL 5.7 会解析并忽略它们)

    相同的检查约束,逐项转换。

  • CHECK constraints with functions IntoSQL doesn't read

    不创建

    IntoSQL 无法读取的检查约束会被省略,并在报告中列出。

    报告记录: check_skipped

  • CHECK ... NOT ENFORCED

    不创建

    MySQL 5.7 和 MariaDB 无法保留不执行的检查约束,而行可能违反它。

    报告记录: check_not_enforced

  • expression defaults, and defaults on TEXT, BLOB, JSON and GEOMETRY

    无默认值

    MySQL 从 8.0.13 起接受它们;脚本要在 5.7 上导入,因此它们会被省略并在报告中列出。MariaDB 接受它们。

    报告记录: default_not_translated

  • functional indexes, KEY ((expr))

    不创建

    MySQL 从 8.0.13 起支持表达式索引,MariaDB 完全不支持;带索引的生成列可以达到同样效果。

    报告记录: index_skipped

  • keys and indexes on a prefix, c(20)

    保留

    相同的索引。

  • FULLTEXT indexes

    保留

    相同的索引;MATCH ... AGAINST 照常工作。

  • SPATIAL indexes

    保留

    相同的索引。

  • foreign keys

    保留,以 FOREIGN_KEY_CHECKS=0 导入

    相同的键;行的导入方式与源转储相同。

  • GEOMETRY, POINT, POLYGON...

    保留,带每个值的 SRID

    复制服务器自身的几何字节,包括 SRID。

  • INET4, INET6, UUID (MariaDB)

    varchar(15), varchar(39), char(36)

    MySQL 没有这些类型;保留 MariaDB 为它们写出的文本。

    报告记录: type_replaced

  • BINARY, VARBINARY, BLOB

    保留

    字节仍然是字节。

  • PARTITION BY

    单个表

    行保持不变;如有需要,请重新对该表分区。

    报告记录: partitions_dropped

  • WITH SYSTEM VERSIONING (MariaDB)

    只含当前行的表

    转储只包含当前的行;MySQL 没有系统版本控制。

    报告记录: system_versioning_dropped

  • Aria, ColumnStore, CONNECT, Spider, RocksDB (MariaDB)

    InnoDB

    MySQL 没有这些引擎。其他引擎都会保留。

    报告记录: engine_dropped

  • CREATE SEQUENCE (MariaDB)

    不创建

    MySQL 没有序列。

    报告记录: sequence_not_converted

  • views, triggers, procedures, functions and events

    在报告中列出

    它们会列出来,由你重新创建;其代码通常会指定定义者和服务器特性。

    报告记录: not_converted_objects

  • NOT NULL columns with values that become NULL

    去除 NOT NULL

    值必须变为 NULL 的列无法保留 NOT NULL,否则导入会中止。

    报告记录: not_null_relaxed

  • text that isn't valid in its character set

    错误的字节变为替换字符

    脚本是 UTF-8;不是 UTF-8 的字节会使导入中止。

    报告记录: invalid_utf8_replaced

  • text decoded twice (ñ)

    按原样复制

    转储中存储的正是这些字符,因此按原样复制;报告会指出它们。

    报告记录: mojibake_suspected

  • dumps without CREATE TABLE

    根据值推断类型

    使用 --no-create-info 生成的转储只有行,因此类型来自值。

    报告记录: no_schema

  • geometries in a dump without CREATE TABLE

    GEOMETRY

    MySQL 的几何格式根据值识别。

  • SET NAMES utf8 from utf8mb4 tables

    已转换,并给出警告

    MySQL 5.x 的 mysqldump 默认写出 3 字节 utf8,在任何转换器看到文件之前就已把每个 emoji 替换为问号。

    报告记录: dump_lost_four_byte_chars

  • dumps without SET NAMES whose text isn't UTF-8

    按 Latin-1 (Windows-1252) 读取

    MySQL 的 latin1 就是 Windows-1252,这是此类转储常用的编码。

    报告记录: charset_guessed

  • sjis, cp932, gbk, big5 dumps

    按 UTF-8 读取,并给出警告

    这些编码暂时无法解码。

    报告记录: unsupported_charset

  • UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows

    求值

    有些转储工具把值写成这些函数调用;它们按其产生的值读取。

  • other expressions in rows

    NULL

    不运行数据库的转换器无法对它们求值。

    报告记录: expression_value

  • DEFAULT in VALUES

    该列的默认值

    字面量默认值会复制到该行中。

    报告记录: default_keyword_filled

  • DEFAULT in VALUES without a literal default

    NULL

    没有可复制的值。

    报告记录: default_keyword_null

  • REPLACE and INSERT IGNORE

    普通行

    转储中每个键只有一行,因此行是相同的。

    报告记录: replace_as_insert

  • types IntoSQL doesn't know

    LONGBLOB

    blob 可以容纳任何值的字节;请在导入后更改类型。

    报告记录: unknown_type

  • values that don't fit their column

    NULL

    损坏或手写的转储可能包含列无法容纳的值;这些值变为 NULL,以便其余数据能够导入。

    报告记录: invalid_value_null

  • unreadable geometries

    NULL

    不是几何数据的字节无法作为几何数据存储。

    报告记录: bad_geometry

  • TIMESTAMP

    保留,按转储声明的时区导入

    脚本设置与转储相同的时区,因此每个时间点都保持不变。

  • VECTOR(n) (MariaDB 11.7+)

    json,浮点数存为数组

    MySQL 5.7 和 8.0 没有向量类型;JSON 数组在每个版本上都保留每个浮点数。

    报告记录: type_replaced

文件中脚本中报告记录
utf8mb4_0900_* and utf8mb4_uca1400_* collationsutf8mb4_unicode_520_ci(二进制排序规则用 utf8mb4_bin)MySQL 不认识较新的排序规则,这正是大多数 MySQL 8 转储在别处无法导入的原因。unicode_520 最接近相同的 Unicode 规则。collation_replaced
zero, partial or impossible dates (0000-00-00, 2024-02-30)保留脚本以 ALLOW_INVALID_DATES 且不带 NO_ZERO_DATE 导入,因此 MySQL 保留与源数据相同的值。
TIMETIME,包括时长相同的类型,相同的范围。
TINYINT(1), BOOLTINYINT(1)相同的类型,相同的值。
UNSIGNED and ZEROFILL保留相同的类型。
ENUM and SET, the '' error value included保留相同的类型;脚本在非严格模式下导入,因此错误值按原样导入。
JSONJSONMySQL 读取相同的 JSON 文本。
NUL bytes in text保留值按源数据使用的相同转义复制。
AUTO_INCREMENTAUTO_INCREMENT,带表的计数器计数器从源数据停下的位置继续,包括 MyISAM 的分组计数器。
MyISAM AUTO_INCREMENT on the second column of a key, in a table that isn't MyISAM in the dump列上的一个索引,整个表一个计数器InnoDB 只在列位于索引首位时才为其计数,并且整个表只计一个。myisam_group_autoincrement
ON UPDATE CURRENT_TIMESTAMP保留相同的子句,保留列的秒小数部分。
generated columns与源数据一样为 VIRTUAL 或 STORED相同的公式,逐项转换。
generated columns with functions IntoSQL doesn't read普通列IntoSQL 无法读取的公式会留下一个普通列和一条报告记录。generated_not_translated
INVISIBLE columns普通列MySQL 从 8.0.23 起支持不可见列,MariaDB 从 10.3 起支持。invisible_column
CHECK constraints保留(MySQL 5.7 会解析并忽略它们)相同的检查约束,逐项转换。
CHECK constraints with functions IntoSQL doesn't read不创建IntoSQL 无法读取的检查约束会被省略,并在报告中列出。check_skipped
CHECK ... NOT ENFORCED不创建MySQL 5.7 和 MariaDB 无法保留不执行的检查约束,而行可能违反它。check_not_enforced
expression defaults, and defaults on TEXT, BLOB, JSON and GEOMETRY无默认值MySQL 从 8.0.13 起接受它们;脚本要在 5.7 上导入,因此它们会被省略并在报告中列出。MariaDB 接受它们。default_not_translated
functional indexes, KEY ((expr))不创建MySQL 从 8.0.13 起支持表达式索引,MariaDB 完全不支持;带索引的生成列可以达到同样效果。index_skipped
keys and indexes on a prefix, c(20)保留相同的索引。
FULLTEXT indexes保留相同的索引;MATCH ... AGAINST 照常工作。
SPATIAL indexes保留相同的索引。
foreign keys保留,以 FOREIGN_KEY_CHECKS=0 导入相同的键;行的导入方式与源转储相同。
GEOMETRY, POINT, POLYGON...保留,带每个值的 SRID复制服务器自身的几何字节,包括 SRID。
INET4, INET6, UUID (MariaDB)varchar(15), varchar(39), char(36)MySQL 没有这些类型;保留 MariaDB 为它们写出的文本。type_replaced
BINARY, VARBINARY, BLOB保留字节仍然是字节。
PARTITION BY单个表行保持不变;如有需要,请重新对该表分区。partitions_dropped
WITH SYSTEM VERSIONING (MariaDB)只含当前行的表转储只包含当前的行;MySQL 没有系统版本控制。system_versioning_dropped
Aria, ColumnStore, CONNECT, Spider, RocksDB (MariaDB)InnoDBMySQL 没有这些引擎。其他引擎都会保留。engine_dropped
CREATE SEQUENCE (MariaDB)不创建MySQL 没有序列。sequence_not_converted
views, triggers, procedures, functions and events在报告中列出它们会列出来,由你重新创建;其代码通常会指定定义者和服务器特性。not_converted_objects
NOT NULL columns with values that become NULL去除 NOT NULL值必须变为 NULL 的列无法保留 NOT NULL,否则导入会中止。not_null_relaxed
text that isn't valid in its character set错误的字节变为替换字符脚本是 UTF-8;不是 UTF-8 的字节会使导入中止。invalid_utf8_replaced
text decoded twice (ñ)按原样复制转储中存储的正是这些字符,因此按原样复制;报告会指出它们。mojibake_suspected
dumps without CREATE TABLE根据值推断类型使用 --no-create-info 生成的转储只有行,因此类型来自值。no_schema
geometries in a dump without CREATE TABLEGEOMETRYMySQL 的几何格式根据值识别。
SET NAMES utf8 from utf8mb4 tables已转换,并给出警告MySQL 5.x 的 mysqldump 默认写出 3 字节 utf8,在任何转换器看到文件之前就已把每个 emoji 替换为问号。dump_lost_four_byte_chars
dumps without SET NAMES whose text isn't UTF-8按 Latin-1 (Windows-1252) 读取MySQL 的 latin1 就是 Windows-1252,这是此类转储常用的编码。charset_guessed
sjis, cp932, gbk, big5 dumps按 UTF-8 读取,并给出警告这些编码暂时无法解码。unsupported_charset
UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows求值有些转储工具把值写成这些函数调用;它们按其产生的值读取。
other expressions in rowsNULL不运行数据库的转换器无法对它们求值。expression_value
DEFAULT in VALUES该列的默认值字面量默认值会复制到该行中。default_keyword_filled
DEFAULT in VALUES without a literal defaultNULL没有可复制的值。default_keyword_null
REPLACE and INSERT IGNORE普通行转储中每个键只有一行,因此行是相同的。replace_as_insert
types IntoSQL doesn't knowLONGBLOBblob 可以容纳任何值的字节;请在导入后更改类型。unknown_type
values that don't fit their columnNULL损坏或手写的转储可能包含列无法容纳的值;这些值变为 NULL,以便其余数据能够导入。invalid_value_null
unreadable geometriesNULL不是几何数据的字节无法作为几何数据存储。bad_geometry
TIMESTAMP保留,按转储声明的时区导入脚本设置与转储相同的时区,因此每个时间点都保持不变。
VECTOR(n) (MariaDB 11.7+)json,浮点数存为数组MySQL 5.7 和 8.0 没有向量类型;JSON 数组在每个版本上都保留每个浮点数。type_replaced

将脚本导入 MySQL

脚本先创建表、复制行,再添加键、索引和外键,因此导入速度快,并会在遇到第一个错误时停止。

mysql --default-character-set=utf8mb4 mydb < mysql.mysql.sql

外键按转储中的声明创建,导入行时使用 FOREIGN_KEY_CHECKS=0,因此指向不存在的行的行不会中止导入。

对于较大的转储,请在服务器所在的机器上运行客户端;如果单行非常大,请调高 max_allowed_packet。

IntoSQL Pro 可以通过桌面应用或命令行将文件直接导入 MySQL,无需生成脚本。

如何转储 MySQL 以获得最佳结果

转换器读取转储中的内容。以下选项能让转储保留更多数据:

  • --default-character-set=utf8mb4 会保留 emoji 和其他 4 字节字符,utf8 转储会在转换器看到之前就丢失它们。
  • --hex-blob 将二进制列写为十六进制,在系统之间复制时不会损坏。
  • --routines --triggers --events 将这些对象加入转储,以便报告列出它们。

哪些内容不会转换

视图、触发器、存储过程、函数等用 MySQL 自己的语言编写的对象,会按名称列在报告中,绝不会被悄悄丢弃,你可以先在要导入的 MySQL 版本上逐一检查再重建。

关于在 MySQL 版本之间迁移的问题

这里没有你要的答案?请通过联系页面给我们留言,会有专人回复。 联系页面

我的转储会被上传吗?

不会。转换器在你的浏览器中运行,分块从磁盘读取转储,因此转储不会离开你的电脑。桌面应用和命令行也在你的电脑上转换。

转储可以多大?

转换器从不把整个转储放进内存:它按范围读取文件两次,边读边写出脚本。几 GB 的转储可以在浏览器、桌面应用和命令行中转换。

它能读取 MariaDB 转储吗?

能。来自 mariadb-dump 以及 MariaDB 10.3 到 12 的转储都以相同方式转换,包括 MariaDB 的 INET6、INET4 和 UUID 列。

0000-00-00 日期会怎样处理?

MySQL 会保留它们:脚本在导入期间设置接受零日期和无效日期的 SQL 模式,因此它们原样到达。

AUTO_INCREMENT 值会保留吗?

是的。AUTO_INCREMENT 保持不变,表的计数器从转储停下的地方继续。

TINYINT(1) 会变为 boolean 吗?

它与源中一样保持 TINYINT(1),因此每个值都保留其数字。

存储过程和触发器怎么处理?

它们按名称列在报告中且不做转换,你可以先在要导入的 MySQL 版本上逐一检查再重建。ON UPDATE CURRENT_TIMESTAMP 保持不变。

脚本可以导入哪些 MySQL 版本?

MySQL 5.7 及以上。每个测试转储都能在 5.7 和 9 上导入,如有问题会在第一个错误处停止。