最快方式是直接查information_schema.COLUMNS和TABLES,因SHOW CREATE TABLE受会话变量、版本、AUTO_INCREMENT值、注释格式等干扰易产生假差异;需用GROUP_CONCAT按ORDINAL_POSITION生成结构指纹比对,并单独校验ENGINE、CHARSET等表级属性。

直接查 INFORMATION_SCHEMA.COLUMNS 和 sys.columns,别拼 DDL
拼 SHOW CREATE TABLE 或动态生成 DDL 再字符串比对,是最快踩坑的路。输出受会话变量、版本、缩进、反引号、AUTO_INCREMENT 值等干扰,两次执行同一张表都可能 diff 出“差异”。真实结构一致但文本不等,纯属噪音。
正确做法是绕过 DDL,直取元数据字段:
-
COLUMN_NAME、DATA_TYPE(MySQL)或system_type_id+max_length+precision+scale(SQL Server)——类型必须组合判断,单靠DATA_TYPE名称会漏掉varchar(50)vsvarchar(100) -
IS_NULLABLE:YES/NO不一致会导致 INSERT 失败 -
COLUMN_DEFAULT:MySQL 里可能是(CURRENT_TIMESTAMP),SQL Server 是((getdate())),括号和函数名大小写都不同,不能直接等值比 -
IS_IDENTITY(SQL Server)或EXTRA = 'auto_increment'(MySQL):主键/自增错位会引发复制中断或主键冲突 -
COLLATION_NAME(SQL Server)或COLLATION(MySQL):跨地域部署时,Chinese_PRC_CI_AS和SQL_Latin1_General_CP1_CI_AS视为不兼容
用 EXCEPT 做集合差,不是 NOT IN
NOT IN 对 NULL 敏感,且无法识别“字段顺序不同但定义相同”的情况——比如 id INT, name VARCHAR(20) 和 name VARCHAR(20), id INT,NOT IN (column_name) 会全报缺失,实际只是顺序错位。
更稳的方式是把两表列元数据分别查入临时表,再用 EXCEPT 做全字段差集:
- SQL Server 示例:
SELECT column_id, name, system_type_id, max_length, precision, scale, is_nullable, is_identity, collation_name FROM sys.columns WHERE object_id = OBJECT_ID('db1.schema.t1') EXCEPT SELECT ... FROM sys.columns WHERE object_id = OBJECT_ID('db2.schema.t2') - MySQL 示例:用
GROUP_CONCAT拼结构指纹,按ORDINAL_POSITION排序后哈希比对,5 秒内可判定是否完全一致 - 注意:必须显式包含
ORDINAL_POSITION或column_id,顺序不同 = 结构不同
跨库比对要拆开查,别用动态 SQL 执行 ALTER
存储过程中用 EXEC(@sql) 或 PREPARE/EXECUTE 动态执行 DDL,在 MySQL 8.0 下大概率触发 ER_UNSUPPORTED_ALTER_IN_PREPARE;SQL Server 则不允许在单个批处理里先 ALTER TABLE ADD COLUMN,再立刻 INSERT 引用该字段。
安全做法是分阶段处理:
- 先查出差异(只读操作),输出成待执行语句清单,人工 review 后再单独执行
- 若需自动同步,MySQL 必须分三步:
ADD COLUMN DEFAULT 'x'→ 分批UPDATE填历史数据 →MODIFY COLUMN改约束;SQL Server 可用IF NOT EXISTS (SELECT ...)包裹每个ALTER,但禁止连写 - 永远不要让存储过程自己决定“要不要加索引”或“要不要改默认值”——这些决策依赖业务语义,代码无法替代人判
表级属性不能忽略:ENGINE、CHARSET、ROW_FORMAT
information_schema.COLUMNS 不管表级配置,但这些差异线上影响极大:
- 引擎不一致(如一个
InnoDB,一个MyISAM):事务失效、外键静默忽略、锁机制错乱 - 字符集不一致(如
utf8mb4vslatin1):插入中文直接报错或乱码 -
ROW_FORMAT不同:影响压缩率、大字段存储方式,某些版本下ALTER会强制重建表
必须单独查 information_schema.TABLES 补齐比对项,且不能只看 TABLE_COLLATION,要落到具体字段的 COLUMN_COLLATION —— 表级一致,字段级不一致照样出问题。

















