为什么大文件不该存数据库:数据库与对象存储的职责分离
把文件存在数据库而不是 S3 里,应用规模上来后会出现两个巨大的架构瓶颈。这篇 dev.to 文章用三个角度拆解了数据库存 BLOB 的代价,以及对象存储为什么更合适。
瓶颈一:CDN 几乎没法用
S3 最大的优势之一是能轻松配合 CDN(如 CloudFront 或 Cloudflare)。想象数百万用户请求同一批图片:用 S3 + CDN,CDN 可以把图片缓存在全球各地的边缘节点,用户从最近的节点拿文件,而不是每次都打到应用服务器。这正是图片、视频、PDF、JavaScript、CSS 等静态内容想要的。
如果图片以 BLOB 存在数据库里,CDN 对它们就是"失明"的。每一次图片请求都必须打到 Web 服务器,服务器再执行一次重量级数据库查询取二进制数据、流回 Web 服务器、再发给客户端。这等于强迫最贵的设施(数据库)当笨拙的文件服务器,完全绕过了边缘缓存的提速和降本。
瓶颈二:数据库复制变重
生产数据库通常有副本做高可用。如果数据库里主要是结构化数据,复制相对直接。但想象数据库里装了几百 GB 甚至几 TB 的图片和视频——这些大二进制对象也进入复制和备份工作负载。原本只复制用户、订单、产品、支付,现在还要复制 500GB 图片、1TB 视频、200GB 文档。备份和恢复同样受影响:含大量二进制数据的备份,恢复时间比只含结构化数据的备份长得多。
瓶颈三:数据库被无谓撑大
数据库极其擅长它设计的事:关系、事务、查询、索引、结构化数据、一致性。但存大文件是另一个问题,对象存储正是为存大对象设计的。与其让数据库包办一切,不如分开职责:数据库存用户、订单、支付、文件元数据和文件引用;S3 存图片、视频、PDF、文档。各做各擅长的。
S3 背后的物理存储
作为 S3 用户,你不需要知道某个对象在 HDD 还是 SSD 上、在哪个物理盘里——AWS 管理那层基础设施。你与 S3 交互的是对象抽象(my-bucket/users/123/profile.jpg),而不是磁盘 123、扇区 456。这种抽象正是对象存储的主要好处之一。
典型架构
应用 → 数据库(文件元数据)+ S3(实际文件)。上传甚至可以用预签名 URL:客户端直接上传到 S3,不经过应用服务器,数据库只需要记文件名、大小、内容类型和 S3 key。
BLOB 永远错吗
不。文件很小且应用简单时,存数据库可能更省事、完全可以接受。关键是理解权衡。对大规模系统,规则很简洁:结构化数据和元数据进数据库,大文件进 S3/对象存储。这让文件存储能独立扩容、CDN 集成更顺,也避免把主数据库变成文件服务器。
来源:Why You Shouldn't Store Large Files in Your Database: Database vs. Amazon S3 - DEV Community