[{"data":1,"prerenderedAt":427},["ShallowReactive",2],{"insight-mysql-to-postgres":3,"insight-related-mysql-to-postgres":164},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":7,"slug":9,"date":10,"duration":11,"category":12,"author":13,"tags":14,"body":19,"_type":158,"_id":159,"_source":160,"_file":161,"_stem":162,"_extension":163},"\u002Finsights\u002F16-mysql-to-postgres","insights",false,"","数据库迁移：100+ 表的 MySQL 项目迁到 PostgreSQL","mysql-to-postgres","2025-10-15",14,"技术实践","浩途技术团队",[15,16,17,18],"数据库","迁移","MySQL","PostgreSQL",{"type":20,"children":21,"toc":151},"root",[22,30,44,48,54,84,87,93,122,131,134,139],{"type":23,"tag":24,"props":25,"children":27},"element","h2",{"id":26},"引子",[28],{"type":29,"value":26},"text",{"type":23,"tag":31,"props":32,"children":33},"p",{},[34,36,42],{"type":29,"value":35},"某客户的核心业务系统跑在 MySQL 上 5 年了，因合规要求需要迁到 PostgreSQL，且业务",{"type":23,"tag":37,"props":38,"children":39},"strong",{},[40],{"type":29,"value":41},"不能\n停超过 2 小时",{"type":29,"value":43},"。这次迁移是浩途近年最复杂的一次基础设施变更，复盘写下来。",{"type":23,"tag":45,"props":46,"children":47},"hr",{},[],{"type":23,"tag":24,"props":49,"children":51},{"id":50},"整体策略双写-灰度切流",[52],{"type":29,"value":53},"整体策略：双写 + 灰度切流",{"type":23,"tag":55,"props":56,"children":57},"ol",{},[58,64,69,74,79],{"type":23,"tag":59,"props":60,"children":61},"li",{},[62],{"type":29,"value":63},"先在生产环境双写（MySQL 主、PostgreSQL 影子）",{"type":23,"tag":59,"props":65,"children":66},{},[67],{"type":29,"value":68},"影子库跑业务回归 + 数据校对",{"type":23,"tag":59,"props":70,"children":71},{},[72],{"type":29,"value":73},"只读流量先切到 PostgreSQL 灰度",{"type":23,"tag":59,"props":75,"children":76},{},[77],{"type":29,"value":78},"写流量按业务模块逐步切换",{"type":23,"tag":59,"props":80,"children":81},{},[82],{"type":29,"value":83},"MySQL 降级为只读 backup，30 天后下线",{"type":23,"tag":45,"props":85,"children":86},{},[],{"type":23,"tag":24,"props":88,"children":90},{"id":89},"踩过的坑占位",[91],{"type":29,"value":92},"踩过的坑（占位）",{"type":23,"tag":94,"props":95,"children":96},"ul",{},[97,102,107,112,117],{"type":23,"tag":59,"props":98,"children":99},{},[100],{"type":29,"value":101},"字符集 \u002F 时区差异",{"type":23,"tag":59,"props":103,"children":104},{},[105],{"type":29,"value":106},"自增 ID 的连续性",{"type":23,"tag":59,"props":108,"children":109},{},[110],{"type":29,"value":111},"全文索引语义差异",{"type":23,"tag":59,"props":113,"children":114},{},[115],{"type":29,"value":116},"触发器与存储过程的等价改写",{"type":23,"tag":59,"props":118,"children":119},{},[120],{"type":29,"value":121},"应用层 ORM 的 SQL 兼容",{"type":23,"tag":123,"props":124,"children":125},"blockquote",{},[126],{"type":23,"tag":31,"props":127,"children":128},{},[129],{"type":29,"value":130},"（每个坑的具体方案与回归脚本后续展开）",{"type":23,"tag":45,"props":132,"children":133},{},[],{"type":23,"tag":24,"props":135,"children":137},{"id":136},"写在最后",[138],{"type":29,"value":136},{"type":23,"tag":31,"props":140,"children":141},{},[142,144,149],{"type":29,"value":143},"数据库迁移没有\"标准方案\"，只有\"对你的业务最小风险的路径\"。",{"type":23,"tag":37,"props":145,"children":146},{},[147],{"type":29,"value":148},"预演 2-3 次比文档读 10\n份更有用",{"type":29,"value":150},"——这是浩途技术团队的硬经验。",{"title":7,"searchDepth":152,"depth":152,"links":153},2,[154,155,156,157],{"id":26,"depth":152,"text":26},{"id":50,"depth":152,"text":53},{"id":89,"depth":152,"text":92},{"id":136,"depth":152,"text":136},"markdown","content:insights:16-mysql-to-postgres.md","content","insights\u002F16-mysql-to-postgres.md","insights\u002F16-mysql-to-postgres","md",[165,293],{"_path":166,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":167,"description":7,"slug":168,"date":169,"duration":170,"category":12,"author":13,"tags":171,"body":175,"_type":158,"_id":290,"_source":160,"_file":291,"_stem":292,"_extension":163},"\u002Finsights\u002F14-django-tech-debt","长期可维护：6 年 Django 项目的技术债治理","django-tech-debt","2026-04-02",11,[172,173,174],"Django","技术债","长期维护",{"type":20,"children":176,"toc":284},[177,181,193,196,202,207,225,230,233,239,257,265,268,272],{"type":23,"tag":24,"props":178,"children":179},{"id":26},[180],{"type":29,"value":26},{"type":23,"tag":31,"props":182,"children":183},{},[184,186,191],{"type":29,"value":185},"祁门政务大屏从 2018 年上线至今 6 年，仍在持续迭代。最初的 Django 项目按\"今天\n看明天就过时\"的标准看，技术债理论上爆炸了——但它没有。这篇文章写浩途如何",{"type":23,"tag":37,"props":187,"children":188},{},[189],{"type":29,"value":190},"边\n走边换",{"type":29,"value":192},"地治理技术债。",{"type":23,"tag":45,"props":194,"children":195},{},[],{"type":23,"tag":24,"props":197,"children":199},{"id":198},"原则不重构重组装",[200],{"type":29,"value":201},"原则：不重构，重组装",{"type":23,"tag":31,"props":203,"children":204},{},[205],{"type":29,"value":206},"每次新需求来时优先做三件事：",{"type":23,"tag":55,"props":208,"children":209},{},[210,215,220],{"type":23,"tag":59,"props":211,"children":212},{},[213],{"type":29,"value":214},"把要改的模块的依赖收敛清楚",{"type":23,"tag":59,"props":216,"children":217},{},[218],{"type":29,"value":219},"把\"不再用的\"代码先标记 deprecated 而不删除",{"type":23,"tag":59,"props":221,"children":222},{},[223],{"type":29,"value":224},"在 deprecated 周围逐步建立新模块",{"type":23,"tag":31,"props":226,"children":227},{},[228],{"type":29,"value":229},"3 年下来旧代码消化掉一大半，期间项目从未停止迭代。",{"type":23,"tag":45,"props":231,"children":232},{},[],{"type":23,"tag":24,"props":234,"children":236},{"id":235},"三类常见债的处理占位",[237],{"type":29,"value":238},"三类常见债的处理（占位）",{"type":23,"tag":94,"props":240,"children":241},{},[242,247,252],{"type":23,"tag":59,"props":243,"children":244},{},[245],{"type":29,"value":246},"数据库 schema 历史遗留",{"type":23,"tag":59,"props":248,"children":249},{},[250],{"type":29,"value":251},"第三方 SDK 升级断点",{"type":23,"tag":59,"props":253,"children":254},{},[255],{"type":29,"value":256},"早期接口设计的硬编码",{"type":23,"tag":123,"props":258,"children":259},{},[260],{"type":23,"tag":31,"props":261,"children":262},{},[263],{"type":29,"value":264},"（每类的具体处理 pattern 后续展开）",{"type":23,"tag":45,"props":266,"children":267},{},[],{"type":23,"tag":24,"props":269,"children":270},{"id":136},[271],{"type":29,"value":136},{"type":23,"tag":31,"props":273,"children":274},{},[275,277,282],{"type":29,"value":276},"技术债治理不是项目，是",{"type":23,"tag":37,"props":278,"children":279},{},[280],{"type":29,"value":281},"日常",{"type":29,"value":283},"。把它当作每周做的事，而不是每年做的事——这是长期项目\n能活下来的关键。",{"title":7,"searchDepth":152,"depth":152,"links":285},[286,287,288,289],{"id":26,"depth":152,"text":26},{"id":198,"depth":152,"text":201},{"id":235,"depth":152,"text":238},{"id":136,"depth":152,"text":136},"content:insights:14-django-tech-debt.md","insights\u002F14-django-tech-debt.md","insights\u002F14-django-tech-debt",{"_path":294,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":295,"description":7,"slug":296,"date":297,"duration":298,"category":12,"author":13,"tags":299,"body":304,"_type":158,"_id":424,"_source":160,"_file":425,"_stem":426,"_extension":163},"\u002Finsights\u002F15-nuxt-pagefind","Nuxt 3 静态化 + Pagefind：内容站的工程实践","nuxt-pagefind","2026-02-28",8,[300,301,302,303],"Nuxt 3","Pagefind","SSG","静态站",{"type":20,"children":305,"toc":418},[306,310,322,325,331,364,367,373,391,399,402,406],{"type":23,"tag":24,"props":307,"children":308},{"id":26},[309],{"type":29,"value":26},{"type":23,"tag":31,"props":311,"children":312},{},[313,315,320],{"type":29,"value":314},"浩途官网（haotunet.com）是一个纯静态站——不需要后端、不依赖 CDN 智能化、单机\nnginx 就能服务全国。但又需要站内搜索。",{"type":23,"tag":37,"props":316,"children":317},{},[318],{"type":29,"value":319},"Nuxt 3 + Pagefind",{"type":29,"value":321}," 的组合让这两件事\n零摩擦共存。",{"type":23,"tag":45,"props":323,"children":324},{},[],{"type":23,"tag":24,"props":326,"children":328},{"id":327},"工程选择的三个-trade-off",[329],{"type":29,"value":330},"工程选择的三个 trade-off",{"type":23,"tag":55,"props":332,"children":333},{},[334,344,354],{"type":23,"tag":59,"props":335,"children":336},{},[337,342],{"type":23,"tag":37,"props":338,"children":339},{},[340],{"type":29,"value":341},"SSG vs SSR",{"type":29,"value":343},"：选 SSG（静态化），换更简单的部署",{"type":23,"tag":59,"props":345,"children":346},{},[347,352],{"type":23,"tag":37,"props":348,"children":349},{},[350],{"type":29,"value":351},"客户端搜索 vs 服务端搜索",{"type":29,"value":353},"：选客户端（Pagefind），不需要 ES",{"type":23,"tag":59,"props":355,"children":356},{},[357,362],{"type":23,"tag":37,"props":358,"children":359},{},[360],{"type":29,"value":361},"站内全文 vs 内容片段",{"type":29,"value":363},"：构建时索引，下载体积可控",{"type":23,"tag":45,"props":365,"children":366},{},[],{"type":23,"tag":24,"props":368,"children":370},{"id":369},"关键工程点占位",[371],{"type":29,"value":372},"关键工程点（占位）",{"type":23,"tag":94,"props":374,"children":375},{},[376,381,386],{"type":23,"tag":59,"props":377,"children":378},{},[379],{"type":29,"value":380},"Pagefind 的索引时机：build 阶段而非 dev",{"type":23,"tag":59,"props":382,"children":383},{},[384],{"type":29,"value":385},"索引体积：50 篇内容大约 500KB，懒加载即可",{"type":23,"tag":59,"props":387,"children":388},{},[389],{"type":29,"value":390},"与 Cmd+K 弹窗的集成",{"type":23,"tag":123,"props":392,"children":393},{},[394],{"type":23,"tag":31,"props":395,"children":396},{},[397],{"type":29,"value":398},"（具体配置文件、索引体积控制、UX 细节后续展开）",{"type":23,"tag":45,"props":400,"children":401},{},[],{"type":23,"tag":24,"props":403,"children":404},{"id":136},[405],{"type":29,"value":136},{"type":23,"tag":31,"props":407,"children":408},{},[409,411,416],{"type":29,"value":410},"不是所有内容站都需要重型架构。",{"type":23,"tag":37,"props":412,"children":413},{},[414],{"type":29,"value":415},"对内容站来说，越简单越长寿",{"type":29,"value":417},"——这是浩途自己用一年\n跑下来的体会。",{"title":7,"searchDepth":152,"depth":152,"links":419},[420,421,422,423],{"id":26,"depth":152,"text":26},{"id":327,"depth":152,"text":330},{"id":369,"depth":152,"text":372},{"id":136,"depth":152,"text":136},"content:insights:15-nuxt-pagefind.md","insights\u002F15-nuxt-pagefind.md","insights\u002F15-nuxt-pagefind",1780542368612]