在PostgreSQL中存储图像

时间:2008-09-10 15:55:30

标签: postgresql image

好吧,所以我正在开发一个应用程序,它将使用运行PostgreSQL的Linux后端将图像提供给Windows框,其前端用C#.NET编写,尽管前端应该不重要。我的问题是:

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

图像大约为4-6百万像素,我们存储的数量超过3000.可能还是值得注意的是:这不是一个Web应用程序,最多只能有两个前端访问数据库马上。

6 个答案:

答案 0 :(得分:53)

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

我们需要区分“原始图像”和“已处理图像”,如缩略图。

正如Jcoby的回答所说,有两种选择,那么,我建议:

  • 使用 blob (二进制大对象):用于原始图像存储,在您的桌面。请参阅Ivan的答案(备份blob没问题!),PostgreSQL additional supplied modulesHow-tos等。

  • 使用单独的数据库DBlink:用于原始图像存储,在另一个(统一/专用)数据库。在这种情况下,我预先 bytea ,但 blob 几乎相同。分离数据库是“统一图像Web服务”的最佳方式。

  • 使用 bytea (BYTE数组):用于缓存缩略图。缓存小图像以将其快速发送到Web浏览器(避免渲染问题)并减少服务器处理。缓存也是必要的元数据,如宽度和高度。数据库缓存是最简单的方法,但检查您的需求和服务器配置(例如Apache模块):store thumbnails at file system可能更好,比较性能。请记住,它是一个(统一的)Web服务,然后可以存储在separete数据库(没有备份),为许多表提供服务。另请参阅PostgreSQL binary data types manualtests with bytea column

注1:今天不推荐使用"dual solutions" (database+filesystem)(!)。使用“仅数据库”代替双重有许多优点。 PostgreSQL具有可比性能和出口/导入/输入/输出的良好工具。

注意2:记住PostgreSQL只有 bytea ,没有默认的Oracle BLOB :“SQL标准定义(...)BLOB。输入格式不同来自bytea,但提供的函数和运算符大多是相同的“,Manual


编辑 2014 :我今天没有更改原文(我的答案是12月4日,现在有14票),我正在为你的更改打开答案(请参阅“Wiki模式”,您可以编辑!),proofreading更新
问题是稳定的(@Ivans '08以19票回答),请帮助改进这个文本。

答案 1 :(得分:51)

Re jcoby的回答:

bytea是一个“普通”列,也意味着当你获取它时,该值被完全读入内存。相比之下,Blob可以流入stdout。这有助于减少服务器内存占用。特别是,当您存储4-6个MPix图像时。

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

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

Re Kris Erickson的回答:

我会说相反:)。当图像不是您存储的唯一数据时,请不要将它们存储在文件系统上,除非您绝对必须这样做。始终确保数据一致性并将数据“整体”(数据库)保持这样的好处。顺便说一句,PostgreSQL非常适合保持一致性。

然而,事实上,现实往往性能要求太高;-),它会促使您从文件系统中提供二进制文件。但即便如此,我倾向于使用DB作为二进制文件的“主”存储,所有其他关系一致地链接,同时提供一些基于文件系统的缓存机制以进行性能优化。

答案 2 :(得分:26)

在数据库中,有两个选项:

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

我过去使用过bytea列非常成功地存储了数千行的10 + gb图像。 PG的TOAST功能几乎否定了blob的任何优势。在文件名,内容类型,维度等方面,您需要包含元数据列。

答案 3 :(得分:20)

快速更新至2015年中期:

您可以使用 Postgres外部数据接口将文件存储在更合适的数据库中。例如,将文件放在GridFS中,这是MongoDB的一部分。然后用 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的优势,而实际文件系统仍然存在,这意味着您可以使用任何所需的文件系统,并且Web服务器可以提供服务它们直接(OS缓存也适用)。

答案 4 :(得分:14)

10年后更新 在2008年,您运行数据库的硬盘驱动器将具有与您存储文件所在的磁盘不同的特性和更高的成本。现在有更好的解决方案来存储10年前不存在的文件,我会撤销这个建议,并建议读者在这个帖子中查看其他一些答案。

<强>原始

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

//linuxserver/images/imagexxx.jpg

那么也许您可以快速设置网络服务器并将网址存储在数据库中(以及本地路径)。虽然数据库可以处理LOB和3000个图像(4-6百万像素,假设500K图像)1.5 Gigs并不是很多空间文件系统设计用于存储大型文件而不是数据库。

答案 5 :(得分:5)

试试this。我使用大对象二进制(LOB)格式来存储生成的PDF文档,其中一些大小超过10 MB,在数据库中运行得非常好。