用 PostgreSQL 存图片等 binary 有什么坑吗

2 天前
 liyafe1997

如题,大概每个主条目下面关联有几张到一两百张不等的图片/文档之类的附件,每张图最大 500KB (入库时超大会自动压缩),文档也是不超过 500KB 。

目前测试数据(几十/百来个主条目)跑起来感觉挺香的,也没见什么性能问题。特别是设置好外键和 cascade delete 之后,主条目删除会自动把存 binary 的表中关联的附件一并干掉,比放文件系统好维护。文件系统还要自己处理数据关联和清理逻辑。

就是不知道以后数据量大了会有什么坑,预计之后主条目有数万个这样的量级。

5367 次点击
所在节点    PostgreSQL
90 条回复
zephyru
2 天前
@liyafe1997
一般来说,大家说图片 CDN 可能是 OSS 那种模式的。
所有的流量全部走 CDN 不会再打到服务器上。
你这种情况,可能只适合使用套在域名上那种作为前置缓存的 CDN (缓存规则,失效诸如此类的先另说)。
你想使用传统使用 CDN 的方式,得先从 DB 里下载出来再上传,这就是麻烦的点。
这么看来主要的坑点,除了开销大,就是传统的方案需要你自己再另外实现。
xtreme1
2 天前
额, 就是富文本吗. 现在方案都很成熟了啊, 文本存 pg, 附件上 oss, 索引上 es.
KongLiu
2 天前
@liyafe1997 能用和好用是两码事,你这个只能算是能用水平,远远谈不上好用。OSS 配合 CDN 能很容易的改变缓存策略,你这个每一点改动都要改代码。除非你这个项目是玩具项目做出来不用考虑维护的,不然早晚有坑等着呢,你现在的想象中的美好都基于没几个人用的情况。
chambered
2 天前
我觉得 pg 的 bytea 就是用来存这些二进制数据的,所以几十 kb 应该没什么问题,太大肯定不行。还是看文档怎么介绍的吧
skallz
2 天前
之前只有富文本这么干过,当时是为了图省事把里面所有图片资源转成 base64 嵌在富文本里,但是后面也是相当难受,最后把富文本生成一个 json 文件传 oss 了
ytmsdy
2 天前
数据库备份的时候,你就会知道这是一个噩梦,备份文件动不动就是上百 G 。
另外数据还原也是一个问题,很慢,很烦。
我们之前把身份证照片转成了 base64 ,存到了数据库里,然后自动备份服务器的空间动不动就满了。贼烦
donaldturinglee
2 天前
正经做法还是上 OSS
SoviaPhilo
2 天前
除非硬件资源限制了, 最好是能分离, 毕竟如楼上说的方案很成熟了。
而方案成熟那是无数前人拿血和泪换来的。

另外, 数据量大了, 你现在的设计绝大多数都会是坑, 不止是图片。毕竟大数据量和小数据量在设计上肯定是不一样的
kenilalexandra
2 天前
OSS 的出现就是为了解决你不知道的“有什么坑吗”的
geminikingfall
2 天前
这是个什么操作?这不上块存储吗?
billbob
2 天前
上 OSS
liyafe1997
2 天前
@ytmsdy base64 那会增大很多吧,正确不应该用 bytea?
jjx
2 天前
500k 就是 5m 带宽了

两个人并发就带宽报警了

这种还是用 7 牛云之类的吧
june4
2 天前
楼上都没给出实锤证据啊,说明可行?
存成文件也是要 IO 的,且存数据库前面也可以配缓存,不管是文件缓存还是 CDN 缓存

可能就是备份比文件方式不方便一点,如果图片量是巨大的话。
sagnitude
2 天前
没什么太大问题,不要被吓到了。
平时这种应用场景很少,所以大家没做过,可能第一反应就是反对。
我就举一个例子,GIS 地图服务器,比如卫星图的图片,一般都是存数据库里的,几十 TB 照样存,我见过的,sqlite ,postgresql ,mongodb ,都有。比如 postgresql 直接就有一个 PostGIS 扩展来做这个。
全国地图总数据量应该是 10 亿图片量级,存数据库也没问题。
才几万个根本无所谓的。

而且 sqlite 也可以的,关键是做好分库分表,我自己就做过 sqlite 地图服务,每个 sqlite 数据库最多存储大概 1-2GB 的数据,没什么问题。

为什么不用 OSS 或者文件系统?因为他扛不住哈哈哈,我一次性导 20 亿文件进去,OSS 要几个月,文件系统也要等一个月,RAID 也没什么用,存储最佳方式就是数据库,可以解决小文件碎片化的问题。
irrigate2554
2 天前
规模小的话应该没啥问题,memos 就支持存储附件到数据库,我也是这么用的。就怕规模越来越大,加上动不动 select * , 这样总有一天要炸。
irrigate2554
2 天前
有一个明显的劣势就是存视频的话流式播放功能就无法实现了。
CEBBCAT
2 天前
@sagnitude #35 请教下,是这个逻辑吗:OSS 是网络 IO(耗时),FS 是系统调用,SQLite 跑在用户空间,众所周知有时候可以比硬盘快
sagnitude
2 天前
@CEBBCAT
1. OSS 每一个操作都是网络,overhead 超级大,每个 stat 或者 mv cp 耗时增加哪怕 1 毫秒,乘以 20 亿的量级就是 23 天。几个月过去,项目都不要做了
2. 数据库可以用内存加速。
3. 文件系统对于巨量小文件的支持比较烂,碎片大,索引效率低,inode 就要占好几分之一的空间。
对数据库来说,读写是在单个文件内部完成的,不需要文件系统操作 open() close()
xiangyuecn
2 天前
这么丁点数据量随便存,简单粗暴的存储架构,不要听楼上的,那些都是没卵用的提前优化

说不定项目黄了,数据库压力都不一定有上来

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/1161291

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX