我想将上传的图像保存bytea
在我的 PostgreSQL 数据库的列中。我正在寻找有关如何将 Rails 中的图像保存到bytea
列中的建议,最好带有示例。
我使用带有“pg”驱动程序的 Rails 3.1 连接到 PostgreSQL。
我想将上传的图像保存bytea
在我的 PostgreSQL 数据库的列中。我正在寻找有关如何将 Rails 中的图像保存到bytea
列中的建议,最好带有示例。
我使用带有“pg”驱动程序的 Rails 3.1 连接到 PostgreSQL。
请参阅有关将图像存储在 BLOB 中还是仅 URL 中更好的讨论?和文件 - 是否在数据库中?. 请注意,这些问题及其答案与 PostgreSQL 无关。
这有一些 PostgreSQL 特定的皱纹。PostgreSQL 没有任何增量转储工具*,因此如果您使用pg_dump
备份,则必须为每个备份转储所有图像数据。存储空间和传输时间可能是一个问题,特别是因为您应该保留数周的备份,而不仅仅是一个最近的备份。
如果图像很大或很多,您可能需要考虑将图像存储在文件系统中,除非您强烈需要对它们进行事务性、符合 ACID 的访问。将文件名存储在数据库中,或者只是根据有用的密钥建立文件命名约定。这样,您可以轻松地对映像目录进行增量备份,将其单独管理到适当的数据库中。
如果您将图像存储在 FS 中,您将无法轻松†</sup> 通过 PostgreSQL 数据库连接访问它们。OTOH,您可以直接从文件系统通过 HTTP 直接为它们提供服务,这比您必须首先从数据库查询它们时所希望的要高效得多。特别是,如果您的图像在 FS 上,但不能来自数据库,您可以使用 rails 中的 sendfile() 。
...那么它在概念上与 .NET 中的相同,但具体细节取决于您使用的 Pg 驱动程序,您没有指定。
有两种方法可以做到:
bytea
,如您所问;和bytea
.ruby-pg
驱动程序,驱动程序中的test_binary_values示例应该对您有所帮助。lo
改用:对于更大的图像,请不要使用bytea
. 它的理论最大值可能是 2GB,但实际上您需要 3 倍 RAM(或更多),因为图像大小会建议您避免使用bytea
大图像或其他大型二进制数据。
PostgreSQL 有一个专用的lo
(大对象)类型。在 9.1 上:
CREATE EXTENSION lo;
CREATE TABLE some_images(id serial primary key, lo image_data not null);
...然后用于lo_import
从磁盘上的临时文件中读取数据,因此您不必一次将整个内容放入 RAM 中。
驱动程序为、等ruby-pg
提供包装调用,并为本地文件访问提供了一个。请参阅这个有用的示例。lo_create
lo_open
lo_import
请使用大物体而不是bytea
.
*增量备份可以通过流复制、PITR / WAL 归档等进行,但再次增加数据库大小会使 WAL 管理等事情变得复杂。无论如何,除非您是专家(或“勇敢”),否则您应该进行pg_dump
备份,而不是仅依靠复制和 PITR。将图像放入数据库也会——通过增加数据库的大小——大大减慢速度pg_basebackup
,这在故障转移场景中可能很重要。
†</sup> adminpack通过 Pg 连接为超级用户提供本地文件访问。但是,您的 webapp 用户永远不应该拥有超级用户权限,甚至不应该拥有它所使用的表的所有权。通过单独的安全通道(例如WebDAV
.