在PostgreSQL中存储图像

好的,所以我正在开发一个应用程序,它将使用运行PostgreSQL的Linux后端将图像提供到Windows前端以C#.NET编写的盒子中,尽pipe前端应该不会有问题。 我的问题是:

  • 处理在Postgres中存储图像的最佳方式是什么?

这些图片大概有4-6百万像素,而且我们存储的是3000个以上的图片。还有一点值得注意的是:这不是一个Web应用程序,最多只有两个前端访问数据库。

Re jcoby的回答:

bytea是一个“正常”列,也意味着当你获取它的值被完全读入内存。 Blob,相反,你可以stream入标准输出。 这有助于减less服务器内存占用。 尤其是,当您存储4-6个MPix图像时。

没有问题备份blob。 pg_dump提供“-b”选项来将大对象包含在备份中。

所以,我更喜欢使用pg_lo_ *,你可能会猜到。

Re Kris Erickson的回答:

我会说相反的:)。 如果图像不是您存储的唯一数据,请不要将其存储在文件系统中,除非您绝对必须。 确保您的数据一致性并将数据“整合”(数据库)是非常有好处的。 顺便说一句,PostgreSQL在保持一致性方面非常出色。

然而,事实上,真实性往往要求太高,而且它会促使你从文件系统提供二进制文件。 但即使如此,我倾向于使用数据库作为二进制文件的“主”存储,其他所有关系都一致地链接,同时为性能优化提供了一些基于文件系统的caching机制。

更新到2012年,当我们看到图像尺寸和图像数量正在不断增长,在所有应用中…

我们需要在“原始图像”和“处理图像”之间做一些区分,如缩略图。

正如Jcoby的回答所说,有两种select,那么我build议:

  • 使用blob (Binary Large OBject):用于原始图像存储,在您的桌面上。 看到伊万的答案(备份斑点没有问题!), PostgreSQL额外提供的模块 ,操作方法等。

  • 在另一个(统一/专用)数据库中使用带有DBlink的独立数据库:用于原始图像存储。 在这种情况下,我认为bytea ,但blob接近相同。 分离数据库是“统一的图像networking服务”的最佳途径。

  • 使用bytea (BYTE Array):用于caching缩略图图像。 caching小图片,快速发送到网页浏览器(避免渲染问题),减less服务器处理。 caching也是必要的元数据,如宽度和高度。 数据库caching是最简单的方法,但检查您的需求和服务器configuration(如Apache模块): 在文件系统存储缩略图可能会更好,比较性能。 请记住,它是一个(统一的)networking服务,然后可以存储在一个单独的数据库(没有备份),为多个表提供服务。 另请参见PostgreSQL二进制数据types手册 , 使用bytea列进行testing等。

注1:今天使用“双重解决scheme”(数据库+文件系统)已被弃用(!)。 使用“唯一的数据库”而不是双重的优点很多。 PostgreSQL具有可比较的性能以及用于导出/导入/input/输出的良好工具。

注2:请记住,PostgreSQL只有bytea ,没有默认的Oracle BLOB :“SQL标准定义(…)BLOB,input格式不同于bytea,但提供的函数和操作符大部分是相同的。


编辑2014年 :我今天没有改变原来的文字(我的回答是2012年4月22日,现在有14票), 我打开你的修改答案 (见“维基模式”,你可以编辑!), 校对和更新
问题是稳定的(@ Ivans '08回答19票),请帮助改善这个文本。

在数据库中有两个选项:

  • BYTEA。 将数据存储在列中,作为备份的一部分导出。 使用标准数据库function来保存和检索。 推荐您的需求。
  • 斑点。 将数据存储在外部,通常不作为备份的一部分导出。 需要特殊的数据库function来保存和检索。

过去,我使用bytea列取得了成千上万行的10 + gb图像。 PG的TOASTfunction几乎否定了blob具有的优点。 无论是文件名,内容types,尺寸等,都需要包含元数据列。

2015年中快速更新:

您可以使用Postgres外部数据接口将文件存储在更合适的数据库中。 例如,将文件放在MongoDB的一部分GridFS中。 然后使用https://github.com/EnterpriseDB/mongo_fdw在Postgres中访问它。;

这样做的优点是,您可以在Postrgres和MongoDB中访问/读取/写入/备份它,具体取决于提供更多的灵活性。

还有文件系统的外部数据包装器: https //wiki.postgresql.org/wiki/Foreign_data_wrappers#File_Wrappers

作为一个例子,你可以使用这个: https : //multicorn.readthedocs.org/en/latest/foreign-data-wrappers/fsfdw.html (这里查看简要的使用示例)

这就给了你一致性的好处(所有链接的文件都在那里)和所有其他的ACID,而实际的文件系统上仍然存在,这意味着你可以使用任何你想要的文件系统,并且networking服务器可以直接服务它们操作系统caching也适用)。

除非您绝对必须,否则不要将图像存储在数据库中。 我明白,这不是一个Web应用程序,但如果没有共享的文件位置,您可以指向将文件的位置保存在数据库中。

//linuxserverhttp://img.dovov.comimagexxx.jpg 

那么也许你可以快速build立一个networking服务器,并将url存储在数据库中(以及本地path)。 虽然数据库可以处理LOB的和3000的图像(4-6万像素,假设500K的图像)1.5 GB的是不是太多的空间文件系统是更好地devise来存储大型文件比数据库是。

试试这个 。 我使用大对象二进制(LOB)格式将生成的PDF文档(其中一些大小超过10 MB)存储在数据库中,并且工作起来非常好。