2008-09-10 100 views
74

好的,所以我正在研究一个应用程序,该应用程序将使用运行PostgreSQL的Linux后端将图像提供给以C#.NET编写的前端的Windows盒子,尽管前端应该不重要。我的问题是:在PostgreSQL中存储图像

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

的图像是围绕每个4-6百万像素,我们正在储存向上的3000也可能是好注意:这不是一个Web应用程序,将有至多是大约两个前置式结束一次访问数据库。

回答

20

在数据库中,有两种选择:

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

我已经使用bytea列在过去成功存储10 + gb图像数千行的成功。 PG的TOAST功能几乎否定了blob具有的优点。您需要在文件名,内容类型,尺寸等情况下包含元数据列。

+0

10GB并不多:-(我正在寻找TBs解决方案 – 2017-06-09 20:33:52

+1

@ValentinHeinitz对于TBs,即使使用较小的文本列,vanilla Postgres仍然在挣扎 – sudo 2017-09-06 20:09:33

2

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

7

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

//linuxserver/images/imagexxx.jpg 

那么也许你可以快速建立一个网络服务器,并将网址存储在数据库中(以及本地路径)。虽然数据库可以处理LOB和3000图像(假设500K的图像为4-6万像素),但1.5G的空间并不是很多,文件系统比数据库更适合存储大型文件。

+9

但是您必须想出一种方法将文件分布到多个目录中。文件系统并不擅长在单个目录中存储数百个文件(实际上有一万个已经是个问题) – 2013-11-03 10:38:45

44

重新jcoby的回答是:

BYTEA是一个“正常”栏也意味着,当你把它拿来被完全读入内存的值。 Blob,相反,你可以流入标准输出。这有助于减少服务器内存占用。特别是,当您存储4-6个MPix图像时。

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

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

Re克里斯埃里克森的回答:

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

然而,真实的现实通常对性能要求过高;-),它会促使您从文件系统提供二进制文件。但即使如此,我仍倾向于将DB用作二进制文件的“主”存储,其他所有关系始终保持关联,同时提供一些基于文件系统的缓存机制以实现性能优化。

41

更新到2012年的时候,我们看到的图像尺寸和图像的数量,都在不断扩张,在所有应用中......

我们需要“原始图像”和“处理后的图像”之间的一些区别,像缩略图一样。

由于Jcoby的回答说,有两种选择,那么,我建议:

  • 使用BLOB(二进制大对象):原创形象店,在你的餐桌。见伊万的回答,PostgreSQL additional supplied modulesHow-tos

  • 使用单独的数据库与DBlink(有备份的斑点没问题!):原创形象店,在另一个(统一/专业)数据库。在这种情况下,我preffer bytea,但blob是几乎相同。分离数据库是“统一图像web服务”的最佳途径。

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

注1:(!)今天使用的"dual solutions" (database+filesystem)已经过时了。使用“唯一数据库”代替双重数据库有很多优点。 PostgreSQL具有可比较的性能和用于导出/导入/输入/输出的良好工具。

NOTE2:记住PostgreSQL的只有BYTEA,没有一个默认Oracle的BLOB:“SQL标准定义(...)BLOB的输入格式为BYTEA不同,但所提供的功能和运营商大多是相同的“,Manual


编辑:我没有改变今天上方的原文(我的答案是04月22日'12,现在有14票),我 正在打开的答案更改(见“维基模式“,你可以编辑!),为proofreading更新
问题是稳定的(@ Ivans '08回答19票),请帮助改进这个文本。

15

快速更新到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,而实际文件系统上仍存在,这意味着您可以使用任何所需的文件系统,并且Web服务器可以直接为它们提供服务(也可以使用操作系统缓存)。