Answers:
更新到2012年,当我们看到在所有应用程序中图像尺寸和图像数量都在不断增长时...
我们需要区分“原始图像”和“处理后的图像”,例如缩略图。
正如Jcoby的回答所言,那么有两种选择,我建议:
使用Blob(二进制大对象):用于原始图像存储,在您的桌子上。见伊万的回答(用备份的斑点没问题!),PostgreSQL的额外供电的模块,如何渡等。
使用DBlink单独的数据库:用于原始图像存储,位于另一个(统一/专业化)数据库。在这种情况下,我更喜欢bytea,但blob 几乎相同。分离数据库是“统一图像Web服务”的最佳方法。
使用BYtea(BYTE Array):用于缓存缩略图。缓存少量图像以将其快速发送到Web浏览器(以避免呈现问题)并减少服务器处理。缓存基本元数据,例如宽度和高度。数据库缓存是最简单的方法,但是检查您的需求和服务器配置(例如Apache模块):将缩略图存储在文件系统中可能会更好,比较性能。请记住,它是一个(统一的)Web服务,然后可以存储在一个单独的数据库中(没有备份),该数据库可以服务许多表。另请参见PostgreSQL二进制数据类型手册,使用bytea列进行测试等。
注意1:今天不建议使用“双重解决方案”(数据库+文件系统)。使用“仅数据库”而不是双重使用有很多优点。PostgreSQL具有可比的性能和用于导出/导入/输入/输出的良好工具。
注意2:请记住PostgreSQL仅具有bytea,而没有默认的Oracle BLOB:“ SQL标准定义了(...)BLOB。输入格式与bytea不同,但是提供的函数和运算符基本相同”,Manual。
EDIT 2014:今天我没有更改上面的原始文本(我的回答是12年12月22日,现在以14票),我正在打开您所做更改的答案 (请参阅“ Wiki模式”,您可以编辑!),以便进行校对和更新。
这个问题很稳定(@Ivans的'08答案为19票),请帮助改善本文。
关于jcoby的回答:
bytea为“正常”列也意味着在您获取值时,该值已完全读入内存。相反,Blob可以流到stdout中。这有助于减少服务器内存占用。特别是当您存储4-6个MPix图像时。
备份Blob没问题。pg_dump提供了“ -b”选项,以将大对象包括到备份中。
因此,您可能会猜测,我更喜欢使用pg_lo_ *。
关于克里斯·埃里克森的回答:
我会说相反的话:)。当图像不是您唯一存储的数据时,除非绝对必要,否则不要将它们存储在文件系统中。始终确保您的数据一致性并将数据“合为一体”(数据库)是非常有益的。顺便说一句,PostgreSQL在保持一致性方面很棒。
但是,确实,现实往往对性能要求很高;-)会迫使您从文件系统提供二进制文件。但是即使那样,我仍然倾向于使用DB作为二进制文件的“主”存储,所有其他关系始终保持链接,同时提供一些基于文件系统的缓存机制来优化性能。
BYTEA
“普通”列。Postgres多年来一直支持到列的流传输BYTEA
,这意味着您不必在将内容存储在数据库中之前将其存储在内存中。
在数据库中,有两个选项:
过去,我使用bytea列取得了巨大的成功,可存储10 + gb的图像并具有数千行。PG的TOAST功能几乎抵消了Blob具有的任何优势。无论哪种情况,您都需要包含元数据列,以用于文件名,内容类型,尺寸等。
快速更新到2015年中期:
您可以使用Postgres Foreign Data接口,将文件存储在更合适的数据库中。例如,将文件放在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服务器可以直接为它们提供服务(操作系统缓存也适用)。
十年后的更新 在2008年,您要在其上运行数据库的硬盘驱动器将具有与要在其上存储文件的磁盘不同的特性,并且成本要高得多。如今,有更好的解决方案来存储10年前不存在的文件,我将撤销此建议,并建议读者查看此主题中的其他一些答案。
原版的
除非绝对必要,否则不要将其存储在数据库的图像中。我知道这不是Web应用程序,但是如果没有共享的文件位置,则可以指向将文件的位置保存在数据库中。
//linuxserver/images/imagexxx.jpg
那么也许您可以快速设置Web服务器并将Web网址存储在数据库中(以及本地路径)。尽管数据库可以处理LOB和3000张图像(4-6兆像素,假设500K图像),但1.5 Gig并不是很多空间文件系统比数据库更适合存储大型文件。
如果图像较小,请考虑将它们作为base64存储在纯文本字段中。
原因是,尽管base64的开销为33%,但压缩几乎消失了。(请参阅Base64编码的空间开销是多少?)您的数据库将更大,但您的Web服务器发送给客户端的数据包将不会更大。在html中,您可以在<img src =“”>标记中内联base64,这可以简化您的应用程序,因为您不必在单独的浏览器访存中将图像作为二进制文件提供。当您必须发送/接收json时,将图像作为文本处理还可以简化事情,而json不能很好地处理二进制文件。
是的,我知道您可以将二进制文件存储在数据库中,并在进出数据库的过程中将其转换为文本或从文本转换为文本,但是有时ORM会带来麻烦。像对待所有其他字段一样,将其视为纯文本可能会更简单。
这绝对是处理缩略图的正确方法。
(OP的图像并不小,因此这并不是他问题的答案。)