【发布时间】:2014-04-30 09:43:13
【问题描述】:
一年前,当我使用简单的 MySQL 数据库为人们创建简单的 PHP 站点时,我从小就认为将整个图像存储在数据库中是可能的,但这是一个糟糕的想法。相反,您应该将图像存储在文件系统中,并将图像路径简单地存储在数据库中。尽管我缺乏经验,但我从一开始就同意这一点。当您将数据库备份到外部服务时,它必须保持数据库轻便,并在实际本地使用时使其更快。然而,后面这点完全是猜测,我希望有人澄清我的理论:
当您将与数据库中的对象关联的图像存储为 BLOB 时,当您请求此对象时,是否将整个对象及其属性(包括大量图像信息)写入内存,即使在不需要时也是如此?例如
2.0.0p247 :001 > Object.column_names
=> ["id", "name", "blob"]
2.0.0p247 :001 > Object.first.blob
=> # not sure what this will return! I'm guessing a matrix-like wall of image information?
2.0.0p247 :003 > Object.first.name
User Load (0.8ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
=> "Kitty"
我了解调用Object.first.blob 将花费相对较长的时间,因为我们正在检索大量图像信息。但是Object.first.name 是否会花费相同的时间,因为Object.first 将所有内容、id、name 和blob 都写入内存? 如果这个问题的答案是肯定的,那就是从不使用 BLOBS 的一个很好的理由。但是,如果答案是否定的,并且 rails 足够聪明,可以只将请求的属性写入内存,那么 BLOBS 突然变得非常有吸引力。
老实说,我真的很担心你会说将图像存储在 BLOB 中既好又好。它会让事情变得容易得多。备份将很简单。在一次“模块化”上传中备份站点的动态内容会感觉非常好,而不是诉诸一些复杂的whenever 增强 rake 任务来确保路径及其各自的图像被上传到外部位置。
更是如此绝对不可能使用 Rails 将某些图像设为私有。我搜索得很高,我搜索得很低,我在这里问过。得到了一些支持,但没有可靠的回应。网上没有教程。没有。关于如何在资产文件夹中存储图像的教程包,但没有将图像设为私有。
假设我有三种类型的用户,typeA、typeB 和 typeC。假设我有三种类型的图像。所以数据库模式如下:
图片
=> ["image_path","blob","type"]
用户
=> ["name","type"]
我想要的是用户只能请求以下内容:
类型A:
只能查看 A 类型的图像
无法查看 B 类型的图像
不能只查看 C 类型的图像
类型B:
只能查看 B 类型的图像
无法查看 A 类型的图像
不能只查看 C 类型的图像
typeC:
只能查看 C 类型的图像
无法查看 A 类型的图像
不能只查看 B 类型的图像
是的,我可以用两种类型的用户和图像给你一个例子,但我真的想确保你理解这个问题;我想到的实际系统将有数百个types。
就像我说的,非常简单的想法,但我发现使用 rails 是不可能的,因为所有图像都存储在公共文件夹中!所以typeB 用户只需输入/assets/typeAImage.jpg 就可以了!哎呀,即使不是用户也可以做到。
send_file 方法对我不起作用,因为我不是按 sae 将图像作为下载发送给他们,而是在视图中向他们展示图像。*
现在,如果图像存储在数据库中,使用 BLOBS 将非常巧妙地解决这个问题。我不确定实际的语法,但我可以在用户视图中做这样的事情:
<% if current_user.type == image.type do %>
<%= image_tag image.blob #=> <img src="/assets/typaAImage.jpg" alt="..." class="..."> %>
<% end %>
是的,你可以用路径做同样的事情:
<% if current_user.type == image.type do %>
<%= image_tag image.path #=> <img src="/assets/typaAImage.jpg" alt="..." class="..."> %>
<% end %>
但就像我说的,即使不是用户也可以简单地请求/assets/typeAImage.jpg。 如果存储在 BLOB 中,则无法执行此操作。
结论:
-
popplersBLOBS 有什么问题?我在 Heroku 上运行一个 postgres 数据库,每秒有几十个用户。所以是的,不是Facebook,但也不是Allegory on the Pointless of Life,所以性能很重要。他们还拥有强大的移动追随者,因此速度至关重要。使用 BLOBS 会与此冲突吗? -
如何在视图中显示存储在 BLOB 中的图像?
-
为了确认一下,BLOBS 将允许我通过 https 向某些成员安全地显示安全的秘密图像?
-
数据库备份速度怎么样?这会受到打击,但无论如何我都想备份图像,而且这是每晚的事情,所以谁在乎它是否很慢?对吧?
-
只要备份是加密的,图像就会是安全的,对吗?就像密码在数据库中存储为哈希一样,我是否也应该以加密格式存储我的超级机密 BLOBS?我想是的......你认为bcrypt 能胜任这项任务吗?我不明白为什么不。
-
BLOBS 是否被认为是业余和懒惰的?
...最后加分(可能超出问题的范围):
*= 当我写这篇文章时,我在想'是的,但是在视图中显示图像是将图像下载给他们。那么send_file方法能不能按照我描述的方式创建私有镜像,使用文件系统存储镜像呢?
【问题讨论】:
-
听起来您更关心 Rails 对
bytea字段的限制(假设这就是您所说的“blob”),而不是与数据库本身有关的任何事情。
标签: ruby-on-rails postgresql blob