**能保留,但只能靠迁移数据库表实现,不能指望 CMS 自带的导出/导入功能。** 几乎所有主流 CMS 的「修订版本」都是一条独立的数据行,且通过父级 ID 挂在原文章下;导出成 XML/JSON 时,这些行 100% 会被丢弃。想让修订跟着文章一起走,就必须把修订行本身当作数据迁移,并在目标站重建「修订 → 文章」的父子关系。
修订版本到底存在哪张表里?
结论:先确认原站修订的存储结构,这决定后面能不能直接搬运。WordPress 最典型,修订就是 wp_posts 表里 post_type = 'revision' 的记录,post_parent 指向原文章 ID,post_content 存的是那一刻的全文快照,post_name 形如 1234-revision-v1。Drupal 用 node_revision 及 {node类型}_revision 独立表;Typecho 在 contents 表用 type 字段区分正文与修订;部分国产 CMS(如早期 Discuz)根本没有原生修订机制,只能靠第三方插件生成的备份表。
动手前先跑一条统计,看清体量:
SELECT post_parent, COUNT(*) AS rev_count,
MAX(post_modified) AS last_rev
FROM wp_posts WHERE post_type='revision'
GROUP BY post_parent ORDER BY rev_count DESC LIMIT 20;
如果单篇修订超过 50 条、总量上百万行,就要考虑先裁剪(只保留最近 N 条或每天最后一条),否则整表导入会拖到几小时。
同构迁移和异构迁移,做法差在哪?
结论:同构(WordPress→WordPress)直接整表搬运、保留原 ID 最省事;异构(换 CMS)必须先生成 ID 映射表,再按映射重写 post_parent。
同构路径的操作顺序是:
wp db export full.sql 导出全库;
- 目标站
wp db import full.sql;
- 域名替换用 WP-CLI 的序列化安全命令:
wp search-replace 'old.com' 'new.com' --all-tables --precise --recurse-objects,普通 SQL REPLACE 会破坏序列化字段长度;
- 迁移前后各执行一次
wp post list --post_type=revision --format=count 对比条数。
异构路径必须先解决 ID 错位:新站自增 ID 与旧站完全不同,直接 INSERT 会让 post_parent 指向不存在的文章或别人的文章。做法是导出旧站 (ID, post_name, post_date) 建临时映射表,用标题+发布时间或旧站的唯一 slug 匹配出新 ID,再批量 UPDATE 修订行的父级字段。
目标站不支持修订怎么办?
结论:降级保存为「存档文章 + 差异记录」,别硬塞。
可行做法有三种:把每篇的修订导出成独立静态文件,按 文章ID/revision-时间戳.html 归档,正文里放下载链接;或者在目标站建一个隐藏版块/独立表,把历史版本作为不可评论的存档内容写入;或者只保留正文的 diff 增量(用 diff -u 或 Python 的 difflib 生成 unified diff),单条体积能压到原文的 5%~15%。注意:一旦目标 CMS 没有修订机制,后续编辑不会再产生新版本,这条链路等于终止,迁移前要和团队确认清楚。
迁移过程中有哪些坑必须避开?
结论:导入期间一定要关闭自动保存和修订清理,否则会出现「导入 20 万条、落地 19 万条」的情况。
具体清单:在 wp-config.php 里设 define('WP_POST_REVISIONS', 100);(默认值 true 表示不限条数,设成数字才是上限,设 false 直接关闭),并设 define('AUTOSAVE_INTERVAL', 300); 拉长自动保存间隔;导入前 define('DISABLE_WP_CRON', true); 并停掉定时任务,避免优化插件在后台跑清理;同时确认目标库 max_allowed_packet 不低于 64M,否则大文章快照会截断。修订行的 post_date 在 WordPress 里通常是 0000-00-00 00:00:00,真正有意义的是 post_modified,做时间排序时别用错字段。最后抽样 10 篇文章,用 wp post get <revision_id> --field=post_content 与原站逐字对比,确认换行和短代码没有被转义破坏。
迁移完成后的验证怎么做
结论:三个数字对齐才算迁移成功——文章数、修订总数、每篇文章的最新修订时间。
把这三项做成对照表,逐项比对源站与目标站;再挑 5 篇改动最频繁的文章,人工对比首个版本与最新版本的差异。GJ 站长论坛的问答区里这类迁移翻车案例不少,共同点都是只核对了文章数、没核对修订数。总耗时参考:1 万篇文章、平均 8 条修订的规模,同构迁移约 20 分钟,异构迁移含 ID 映射约 1.5~2 小时。
一句话收束:修订版本不是文章的附属属性,而是一张独立的数据表,迁移方案要按「数据表迁移」来设计,先盘点结构、再决定同构直搬还是异构映射、最后用三项指标验收,缺一步都会丢历史。