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

5 天前
 liyafe1997

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

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

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

5516 次点击
所在节点    PostgreSQL
90 条回复
thealert
4 天前
@thealert #59 单机地图你甚至都不需要数据库,自定义文件数据结构和解析,参考游戏客户端即可
sagnitude
4 天前
@thealert 1. 基于 sqlite 分库分表,数据库根本不需要主从同步,平均 1GB 一个数据库文件,直接拷贝数据库文件分发到其他服务器就行,增加并发量可以简单的通过增加物理磁盘数量实现
2. 并发访问地图数据有内存缓存池子,sqlite 可以自己把部分数据加载到内存中读取,为何并发量会把接口爆掉?直接从内存返回数据还能被爆掉,那这台服务器上跑任何服务都会被爆掉
3. 地图请求天生都是连续的,因为用户看地图一定是一片连着一片看的,我收到第一个请求,直接把附近的数据加载到内存里,大概率马上就会被请求到,这一段读性能可以得到大幅优化
4. 不是单机地图,我都说了是 GIS 服务,提供标准 OGC 接口,WMS ,WMTS ,的 tile 服务
5. 为什么优先存数据库?地图数据不仅仅只有卫星图这种静态图像,还有高程图这种要随时读取内容并且用于计算的图像数据,还有矢量地图,架构肯定要统一
sagnitude
4 天前
@thealert 而且最重要的原因上面也说了,磁盘存储和 OSS 存储和读写效率太低,我部署一次就要一个月,现在我的数据库导入、导出、更新大部分都可以在内存里做,最低最低也可以达到硬盘的读写极限,比读写小文件性能高太多了
yh7gdiaYW
4 天前
@sagnitude 我猜你的这些场景不需要频繁删改老数据,会有惊喜
yh7gdiaYW
4 天前
说白了这个存数据库这个方案至少在初期可行,但除了给你开发省点力气,与存对象存储的方案相比没有任何好处。看你对现在这份干多久的预期了,过两年就跑就怎么省事怎么来
thealert
4 天前
@sagnitude #62
1 有些业务需要主从同步,跨机房延迟很高,分库分表解决不了高延迟问题
2 本质你是加载了缓存,和数据库就没关系了,但是图片是 ugc 的如何保证实时同步到缓存,我说的是用户请求大你每个用户都返回二进制图片网络接口带宽直接爆了
3 还是缓存问题其实就是 cdn
billbob
4 天前
没坑啊! PostgreSQL 就支持啊,只要支持,就能用.

业务增长,是否合理,那是未来你要考虑的,你前期设计个罗马出来,你也造不出来啊.

开发时间允许,可以放 OSS
sagnitude
4 天前
@thealert 如果抵达后端服务器的请求能把带宽撑爆,后端实现方式是数据库还是文件有区别吗; CDN 实际上就是把重复的直接拦截在前面了,我用数据库也可以用 CDN ,这个不影响
julyclyde
4 天前
文件系统也不过是(多级索引的)数据库
KV 存储也不过是数据库


用关系型数据库保存,其“不好”其实是取决于这个数据库的设计开发水平不好,而不是天生这个形式就不适用于这个用途
yannxia
4 天前
就没什么优点吧?
thealert
4 天前
@sagnitude #68 存在数据库的话不需要同步数据么,而且你这种查库服务的算接口请求把,直接返回大字节的接口数据会给其他业务接口造成压力,具体建议参考下百度,高度地图的存储方案就知道了
thealert
4 天前
@sagnitude #68 因为服务器对客户端的 IP 有连接数量的限制,所以地图瓦片的服务器会提供几个子域,浏览器均匀请求这些子域,来绕过 IP 限制,例如 OSM 地图服务有三个子域,a.tile 、b.tile 、c.tile ,它们指向的是同一个 CDN (内容传送网络)。
gooin
4 天前
@sagnitude 附议。 刚好这两天做了一个存储到 Mbtiles(sqlite)的功能, 看一下它的 Schema
```
CREATE TABLE tiles (zoom_level integer, tile_column integer, tile_row integer, tile_data blob);
```

> MBTiles is a specification for storing tiled map data in SQLite databases for immediate usage and for transfer. MBTiles files, known as tilesets, MUST implement the specification below to ensure compatibility with devices.

https://github.com/mapbox/mbtiles-spec/blob/master/1.3/spec.md
sagnitude
4 天前
@thealert 浏览器到服务器的 TCP 连接是有限制数量,但 http/2 建立的是长连接,已经没这个问题了;用多个子域名去做这个是以前的解决办法

如果数据实时性要求很高,我会改用 postgres 或者 oracle 或者 sqlserver ,我选型就是因为我的更新频率低
sagnitude
4 天前
@gooin 对的,就是 mbtiles ,基于 sqlite 做的扩展,在需要存储 metadata 的情况下,只能选择数据库存储,表很简单,迁移到其他数据库也一样
sagnitude
4 天前
@thealert 地图数据和业务数据肯定不是一个数据库,也不会和业务逻辑跑在同一个带宽、同一台服务器上,没有这个挤占问题,给地图服务的服务器就纯粹为了提供地图 API ,所以他的吞吐量就完完全全是给 tile 服务的。
adoal
4 天前
没必要哄着 5 个并发访问的客户,写着 100 个并发余量的程序,操着 100 万个并发梦的心思。
thealert
4 天前
@sagnitude #74 路况瓦片这种频繁更新的情况,方案是频繁写入数据库然后从库读取,阁下如何对敌?
sagnitude
4 天前
@thealert 路况是矢量图,不会存成图片,矢量图本身数据量就很小,同步压力很小,且不说数据库实时同步,就算用文件我也可以做比如三轮文件轮流切换更新
sagnitude
4 天前
如果有一天我有机会做全国的路况图部署,我肯定是在业务服务器上把道路数据直接切成矢量切片,然后准备一个大内存的机器,直接把 sqlite 或者其他数据库做全内存存储,比如 sqlite 支持 memory 模式。全国卫星图才 12TB ,矢量图最多一百 G ,内存全缓存绰绰有余

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

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

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

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

© 2021 V2EX