存储上传的映像、 SQL 数据库或磁盘文件系统的最佳位置是什么?

我正在写一个应用程序,允许用户上传图片到服务器上。我希望每天有大约20张图片都是 jpeg 格式的,而且可能没有经过编辑或者调整大小。(这是另一个问题,如何在存储之前调整服务器端的图像大小。也许有人可以把。NET 资源)。 现在我想知道存储上传图片的最佳地点是哪里。

  • 将图像作为文件存储在文件系统中,并在表中创建一条具有该图像确切路径的记录。

  • 或者,使用数据库服务器的“图像”或“二进制数据”数据类型将图像本身存储在表中。

我看到了两者的优点和缺点。 我喜欢 a) ,因为我可以很容易地重新定位文件,只需要改变表条目。另一方面,我不喜欢在 Web 服务器上存储业务数据,我也不想将 Web 服务器连接到任何其他存储业务数据的数据源(出于安全原因) 我喜欢 b) ,因为所有的信息都在一个地方,很容易通过查询访问。另一方面,数据库很快就会变得非常庞大。将这些数据外包可能会更加困难。

147388 次浏览

我通常将文件存储在文件系统中,因为这就是文件系统存储文件的目的,尽管也有例外。对于文件,文件系统是最灵活和性能最好的解决方案(通常)。

在数据库中存储文件有一些问题-文件通常比平均行结果大得多-包含许多大文件的结果集将消耗大量内存。此外,如果使用使用表锁进行写操作的存储引擎(例如 ISAM) ,则根据存储在那里的文件的大小/速率,可能会经常锁定文件表。

关于安全性——我通常将文件存储在文档根目录之外的目录中(不能通过 http 请求访问) ,并通过一个脚本首先检查正确的授权。

我们使用 A,我会把它放在一个共享驱动器上(除非你不打算运行多个服务器)。

如果时机成熟,这种方法不适合您,那么您可以研究缓存机制。

大多数实现是选项 A。

使用选项 B,当您将数据库中的这些位整理成可以在浏览器上显示的内容时,您将打开一个完整的 whoop4ss 大罐... ... 此外,如果数据库关闭,图像将不可用。

我不认为空间是一个太大的问题... 太字节驱动器现在是几百美元。

我们使用选项 A 来实现,因为我们没有时间或资源来实现选项 B。

当然,肯定的选项 A。其他人提到,数据库通常不能很好地处理 BLOB,无论它们是否被设计成这样。另一方面,文件系统就是为这些东西而存在的。您可以选择使用 RAID 条带化,在多个驱动器之间传播映像,甚至在地理上完全不同的服务器之间传播映像。

另一个优势是您的数据库备份/复制将是可怕的。

对于自动调整大小,尝试 image magick... 它被用于许多主要的开源内容/照片管理系统... 我相信有一些。它的净扩展。

我们已经有客户在几个不同的后端上坚持选项 B (数据库存储)几次,我们 一直都是最终回到选项 A (文件系统存储)。

即使是 SQLServer2005也没有很好地处理像这样的大型 BLOB,而 SQLServer2005是我们尝试使用的最新版本。

具体来说,我们看到了严重的膨胀,我认为可能是锁定问题。

另一个注意事项: 如果您正在使用基于 NTFS 的存储(Windows 服务器等) ,您可能会考虑找到一种方法,将成千上万的文件放在一个目录中。我不知道为什么,但有时文件系统不能很好地处理这种情况。如果有人知道更多,我很乐意听听。

但是我总是尝试使用子目录来打破一些东西,创建日期通常很适合这一点:

图片/2008/12/17/. jpg

... 这提供了一个不错的分离级别,并且在调试期间也有一点帮助。当存在真正巨大的目录时,资源管理器和 FTP 客户端都会有点窒息。

编辑: 2017年的一个简短说明,在最新版本的 SQL Server 中,有一些处理大量 BLOB 的新选项,这些选项应该能够避免我所讨论的缺点。

编辑: 快速说明2020年,AWS/Azure/etc 中的 Blob 存储也是多年来的一种选择。这非常适合许多基于 Web 的项目,因为它成本低廉,而且通常可以简化部署、扩展到多个服务器、必要时调试其他环境等方面的某些问题。

我在我的网站上使用上传的图片,我肯定会说选项 a)。

我强烈推荐的另一件事是立即将文件名从用户给照片命名的名称更改为更易于管理的名称。例如,带有日期和时间以唯一标识每张图片的内容。

它还有助于去除用户的文件名中的任何奇怪字符,以避免将来的复杂情况。

一定要调整图像的大小,如果可以的话,检查一下它的格式。有些恶意文件是由不知情的主机上传和发送的,例如,GIFAR漏洞可以让你在一个 GIF 文件中隐藏一个恶意的 java applet,然后这个 GIF 文件可以在当前上下文中读取 cookies 并将它们发送到另一个网站进行跨网站脚本攻击。调整图像大小通常可以防止这种情况,因为它会删除嵌入的代码。虽然这种攻击已经被 JVM 补丁修复,但是天真地提供二进制文件而不清除它们会使您暴露出一系列漏洞。

请记住,大多数病毒扫描器只能针对文件系统运行——如果您将二进制文件存储在数据库中,则不能很容易地针对它们运行扫描器。

我最近创建了一个 PHP/MySQL 应用程序,它在 MySQL 表中存储 PDF/Word 文件(目前为止每个文件大约有40MB)。

优点:

  • 上传的文件被复制到备份服务器以及其他一切,不需要单独的备份策略(安心)。
  • 设置 Web 服务器稍微简单一些,因为我不需要有一个上传/文件夹,并告诉所有我的应用程序在哪里。
  • 我可以使用事务来进行编辑,以提高数据的完整性——我不必担心孤立的文件和丢失的文件

缺点:

  • Mysqldump 现在需要很长时间,因为其中一个表中有500MB 的文件数据。
  • 总的来说,与文件系统相比,内存/CPU 效率不是很高

我认为我的实现是成功的,它处理了备份需求并简化了项目的布局。对于使用该应用程序的20-30人来说,性能是很好的。

选项 A。

一旦加载了图像,您可以在保存之前验证格式并调整其大小。有一些。在 http://www.codeproject.com上调整图像大小的净代码示例。例如: http://www.codeproject.com/KB/cs/Photo_Resize.aspx

如果它们是不需要编辑的小文件,那么选项 B 不是一个坏选项。我更喜欢这样编写逻辑来存储文件和处理疯狂的目录结构问题。将文件的 很多放在一个目录中是不好的。好吗?

如果文件很大或者需要不断编辑,特别是像 office 这样的程序,那么选项 A 是最好的选择。

对于大多数情况,这是一个优先选择的问题,但如果您选择 A,只要重新使目录中没有太多的文件。如果选择选项 B,那么将带有 BLOBed 数据的表放在其自己的数据库和/或文件组中。这将有助于维护,特别是备份/还原。您的常规数据可能相当小,而您的图像数据随着时间的推移将是 巨大

在 SQLServer2008中有一种称为 文件流数据类型的混合方法,RunAs Radio # 74中提到过这种方法,这种方法有点像是两个世界中最好的方法。大多数人没有2008年的选择,但是如果你有,这个选择看起来很酷

出于安全考虑,最好的做法是避免由 IE 的内容嗅探引起的问题,因为 IE 的内容嗅探允许攻击者在图像文件中上传 JavaScript,这可能会在您的站点上下文中执行。因此,在存储图像之前,您可能需要以某种方式对图像进行转换(裁剪/调整大小) ,以防止此类攻击。这个答案有一些其他的想法。

我有一个类似的项目,用户上传文件到服务器上。在我看来,选项 a)是最好的解决方案,因为它更加灵活。您必须做的是将图像存储在按子目录分类的受保护文件夹中。主目录必须由管理员设置,因为内容必须没有运行脚本(非常重要)和(读、写)保护,不能在 http 请求中访问。

我希望这能帮到你。

选项 B 的唯一好处是在一个系统中拥有所有数据,但这是一个错误的好处!您可能会争辩说,您的代码也是一种数据形式,因此也可以存储在数据库中——您希望如何存储呢?

除非你有特例:

  • 业务逻辑属于代码。
  • 结构化数据属于数据库(关系数据或非关系数据)。
  • 大容量数据属于存储(文件系统或其他)。

Files, Code, Data

没有必要使用文件系统来保存文件。相反,您可以使用云存储(如 亚马逊 S3)或基础设施即服务(如 上传) :

Https://uploadcare.com/upload-api-cloud-storage-and-cdn/

但是在数据库中存储文件是一个坏主意。

基本上就是这样。

  1. 将上载的映像存储在临时目录或内存中。
  2. 在永久存储该图像之前对其进行处理。 2.1色彩校正 2.2压缩 根据图像尺寸创建几个副本 2.4. 使用. xl、 . lg、 . md、 . sm 等后缀重命名
  3. 将所有处理过的图像文件(来自单个文件)打包在一个文件夹中,文件夹名称为 id,它将与 image file name一起存储在数据库中的任何行/文档中(或者可以是随机名称作为图像名称)。
  4. 如果不存在,创建 天啊 path文件夹。例如2016/08/21。记住这个路径,并在数据库中存储相同的文档和行。
  5. 将图像 id文件夹移动到 path文件夹(路径文件夹可能位于/var/web-content 文件夹中)
  6. 刷新内存缓冲区或删除临时文件。

当您需要访问文档中提到的任何图像时,您的文件夹的路径和 ID 比包含图像的文件夹还要多。例如 /var/web-content/\{\{path}}/\{\{id}}/image-file-name.sm.jpg

这样,如果您必须删除所有处理过的图像文件,只需递归删除文件夹和它的内容。

这取决于你的需求,特别是体积,用户和搜索频率。但是,对于小型或中型办公室,最好的选择是使用像苹果照片或 Adobe Lighroom 这样的应用程序。它们专门用于存储、编目、索引和组织这种资源。但是,对于存储要求高、用户数量多的大型组织来说,建议使用数字资产管理(Digital Asset Management)来实例化内容管理平台,比如 Nuxeo 或 Alfresco; 这两个平台都提供了非常好的资源,可以用简化的方法来管理大量的数据。而且,非常重要的是: 这两个平台都有一个免费(开源)选项。

我知道这是一个老职位。但是许多访问这个页面的人没有得到任何与这个问题相关的信息。尤其是对一个新手来说。

如何在本网站上载及储存图像或档案:

对于一个静态网站可能没有问题,因为文件存储为一些共享托管仍然足够。问题来自一个动态网站,当它变得更大。可以处理数据库中较大的内容,但文件中较大的内容(如图像)就成为一个问题。网站上的图片有两种:

  1. 图片来自动态博客的管理员。通常,这些图片在上传之前已经进行了优化。

  2. 来自用户的图像,如用户允许上传图像,如头像。或者用户可以创建博客内容,并从文本编辑器放置一些图像。这种图像的大小很难预测。用户可以通过调整视图大小而不是图像大小来上传大图片。

忽略上面的第一项,如果我们的网站没有图像优化器的功能,第二项的快速解决方案可以通过下面的提示来临时解决:

  1. 不允许用户通过重定向到图像库直接从文本编辑器上传。在此页面上,用户必须提前上传文件,然后才能嵌入到内容中。此方法作为文件管理器调用。

  2. 使用作物图像功能,用户上传图像。这将限制图像大小,甚至用户上传非常大的文件。最终的图像是裁剪图像的结果。我们可以在服务器端定义大小,只接受例如500Kb 或更低。

现在,这只是暂时的。对于最终的解决方案,我们要重复一个问题:

  • 如何处理大图像存储?
  • 调整或更改扩展名。
  • 一个大型或中型网站或电子商务如何处理其图像的文件存储?

我们能做的是:

  1. 从共享主机 VPS 迁移。不够吗? 那么更高的升级到专用。

  2. 为文件存储创建自己的服务器。谷歌一下就知道了。这没有你想的那么难。有些人是为了他们的网站。

  3. 简单的方法是使用 CDN 文件存储服务。

好吧,1和2有点贵,但是我认为不3是最好的解决方案。

一些 CDN 服务允许您存储任意数量的网络文件。

问题,“如何从我们的网站上传文件到 CDN?”

不要担心,一旦你注册,通常是免费的,你会得到指导如何上传文件和获得他们的链接从/到你的网站。你会得到一个 API 和更多。很简单。

一些供应商为我们提供14天的免费服务,但存储空间和带宽有限。但对于起点来说,这是可以接受的。唯一的问题是“人们从不尝试”。

希望对新手有所帮助。