# 数据库比对工具 **Repository Path**: swastika-wan/db-diff ## Basic Information - **Project Name**: 数据库比对工具 - **Description**: 这个程序主要用于在数据库迁移或同步过程中,验证两个达梦数据库中表的一致性,包括结构和内容。它帮助用户识别出不同点,从而确保数据同步的完整性和一致性 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-08-08 - **Last Updated**: 2026-07-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 数据库表结构与数据比对工具(db-diff) 本工具用于比对两个数据库(达梦 DM / Oracle / MySQL)之间的表结构差异和数据差异,支持配置多个表进行批量比对。可用于迁移验证、差异排查等场景。 ## 特点 - 支持配置文件灵活设置源数据库和目标数据库的连接信息 - 源端、目标端可独立选择 **达梦(DM)** / **Oracle** / **MySQL**,支持任意同型组合(DM↔DM / Oracle↔Oracle / MySQL↔MySQL) - 输出详细的表结构差异(字段、主键、外键) - 输出表中数据的差异(新增、缺失或变更的行) - 自适应分批 + 断点续传,支持百万级大表 ## 目录结构 - `run.go`:程序主入口及核心逻辑 - `dialect.go`:数据库方言抽象(MySQL / Oracle / DM 三种实现) - `db.conf`:配置文件 - `diff-linux-amd64`:Linux x86_64 预编译二进制(已随仓库提交,Linux 端无需装 Go 即可直接运行) - `Makefile`:构建脚本(改代码后用 `make linux` 重新生成上面的二进制) - 依赖库: - `gitee.com/chunanyong/dm`:达梦数据库驱动 - `github.com/sijms/go-ora`:纯 Go Oracle 驱动(无需 Oracle Instant Client) - `github.com/go-sql-driver/mysql`:MySQL 驱动 ## 前提条件 - 本机编译需要 Go 环境(1.24 及以上);**运行端可以完全没有 Go**(见下方「在无 Go 环境的 Linux 上部署」) - 可访问源端和目标端数据库 ## 使用步骤 ### 1. 配置 `db.conf` 配置文件按数据库类型分块,**不用的块整段注释掉,保留要用的那一块**。源端 / 目标端可独立配置。 每端独立配置数据库类型 `SRC_TYPE` / `DST_TYPE`: | TYPE | 必填项 | 说明 | |----------|---------------------|-------------------------------------| | `DM` | `INSTANCE` | 达梦实例名 | | `ORACLE` | `SERVICE` | Oracle Service Name | | `MYSQL` | `DB` | MySQL database 名 | 示例(MySQL ↔ MySQL): ``` SRC_TYPE=MYSQL SRC_IP=127.0.0.1 SRC_PORT=3306 SRC_DB=mydb SRC_USERNAME=root SRC_PASSWORD=*** DST_TYPE=MYSQL DST_IP=127.0.0.1 DST_PORT=3306 DST_DB=mydb DST_USERNAME=root DST_PASSWORD=*** TABLES=* ``` 示例(DM ↔ DM): ``` SRC_TYPE=DM SRC_IP=192.168.9.37 SRC_PORT=5236 SRC_INSTANCE=DMSERVER SRC_USERNAME=captbox SRC_PASSWORD=Admin123 DST_TYPE=DM DST_IP=192.168.9.38 DST_PORT=5236 DST_INSTANCE=DMSERVER DST_USERNAME=captbox DST_PASSWORD=Admin123 TABLES=table1,table2,table3 ``` > 完整示例(含三种数据库的注释块)见仓库 `db.conf`。 ### TABLES 取值说明 | 写法 | 含义 | |------|------| | `TABLES=` 留空 | 比对源端当前用户下**所有表**(`USER_TABLES`) | | `TABLES=*` | 同上,显式写法(推荐,更直观) | | `TABLES=A*,B?_x` | glob 通配符过滤 | | `TABLES=T1,T2,T3` | 精确列表(自动去重) | > 说明:`*` 不会与真实表名冲突,因为 Oracle/DM 不加引号的标识符不允许包含 `*` 字符。多种写法可任意混用,例如 `TABLES=DICT_*,LOG_*,USER`。 > 注意: > - 当前数据比对使用 `SELECT * FROM ORDER BY 1`,假设**第一列是唯一排序键且两端一致**。如第一列不是唯一键请提前手工按主键排序后导入,或后续升级到基于主键的哈希比对。 > - 比较的表名需两端大小写一致(默认大写)。 > - 跨库型比对(DM↔Oracle)时类型字符串会做归一化(见 run.go `normalizeType`)。 ### 2. 构建和运行 **Linux(无需装 Go)**:仓库里已附带 `db-diff/diff-linux-amd64`,直接进目录运行即可: ``` cd db-diff ./diff-linux-amd64 -test # 先测两端连接 ./diff-linux-amd64 # 正式比对 ``` **有 Go 环境的开发机**:可自行编译(macOS / Windows / 任意架构): ``` go build -o diff # 本机编译 ./diff # Linux/macOS diff.exe # Windows ``` 或用 Makefile: ``` make build # 本机编译,产物 ./diff make test # 编译并以 -test 模式运行(仅测两端连接) make run # 编译并运行( ARGS=-test 透传参数) make linux # 交叉编译 Linux amd64,生成 diff-linux-amd64(改代码后重新生成并提交) ``` **测试连接**(推荐先跑这一步,验证两端可达和权限): ``` ./diff-linux-amd64 -test # Linux ./diff -test # Linux/macOS 本机编译版 diff.exe -test # Windows ``` 输出会逐项检查:连接 → Ping → 查表权限。全部通过才进入正式比对。 > 修改了代码后,在开发机执行 `make linux` 重新生成 `diff-linux-amd64`,再 `git` 提交该文件,Linux 端 `git pull` 即可获得新版本。 ### 3. 查看输出 程序逐个输出每个表的结构差异与数据差异。 ## 主要功能介绍 ### 配置加载 - 读取 `db.conf` 文件 - 支持源 / 目标独立选择数据库类型 - 支持任意多个表 ### 数据库连接 - `DM`:`dm://user:pwd@ip:port/instance` - `Oracle`:`oracle://user:pwd@ip:port/service` - `MySQL`:`user:pwd@tcp(ip:port)/db?parseTime=true` - 自动 `Ping()` 校验 ### 方言抽象(dialect) `dialect.go` 把三种数据库的差异封装在 `Dialect` 接口背后: - 系统目录查询(`USER_TABLES` vs `INFORMATION_SCHEMA.TABLES`) - 占位符(`:1` vs `?`) - 分页(`ROWNUM` vs `LIMIT`) 主流程对具体方言无感知,新增 PostgreSQL / SQLite 等只需实现 `Dialect` 接口即可。 ### 结构比较 - 比较字段:是否存在、类型是否一致(已做语义归一化) - 比较主键 / 外键 ### 数据比较 - 按第一列排序后逐行扫描 - 逐列字符串化对比(NULL → ``,`[]byte` → 字符串) ### 示例 ![diff 示例](image.png)