参考资料

  1. 使用 MySQL 二进制方式连接
  2. MySQL 复制表详细说明以及案例
  3. MySQL 查询数据详细说明以及案例
  4. MySQL 命令详细说明以及案例
  5. MySQL 事务详细说明以及案例
  6. MySQL UNION 操作符详细说明以及案例
  7. MySQL 连接的使用详细说明以及案例
  8. MySQL 插入数据详细说明以及案例

将 SQLite 数据库迁移到 MySQL 是一个常见的需求

好的,将 SQLite 数据库迁移到 MySQL 是一个常见的需求。虽然两者都使用 SQL,但在数据类型、语法和一些特性上存在差异,因此不能简单地直接复制粘贴。

下面我将为您提供一个详细、步骤清晰的迁移指南,包括手动方法和使用工具的方法。

迁移前的重要注意事项

  1. 数据类型差异:这是最大的坑。例如:

    • SQLite 的 INTEGER 对应 MySQL 的 INTBIGINT(取决于自增等情况)。

    • SQLite 的 TEXT 对应 MySQL 的 VARCHARTEXTLONGTEXT(需要根据长度选择)。

    • SQLite 的 REAL 对应 MySQL 的 FLOATDOUBLE

    • SQLite 的 BLOB 对应 MySQL 的 BLOBLONGBLOB

    • 布尔值:SQLite 用 INTEGER (0/1) 表示,MySQL 有原生的 BOOLEANBOOL(实际上是 TINYINT(1) 的别名)。

    • 日期时间:SQLite 用 TEXT, INTEGER, 或 REAL 存储,而 MySQL 有专门的 DATE, TIME, DATETIME, TIMESTAMP

  2. SQL 语法差异

    • 自增主键:SQLite 是 AUTOINCREMENT,MySQL 是 AUTO_INCREMENT

    • 引号:MySQL 反引号 ``` 用于引用标识符(表名、列名),而 SQLite 通常用双引号 " 或方括号 []

    • INSERT 语句:SQLite 可能更宽松,MySQL 对严格模式有要求。

    • DEFAULT 值:对于 TIMESTAMP 类型,MySQL 常用 CURRENT_TIMESTAMP 作为默认值。

    • 外键:需要显式在 MySQL 中启用 FOREIGN_KEY_CHECKS

  3. 编码:确保你的 MySQL 数据库使用正确的字符集(如 utf8mb4)以支持中文和所有 Unicode 字符(包括表情符号)。


方法一:使用迁移工具(推荐)

这是最省时省力且不容易出错的方法。

1. 使用 Navicat(图形化界面,最方便)

Navicat 同时支持 SQLite 和 MySQL,其“数据传输”功能可以自动处理大部分兼容性问题。

步骤:

  1. 同时连接你的 SQLite 源数据库和 MySQL 目标数据库。

  2. 在 Navicat 主界面,点击 工具 -> 数据传输

  3. :选择你的 SQLite 连接和数据库。

  4. 目标:选择你的 MySQL 连接和数据库(可以是一个空数据库)。

  5. 点击 下一步,选择你要传输的表。你可以点击“选项”进行一些高级配置。

  6. 点击 开始,Navicat 会自动创建表结构并导入数据。它会尝试智能地映射数据类型(如将 TEXT 映射为 LONGTEXT)。

2. 使用 MySQL Workbench 的 Migration Wizard(免费)

MySQL Workbench 内置了一个强大的迁移工具包。

步骤:

  1. 打开 MySQL Workbench。

  2. 点击菜单栏的 Database -> Migration Wizard

  3. Source Selection:选择 “SQLite”,并浏览到你的 .sqlite.db 文件。

  4. Target Selection:选择你的 MySQL 连接。

  5. 按照向导一步步操作:反向工程源和目标、选择要迁移的架构对象(表)、转换对象类型、迁移数据。

  6. 向导会显示迁移过程中遇到的任何问题,并允许你手动调整生成的 SQL 脚本。

3. 使用命令行工具 sqlite3mysql

这是一种更手动但可控的方法。

步骤 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免费,功能强大,官方工具配置稍复杂,速度可能较慢免费首选,适合有一定技术能力的用户
命令行手动免费,完全可控非常繁琐,容易出错,需大量手动修改数据量很小,或需要极精细控制的情况
编程脚本可自动化,可定制开发工作量大,需要处理所有边缘情况需要频繁、定期迁移的场景

对于大多数用户,我首推使用 NavicatMySQL Workbench 的迁移工具。它们能为你节省大量时间和精力,避免手动操作带来的错误。