# mysqlDiffQt **Repository Path**: bill_hu1971/mysql-diff-qt ## Basic Information - **Project Name**: mysqlDiffQt - **Description**: 生成两个mysql数据库结构对齐脚本 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-19 - **Last Updated**: 2026-08-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # mysqlDiffQt 基于 **Qt5 + C++** 实现的 MySQL 库结构对比工具,是 Go 版 `mysqlDiff`(`sqlDiff_mysql5.7.31` / `sqlDiff_mysql8.0.32`)的忠实移植。 同时提供 **GUI(图形界面)** 与 **CLI(命令行)** 两种使用方式,一次运行即可生成**互为逆操作**的两个方向的差异 SQL: - `[1/2] SOURCE -> DEST`:把这段 DDL 应用到 DEST,使其与 SOURCE 一致 - `[2/2] DEST -> SOURCE`:把这段 DDL 应用到 SOURCE,使其与 DEST 一致 --- ## 功能特性 - 对比两个 MySQL 库(target / source)的结构差异,生成更新用的 DDL 脚本。 - 支持四类差异: - **表级**:DROP TABLE(目标有、源没有)、CREATE TABLE(源有、目标没有,含完整建表语句)。 - **列级**:ADD COLUMN / DROP COLUMN / MODIFY COLUMN(含 COMMENT、DEFAULT、NOT NULL、PRIMARY KEY、AUTO_INCREMENT)。 - **索引级**:CREATE INDEX / DROP INDEX(含 UNIQUE)。 - **双语法模式**: - `mysql8`(默认,对应 `sqlDiff_mysql8.0.32`):支持 `INVISIBLE` 不可见索引、函数索引表达式 `((expr))`。 - `mysql5`(对应 `sqlDiff_mysql5.7.31`):索引 DDL 不生成 `VISIBLE`/`INVISIBLE`;5.7 无法表达的函数索引会跳过其 CREATE(DROP 侧仍保留)。 - 中文 COMMENT 通过 `SET NAMES utf8mb4` 往返,输出文件为 UTF-8,无乱码。 --- ## 编译环境 - **Qt**:5.15.2(`msvc2019_64`)。 - **编译器**:MSVC 2022 x64(通过 `vcvarsall.bat x64` 加载,需要 VS2022 Build Tools / Community)。 - **构建工具**:Qt 的 `qmake` + `nmake`。 - **MySQL 客户端库**:`libmysql.dll` 需与要连接的 MySQL 服务端**大版本一致**(例如连 9.6 就用 9.6 自带的 `libmysql.dll`),否则会出现认证插件加载失败。 ### 一键构建 项目根目录的 `build_qt.bat` 已内联好 `vcvarsall.bat x64` 与 Qt 的 PATH,直接双击或在命令行运行即可: ```bat build_qt.bat ``` 输出:`mysqlDiffQt.exe`(release)。 > 注意:`build_qt.bat` 必须是 **ASCII + CRLF** 编码(不要含中文注释、不要 UTF-8 的 BOM),否则在 GBK 代码页下会被 `cmd` 误解析。 ### 关于 QMYSQL 驱动(重要) Qt 自带的 `msvc2019_64` 发行包**不含** `qsqlmysql.dll`。务必用**本机 Qt 源码**重新编译插件,保证 ABI 与当前 Qt 版本一致——直接拷贝别的程序(如 `sqlbrowser`)自带的 `qsqlmysql.dll` 会因 Qt 版本不匹配导致 `addDatabase("QMYSQL")` 时进程崩溃(退出码 127)。 编译步骤(路径按本机实际调整): ```bat cd /d "D:\Qt5.15\5.15.2\Src\qtbase\src\plugins\sqldrivers\mysql" call "d:\vs2022\Community\VC\Auxiliary\Build\vcvarsall.bat" x64 set PATH=D:\Qt5.15\5.15.2\msvc2019_64\bin;%PATH% qmake mysql.pro nmake ``` - `mysql.pro` 已配置 MySQL 头文件/库路径(指向 9.6 的 `include`/`lib`)及输出目录。 - 产物:`qsqlmysql.dll`,复制到 `mysqlDiffQt/sqldrivers/` 即可。 --- ## 运行依赖部署 把 `mysqlDiffQt.exe` 连同以下文件放在同一目录(这些文件已随构建产物就位): | 文件 | 说明 | | --- | --- | | `Qt5Core.dll` `Qt5Gui.dll` `Qt5Widgets.dll` `Qt5Sql.dll` | Qt 运行时 | | `platforms/qwindows.dll` | Windows 平台插件 | | `sqldrivers/qsqlmysql.dll` | QMYSQL 驱动(本机 Qt 重编) | | `libmysql.dll` | MySQL 客户端库(与服务端大版本一致) | | `libssl-3-x64.dll` `libcrypto-3-x64.dll` | OpenSSL(MySQL 9.x 默认 `caching_sha2_password` 认证所需) | --- ## 用法 ### 方式一:GUI(双击运行) 直接双击 `mysqlDiffQt.exe`(若保留了 `CONFIG += console`,会带一个黑色控制台窗口)。 1. 分别填写 **目标库(DEST)** 与 **源库(SOURCE)** 的 `host / port / user / password / database`。 2. 选择 **生成语法版本**:`MySQL 8.0`(默认)或 `MySQL 5.7`。 3. 点 **生成差异 SQL**,结果分别展示在下方两个文本框: - 上:**UPGRADE — SOURCE -> DEST**(把 DEST 改造成与 SOURCE 一致,应用于目标库) - 下:**DOWNGRADE — DEST -> SOURCE**(应用于目标库可回退到变更前) 4. 分别点 **保存 UPGRADE** / **保存 DOWNGRADE**,各自存为 `_upgrade.sql` / `_downgrade.sql`(默认文件名以目标库名命名,可在对话框中修改)。 ### 方式二:CLI(命令行) ```bat mysqlDiffQt.exe ^ -targetDB "user:password@tcp(host:port)/dbDest" ^ -sourceDB "user:password@tcp(host:port)/dbSource" ^ [-syntax mysql5|mysql8] ^ [-o diff.sql] ``` 参数说明: | 参数 | 说明 | | --- | --- | | `-targetDB` | DSN,格式 `user:password@tcp(host:port)/database`(即 DEST) | | `-sourceDB` | DSN(即 SOURCE) | | `-syntax` | `mysql8`(默认)或 `mysql5`,对应 Go 版的 8.0.32 / 5.7.31 行为 | | `-o` | 输出基础名(UTF-8);生成 `_upgrade.sql` 与 `_downgrade.sql`;不指定则以 target 库名自动命名 | | `-h` / `--help` | 查看用法 | > DSN 中的 `@tcp(...)` 含括号,命令行里务必用**双引号**包裹整个 DSN(见 `runtest.bat`)。 示例: ```bat mysqlDiffQt.exe -targetDB "root:1234@tcp(localhost:3306)/db_target" -sourceDB "root:1234@tcp(localhost:3306)/db_source" -syntax mysql8 -o db_target ``` 运行后将生成两个文件: - `db_target_upgrade.sql`:UPGRADE,即 SOURCE -> DEST,把目标库改造成与源库一致。 - `db_target_downgrade.sql`:DOWNGRADE,即 DEST -> SOURCE,应用于目标库可回退到变更前。 > 若省略 `-o`,则以 `-targetDB` 的库名自动命名(如 `db_target_upgrade.sql`)。`-o` 可带 `.sql`/`.txt` 后缀,会自动剥离后拼接 `_upgrade`/`_downgrade`。 --- ## 示例输出(节选) > 输出含两段:`[UPGRADE] SOURCE -> DEST`(对应 `_upgrade.sql`)与 `[DOWNGRADE] DEST -> SOURCE`(对应 `_downgrade.sql`)。 ``` # ==================== [UPGRADE] SOURCE -> DEST ==================== # Apply these DDL to DEST 'db_target' to make it identical to SOURCE 'db_source' #Table changes from database db_target to database db_source: DROP TABLE tb_legacy; CREATE TABLE `tb_test` (...); #The sql statement corresponding to the change of table tb_account : ALTER TABLE tb_account ADD COLUMN delete_tm datetime COMMENT '账户删除时间', MODIFY COLUMN user_id int NOT NULL DEFAULT 34535 COMMENT '用户ID'; #Index update statement for table tb_account: CREATE INDEX idx_invisible_test ON tb_account(platform_id) INVISIBLE; CREATE INDEX idx_func_test ON tb_account((`user_id` + 1)); # ==================== [DOWNGRADE] DEST -> SOURCE ==================== # Apply these DDL to SOURCE 'db_source' to make it identical to DEST 'db_target' #Table changes from database db_source to database db_target: DROP TABLE tb_test; CREATE TABLE `tb_legacy` (...); #Index update statement for table tb_account: DROP INDEX idx_invisible_test ON tb_account; DROP INDEX idx_func_test ON tb_account; ``` --- ## 测试 `test_setup.sql` 用于在本机构建演示用的两套库(`db_target` / `db_source`),包含: - `tb_account`:两端有列/默认值差异(用于验证 ALTER TABLE)。 - `tb_legacy`:仅存在于目标库;`tb_test`:仅存在于源库(用于验证 DROP/CREATE TABLE)。 - 源库端的 `idx_invisible_test`(INVISIBLE)与 `idx_func_test`(函数索引):用于演示 mysql8 与 mysql5 的索引 DDL 差异。 载入(务必指定 `utf8mb4`,否则中文会被按 GBK 误存): ```bat mysql -uroot -p1234 --default-character-set=utf8mb4 < test_setup.sql ``` 命令行跑通后可用 `runtest.bat` 一键复测。 --- ## 与 Go 版的关系 | 本工具选项 | 对应 Go 版 | 区别点 | | --- | --- | --- | | `-syntax mysql8` | `sqlDiff_mysql8.0.32` | `SHOW INDEX` 读 15 列(含 `Visible`/`Expression`),支持 `INVISIBLE` 与函数索引 | | `-syntax mysql5` | `sqlDiff_mysql5.7.31` | `SHOW INDEX` 读 13 列,索引 DDL 不含 `VISIBLE`/`INVISIBLE` | > 说明:本地只有 MySQL 9.6,未安装 MySQL 5.7,故 `mysql5` 模式仅做逻辑验证(不崩溃、函数索引 CREATE 被合理跳过),未针对真实 5.7 服务端实测。 --- ## 已知限制 1. **CLI 中文到终端**:CONSOLE 子系统下,stdout 的中文在 GBK 代码页终端会显示为乱码(仅影响 `-h` 帮助与报错信息)。`-o` 输出文件和 GUI 输出的 UTF-8 均正常。 2. **控制台窗口**:`.pro` 中保留 `CONFIG += console` 以保证 CLI 的 stdout 可靠。若需纯 GUI(双击无黑窗),可去掉此行重新构建,但此时 CLI 输出会丢失、只能依赖 `-o` 写文件。 3. `libmysql.dll` 必须与目标 MySQL 服务端**大版本一致**;连 8.x/9.x 服务端时还需同目录放好 `libssl-3-x64.dll` / `libcrypto-3-x64.dll`。