MySQL的datetime映射PostgreSQL的timestamp without time zone,timestamp映射timestamp with time zone;若源为UTC,目标用timestamptz并加AT TIME ZONE 'UTC';应用层需适配时区逻辑。

MySQL 到 PostgreSQL 迁移时 datetime 和 timestamp 怎么映射?
MySQL 的 datetime 默认不带时区,timestamp 却隐式依赖系统时区且自动转换;PostgreSQL 的 timestamp without time zone 表面像前者,但语义更接近 MySQL 的 datetime,而 timestamp with time zone 才真正做时区归一化。直接按字段名一对一映射会出问题。
- 如果源数据全是 UTC 时间,目标用
timestamp with time zone最稳妥,导入时加AT TIME ZONE 'UTC'强制解释 - 若业务逻辑依赖 MySQL 的“本地时间存储+本地时区读取”行为(比如日志时间按服务器所在时区写入),迁到 PostgreSQL 后必须统一改写应用层,不能靠数据库自动补救
-
timestamp字段在 MySQL 5.6+ 支持微秒,PostgreSQL 默认也支持,但迁移工具如pgloader需显式开启with truncate和with data才保留精度,否则默认截断到秒
Oracle NUMBER(10,2) 导入 MySQL 后精度丢失怎么办?
Oracle 的 NUMBER 是精确十进制类型,MySQL 的 DECIMAL 虽然也是定点数,但声明方式不同:NUMBER(10,2) 对应的是 DECIMAL(10,2),不是 FLOAT 或 DOUBLE。很多迁移脚本误用浮点类型,导致小数四舍五入或科学计数法显示。
- 检查导出 SQL 是否含
CAST(... AS FLOAT)类型转换,这是精度丢失主因 - 使用
mysqldump --compatible=oracle并不真正兼容 Oracle 类型,它只改语法糖,NUMBER仍被转成DOUBLE,得手动替换正则:NUMBER((\d+),(\d+))→DECIMAL($1,$2) - MySQL 8.0+ 支持
DECIMAL最大 65 位精度,但客户端(如 Python 的mysql-connector-python)默认把DECIMAL当 float 返回,需显式设decimal_values=True参数
SQL Server uniqueidentifier 字段迁到 MySQL 后查不到记录?
SQL Server 的 uniqueidentifier 是 16 字节二进制 UUID,常以 'A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11' 格式存储;MySQL 原生不识别这种格式,若直接当字符串导入到 VARCHAR(36),虽然能存,但排序、索引效率差,且和 MySQL 的 UUID() 函数不互通。
- 更优做法是转成
BINARY(16):用UNHEX(REPLACE(uuid_str, '-', ''))入库,查询时用HEX(uuid_col)反查,或用UUID_TO_BIN()(MySQL 8.0.1+) - 注意大小端:SQL Server 默认小端序生成 UUID,MySQL 的
UUID_TO_BIN()默认大端序,要加第二个参数1:UUID_TO_BIN('A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11', 1) - 如果已有数据在
VARCHAR(36)里,别用LIKE模糊查,REPLACE(col, '-', '') = UNHEX(...)无法走索引,得重建字段并加函数索引
迁移后 TEXT 字段内容莫名被截断或乱码?
本质是字符集与排序规则没对齐。MySQL 的 utf8mb4 是真 UTF-8,而旧版迁移工具(如某些版本的 mysqldump 或 Navicat)默认用 utf8(即 utf8mb3),遇到 emoji 或生僻汉字就丢字节;PostgreSQL 默认 UTF8 没问题,但连接层可能强制 client_encoding 为 SQL_ASCII。
- 导出前确认 MySQL 服务端字符集:
SHOW VARIABLES LIKE 'character_set%';,重点看character_set_server和collation_server - 导入命令必须带
--default-character-set=utf8mb4,且连接字符串加?charset=utf8mb4 - PostgreSQL 侧检查
SHOW client_encoding;,不是UTF8就执行SET client_encoding = 'UTF8'; -
TEXT类型本身无长度限制,但中间件(如 Django ORM)可能默认用TextField对应,若原始字段是MEDIUMTEXT且含超长内容,得确认 ORM 层没做隐式截断
跨异构迁移最耗时间的从来不是数据搬运,而是字段语义对齐——同一串字符,在不同数据库里代表的时间基准、精度含义、二进制布局都可能差一个隐式转换。别信“自动映射”,每个字段都得单独验。


















