将 SQLite 数据库迁移到 MySQL 是一个常见的需求
参考资料
将 SQLite 数据库迁移到 MySQL 是一个常见的需求
好的,将 SQLite 数据库迁移到 MySQL 是一个常见的需求。虽然两者都使用 SQL,但在数据类型、语法和一些特性上存在差异,因此不能简单地直接复制粘贴。
下面我将为您提供一个详细、步骤清晰的迁移指南,包括手动方法和使用工具的方法。
迁移前的重要注意事项
数据类型差异:这是最大的坑。例如:
SQLite 的
INTEGER
对应 MySQL 的INT
或BIGINT
(取决于自增等情况)。SQLite 的
TEXT
对应 MySQL 的VARCHAR
,TEXT
或LONGTEXT
(需要根据长度选择)。SQLite 的
REAL
对应 MySQL 的FLOAT
或DOUBLE
。SQLite 的
BLOB
对应 MySQL 的BLOB
或LONGBLOB
。布尔值:SQLite 用
INTEGER
(0/1) 表示,MySQL 有原生的BOOLEAN
或BOOL
(实际上是TINYINT(1)
的别名)。日期时间:SQLite 用
TEXT
,INTEGER
, 或REAL
存储,而 MySQL 有专门的DATE
,TIME
,DATETIME
,TIMESTAMP
。SQL 语法差异:
自增主键:SQLite 是
AUTOINCREMENT
,MySQL 是AUTO_INCREMENT
。引号:MySQL 反引号 ``` 用于引用标识符(表名、列名),而 SQLite 通常用双引号
"
或方括号[]
。INSERT 语句:SQLite 可能更宽松,MySQL 对严格模式有要求。
DEFAULT 值:对于
TIMESTAMP
类型,MySQL 常用CURRENT_TIMESTAMP
作为默认值。外键:需要显式在 MySQL 中启用
FOREIGN_KEY_CHECKS
。编码:确保你的 MySQL 数据库使用正确的字符集(如
utf8mb4
)以支持中文和所有 Unicode 字符(包括表情符号)。
方法一:使用迁移工具(推荐)
这是最省时省力且不容易出错的方法。
1. 使用 Navicat(图形化界面,最方便)
Navicat 同时支持 SQLite 和 MySQL,其“数据传输”功能可以自动处理大部分兼容性问题。
步骤:
同时连接你的 SQLite 源数据库和 MySQL 目标数据库。
在 Navicat 主界面,点击 工具 -> 数据传输。
源:选择你的 SQLite 连接和数据库。
目标:选择你的 MySQL 连接和数据库(可以是一个空数据库)。
点击 下一步,选择你要传输的表。你可以点击“选项”进行一些高级配置。
点击 开始,Navicat 会自动创建表结构并导入数据。它会尝试智能地映射数据类型(如将
TEXT
映射为LONGTEXT
)。
2. 使用 MySQL Workbench 的 Migration Wizard(免费)
MySQL Workbench 内置了一个强大的迁移工具包。
步骤:
打开 MySQL Workbench。
点击菜单栏的 Database -> Migration Wizard。
Source Selection:选择 “SQLite”,并浏览到你的
.sqlite
或.db
文件。Target Selection:选择你的 MySQL 连接。
按照向导一步步操作:反向工程源和目标、选择要迁移的架构对象(表)、转换对象类型、迁移数据。
向导会显示迁移过程中遇到的任何问题,并允许你手动调整生成的 SQL 脚本。
3. 使用命令行工具 sqlite3
和 mysql
这是一种更手动但可控的方法。
步骤 1:从 SQLite 导出数据为 SQL 文件
# 连接到你的 SQLite 数据库 sqlite3 your_database.db # 在 sqlite> 提示符下,输出所有数据和结构到 .sql 文件 sqlite> .output backup.sql sqlite> .dump sqlite> .exit
步骤 2:手动修改 backup.sql
文件
用文本编辑器(如 VSCode, Notepad++)打开 backup.sql
,进行全局查找和替换:
AUTOINCREMENT
->AUTO_INCREMENT
将表名和列名的双引号
"
替换为反引号`
检查并修改数据类型(如
TEXT
->LONGTEXT
)。移除 SQLite 特有的语句(如
BEGIN TRANSACTION;
,COMMIT;
)。
步骤 3:将修改后的 SQL 文件导入 MySQL
mysql -u your_mysql_user -p your_mysql_database < backup_modified.sql
方法二:编程方式(Python 示例)
如果你需要经常迁移或进行自动化,可以用脚本实现。
import sqlite3 import pymysql # 连接到 SQLite 源数据库 sqlite_conn = sqlite3.connect('source.db') sqlite_cursor = sqlite_conn.cursor() # 连接到 MySQL 目标数据库 mysql_conn = pymysql.connect( host='localhost', user='your_username', password='your_password', database='target_db', charset='utf8mb4' ) mysql_cursor = mysql_conn.cursor() # 1. 获取 SQLite 中的所有表名 sqlite_cursor.execute("SELECT name FROM sqlite_master WHERE type='table';") tables = sqlite_cursor.fetchall() for table in tables: table_name = table[0] print(f"Processing table: {table_name}") # 2. 获取表结构 sqlite_cursor.execute(f"PRAGMA table_info({table_name})") columns = sqlite_cursor.fetchall() # 根据 columns 信息构建 MySQL 的 CREATE TABLE 语句 (需要手动映射数据类型) # ... (这里需要复杂的逻辑来处理类型映射) # 3. 获取数据 sqlite_cursor.execute(f"SELECT * FROM {table_name}") rows = sqlite_cursor.fetchall() # 4. 插入数据到 MySQL for row in rows: # 构建 INSERT INTO 语句 placeholders = ', '.join(['%s'] * len(row)) columns_str = ', '.join([col[1] for col in columns]) # 获取列名 query = f"INSERT INTO `{table_name}` ({columns_str}) VALUES ({placeholders})" mysql_cursor.execute(query, row) # 提交事务并关闭连接 mysql_conn.commit() sqlite_conn.close() mysql_conn.close()
注意:上面的示例是一个框架,最关键且复杂的部分是第 2 步:自动将 SQLite 的 PRAGMA table_info
信息转换为 MySQL 的 CREATE TABLE
语句。你需要编写一个强大的映射函数来处理数据类型、主键、自增等属性。
总结与推荐
方法 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
Navicat | 极其方便,图形化操作,自动处理大部分问题 | 是商业软件,需要付费 | 强烈推荐,尤其是偶尔迁移或公司使用 |
MySQL Workbench | 免费,功能强大,官方工具 | 配置稍复杂,速度可能较慢 | 免费首选,适合有一定技术能力的用户 |
命令行手动 | 免费,完全可控 | 非常繁琐,容易出错,需大量手动修改 | 数据量很小,或需要极精细控制的情况 |
编程脚本 | 可自动化,可定制 | 开发工作量大,需要处理所有边缘情况 | 需要频繁、定期迁移的场景 |
对于大多数用户,我首推使用 Navicat 或 MySQL Workbench 的迁移工具。它们能为你节省大量时间和精力,避免手动操作带来的错误。