老网站搬家到新系统,数据库对不上号,咋整?

1,986字
8–13 分钟
in

老网站想换个更顺手的后台,结果数据导过去全乱套?这事儿在开发圈里可太常见了。就拿数据库结构来说,旧系统(比如WordPress)的存储方式和那种自己从头撸的CMS(内容管理系统)简直是两个次元。CMS说白了就是管理网站内容的工具,有的自带一套奇怪的数据库关系,有的则追求规规矩矩的表结构。当试图把一堆乱糟糟的数据塞进新家,就会发现字段对不上、关联全断裂,分分钟让人头秃。

目录

迁移痛点

WordPress的数据库表设计,外人看着真有点摸不着北。帖子、元数据、分类关系搅在一起,而新系统如果用PostgreSQL这类关系型数据库,追求的是严谨的字段类型和明确的外键约束。两边一碰撞,光是把wp_postmeta里那些键值对拆解成规整的列,就得掉不少头发。一个实际案例:某个技术博客站点有上万篇文章,每篇文章带十几个自定义字段,迁移时发现新系统的文章表里根本没地方放这些额外信息。解决方案不是硬塞,而是重新建模——把自定义字段单独拉一张表,通过外键和主文章关联。

旧系统字段新系统字段处理方式
post_titletitle直接映射
post_contentbody清洗标签
meta_keycustom_key分表存储

方案一脚本

拿Python写个迁移脚本,分三步走。第一步连接旧库,查出所有文章数据。第二步根据映射规则转换格式,比如把post_date的字符串转成时间戳。第三步批量插入新库。中间加个断点续传功能,防止跑到一半网络抖崩了。

# 伪代码示意连接旧库
old_cursor.execute("SELECT ID, post_title, post_content FROM wp_posts WHERE post_type='post'")
rows = old_cursor.fetchall()
for row in rows:
    new_doc = {
        "doc_id": row[0],
        "title": row[1].strip(),
        "content": clean_html(row[2])
    }
    # 插入新系统
    new_cursor.execute("INSERT INTO articles (id, title, body) VALUES (%s, %s, %s)", 
                       (new_doc["doc_id"], new_doc["title"], new_doc["content"]))

跑脚本之前一定先在本地搭个镜像环境测一把。见过好多次生产库直接跑脚本,结果字段长度不匹配导致大批数据被截断,回头还得从备份恢复,那叫一个酸爽。另外记得把旧库的字符集确认好,utf8mb4和utf8之间转码一不小心就出乱码。

方案二抽层

如果不想跟数据库死磕,可以加个中间层。新系统不直接吞旧数据,而是先导成一套标准格式,比如JSON Lines文件。每行一个文章对象,字段名统一为titlebodycreated_at等。然后写一个通用的导入器,读取这个文件塞进新库。这样做的好处是旧库的奇葩结构只在导出阶段恶心一次,后续换其他新系统都不用重写导入逻辑。

# 导出成标准格式
wp db query "SELECT ID, post_title, post_content FROM wp_posts" --json > articles.jsonl
# 再调用导入脚本
python import_to_new_cms.py --file articles.jsonl

注意这种方案下,文件可能会非常大。一个中型站点导出个几GB的JSON文件很常见,这时候别用记事本打开,否则电脑直接卡死。用head命令先瞅几行结构对不对。还有文件里的换行符,Windows和Linux下不一致,导入脚本最好能自动适配。

静态化加速

迁移完成之后,还有个骚操作能把性能拉满——静态导出。新系统背后的数据库再快,也不如直接把所有公开内容扔到CDN(内容分发网络,就是全球各地布一堆缓存节点)上。每次有读者访问,CDN节点秒回静态HTML,数据库连查询都不用做。只有编辑后台发文章或者改内容的时候,才触发重新生成静态文件。

实现这个流程,需要在CMS里加个钩子。文章保存成功后,调用静态生成器,把最新内容渲染成/posts/123.html,然后同步到对象存储。CDN再设置个缓存规则,比如5分钟内自动回源检查更新。实际操作时注意不要把所有页面一次性全量生成,可以按修改时间增量生成。曾经有个团队全量生成了一百万篇文章,直接把服务器CPU跑满,持续了四十分钟。改成增量之后,每次编辑只生成受影响的那一页和列表页,丝滑多了。

表里对比

迁移方式耗时程度数据风险回滚难度
直接写脚本中等较高困难
中间层导入稍慢简单
静态化导出前期重中等

不管选哪条路,迁移前一定把旧库完整备份,并且在新环境跑通整个流程至少两次。第一次记录下所有报错,第二次验证修复。等正式切换的时候,选个凌晨访问量最少的时间段,切完之后别急着删旧库,留它一礼拜当个安心丸。