[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-post-file-storage-evolution-zh-CN":3,"blog-adjacent-file-storage-evolution-zh-CN":29,"blog-related-file-storage-evolution-zh-CN":65},{"id":4,"slug":5,"title":6,"excerpt":7,"content":8,"cover":9,"tone":10,"author":11,"publishedAt":12,"updatedAt":12,"readingMinutes":13,"featured":14,"tags":15,"category":19,"seoSettings":28},44,"file-storage-evolution","文件存储：从本地目录到对象存储","附件功能一开始都很简单，直到客户开始上传几个 G 的视频，并要求权限隔离。","\u003Cp>几乎所有后台系统都有附件功能。第一版通常是把文件存到服务器本地目录，数据库记一个路径。这套方案在单机、小文件、少量用户的场景下完全够用。\u003C\u002Fp>\n\u003Ch2>什么时候必须换\u003C\u002Fh2>\n\u003Cp>多台服务器部署时，本地目录无法共享，用户上传的文件可能在下一次请求里找不到。\u003C\u002Fp>\n\u003Cp>文件体积增长后，备份和迁移成本迅速上升，磁盘扩容也变得麻烦。\u003C\u002Fp>\n\u003Cp>合规要求需要细粒度权限，本地目录的权限模型难以支撑。\u003C\u002Fp>\n\u003Ch2>迁移路径\u003C\u002Fh2>\n\u003Cp>先抽象出统一的存储接口，业务只依赖接口，不直接操作文件系统。\u003C\u002Fp>\n\u003Cp>把新上传的文件写入对象存储，历史文件保留原路径并逐步迁移。\u003C\u002Fp>\n\u003Cp>下载统一走签名链接，控制有效期和访问权限，避免文件被直接爬取。\u003C\u002Fp>\n\u003Cp>存储方案的演进不必一步到位，但接口抽象应该在第一版就做好，否则迁移成本会高出一个量级。\u003C\u002Fp>","","cyan","佳益方圆团队","2026-05-02T15:02:00+08:00",1,false,[16,17,18],"存储","架构","文件管理",{"id":13,"parentId":20,"slug":21,"name":22,"description":23,"icon":24,"cover":9,"tone":25,"kind":26,"sortOrder":27,"count":20},0,"engineering","技术专栏","架构设计、性能优化、AI 集成与跨端方案等一线技术实践，由研发团队持续分享。","cpu","blue","article",60,{},{"previous":30,"next":48},{"id":31,"slug":32,"title":33,"excerpt":34,"content":9,"cover":9,"tone":35,"author":11,"publishedAt":36,"updatedAt":36,"readingMinutes":13,"featured":14,"tags":37,"category":41},23,"how-small-teams-learn","小团队怎么学新技术","没有培训预算、没有学习时间，小团队只能把学习嵌进项目里。","slate","2026-05-04T14:49:00+08:00",[38,39,40],"创业","技术","学习",{"id":42,"parentId":20,"slug":43,"name":44,"description":45,"icon":46,"cover":9,"tone":25,"kind":26,"sortOrder":47,"count":20},6,"founder-notes","创业手记","创始团队在经营、管理与产品上的思考，记录一家软件公司的成长过程。","pen-tool",10,{"id":49,"slug":50,"title":51,"excerpt":52,"content":9,"cover":9,"tone":35,"author":11,"publishedAt":53,"updatedAt":53,"readingMinutes":13,"featured":14,"tags":54,"category":58},64,"multilingual-product-costs","多语言产品的隐性成本","把界面翻译成英文只是开始，真正的成本在内容、日期格式和业务流程上。","2026-04-30T15:02:00+08:00",[55,56,57],"多语言","产品设计","国际化",{"id":59,"parentId":20,"slug":60,"name":61,"description":62,"icon":63,"cover":9,"tone":25,"kind":26,"sortOrder":64,"count":20},2,"product-thinking","产品思维","需求分析、用户体验与产品设计方法论，以及从业务问题到产品方案的思考过程。","lightbulb",50,[66,77,88],{"id":67,"slug":68,"title":69,"excerpt":70,"content":9,"cover":9,"tone":10,"author":11,"publishedAt":71,"updatedAt":71,"readingMinutes":13,"featured":14,"tags":72,"category":76},30,"integration-api-pitfalls","企业系统集成：接口对接最容易踩的五个坑","接口文档写得再全，真正对接时仍然会卡在字段约定、超时和重复推送这些细节上。","2026-10-17T09:00:00+08:00",[73,74,75],"系统集成","接口","工程实践",{"id":13,"parentId":20,"slug":21,"name":22,"description":23,"icon":24,"cover":9,"tone":25,"kind":26,"sortOrder":27,"count":20},{"id":13,"slug":78,"title":79,"excerpt":80,"content":9,"cover":9,"tone":10,"author":11,"publishedAt":81,"updatedAt":82,"readingMinutes":59,"featured":83,"tags":84,"category":87},"why-enterprise-systems-age","为什么企业系统会在三年后开始“老化”","系统上线时功能齐全，三年后却处处别扭。问题往往不在代码，而在交付时被忽略的那些变化。","2026-10-16T09:30:00+08:00","2026-10-18T15:58:14.648+08:00",true,[85,86],"系统演进","架构设计",{"id":13,"parentId":20,"slug":21,"name":22,"description":23,"icon":24,"cover":9,"tone":25,"kind":26,"sortOrder":27,"count":20},{"id":89,"slug":90,"title":91,"excerpt":92,"content":9,"cover":9,"tone":25,"author":11,"publishedAt":93,"updatedAt":93,"readingMinutes":13,"featured":14,"tags":94,"category":98},31,"idempotent-design-basics","幂等设计：重复提交不只是用户手抖","网络重试、消息重投、用户连点，都会让同一个请求到达多次。幂等应该设计在接口里。","2026-10-05T10:13:00+08:00",[95,96,97],"接口设计","幂等","可靠性",{"id":13,"parentId":20,"slug":21,"name":22,"description":23,"icon":24,"cover":9,"tone":25,"kind":26,"sortOrder":27,"count":20}]