什么是存储上传的图像,SQL数据库或磁盘文件系统的最佳地点?
我正在编写一个允许用户将图像上传到服务器上的应用程序。 我期望每天大约20个图像所有jpeg,可能不会被编辑/resize。 (这是另一个问题,如何在存储之前调整服务器端的图像大小,也许有人可以在注释中放一个.NET资源)。 我想知道什么是存储上传图像的最佳地点。
-
将图像作为文件存储在文件系统中,并在表格中创build具有该图像的确切path的logging。
-
或者,使用数据库服务器的“图像”或“二进制数据”数据types将图像本身存储在表格中。
我看到两者的优点和缺点。 我喜欢a),因为我可以轻松地重定位文件,只需更改表条目。 另一方面,我不喜欢在Web服务器上存储业务数据,我不想将Web服务器连接到任何其他持有业务数据的数据源(出于安全原因),我喜欢b),因为所有的信息是在一个地方,并通过查询很容易访问。 另一方面,数据库很快就会变得很大。 外包数据可能会更困难。
我通常将文件存储在文件系统上,因为这就是它的目的,尽pipe也有例外。 对于文件,文件系统是最灵活和最高效的解决scheme(通常)。
将文件存储在数据库中有几个问题 – 文件通常比平均行大得多 – 包含许多大文件的结果集将消耗大量内存。 此外,如果您使用使用表锁进行写入的存储引擎(例如ISAM),那么您的文件表可能经常被locking,具体取决于您在那里存储的文件的大小/速率。
关于安全性 – 我通常将文件存储在文档根目录之外的目录(不能通过http请求访问),并通过脚本来提供这些文件,以便首先检查适当的授权。
选项B的唯一好处是在一个系统中拥有所有的数据,但这是一个虚假的好处! 你可能会争辩说,你的代码也是一种数据forms,因此也可以存储在数据库中 – 你想怎么样?
除非你有一些独特的情况:
- 业务逻辑属于代码。
- 结构化数据属于数据库(关系或非关系)。
- 批量数据属于存储(文件系统或其他)。
没有必要使用文件系统来保存文件。 相反,您可以使用云存储(如Amazon S3 )或基础架构即服务(如Uploadcare ):
https://uploadcare.com/upload-api-cloud-storage-and-cdn/
但是将文件存储在数据库中是一个坏主意。
Flickr使用文件系统 – 他们在这里讨论原因
我们在几个不同的后端有几次客户坚持选项B(数据库存储),我们总是最终回到选项A(文件系统存储)。
像这样的大型BLOB,即使是SQL Server 2005,也是我们尝试过的最新的。
具体来说,我们看到严重的膨胀,我想也许locking问题。
另外一个注意事项:如果你使用基于NTFS的存储(Windows服务器等),你可能会考虑find一种方法将成千上万的文件放在一个目录中。 我不知道为什么,但是有时文件系统不能很好地处理这种情况。 如果有人对此有更多的了解,我很乐意听到。
但是我总是试图使用子目录来分解一些东西。 创builddate通常适用于此:
图片/ 2008/12/17 / .JPG
…这提供了一个体面的分离水平,也有助于debugging。 资源pipe理器和FTP客户端都可以在有真正庞大的目录时憋一会儿。
编辑:只是在2017年的更快的说明,在最新版本的SQL Server,有处理大量的应该避免我讨论的缺点的BLOB的新选项。
我最近创build了一个将PDF / Word文件存储在MySQL表中的PHP / MySQL应用程序(到目前为止,每个文件大小为40MB)。
优点:
- 上传的文件与其他所有内容一起复制到备份服务器,不需要单独的备份策略(安心)。
- 设置Web服务器稍微简单一点,因为我不需要上传/文件夹,并告诉我的所有应用程序它在哪里。
- 我可以使用事务进行编辑,以提高数据的完整性 – 我不必担心孤立和丢失的文件
缺点:
- mysqldump现在需要一个looooong时间,因为其中一个表中有500MB的文件数据。
- 与文件系统相比,整体来说内存/ CPU效率不高
我会叫我的实现成功,它会照顾备份需求并简化项目的布局。 对于使用该应用程序的20-30人来说,performance还不错。
我使用上传的图片在我的网站上,我一定会说选项a)。
我强烈推荐的另一件事是立即将用户命名照片的文件名更改为更易于pipe理的内容。 例如用date和时间来唯一标识每张照片。
它也有助于去除任何陌生人物的用户文件名,以避免将来的复杂化。
绝对调整图像大小,如果可以的话,检查它的格式。 有一些恶意文件被不知情的主机上传和处理,例如, GIFAR漏洞可以让你隐藏一个恶意的Java小程序到一个GIF文件中,然后这个小程序就可以读取当前上下文中的cookies并发送给另一个网站的跨站点脚本攻击。 调整图像大小通常可以防止这种情况,因为它通过embedded的代码。 虽然这个攻击已经被JVM补丁所修复,但是天真地提供二进制文件而不去清理它们会导致一系列的漏洞。
请记住,大多数病毒扫描程序只能运行在文件系统上 – 如果将二进制文件存储在数据库中,则无法轻松地运行扫描程序。
大多数实现是选项A.
使用选项B,当您将数据库中的那些位封装到可以在浏览器中显示的内容时,您将打开一个完整的whoop4ssjar。另外,如果数据库closures,图像将不可用。
我认为这个空间不是太大的问题,现在Terabyte驱动器是几百美元。
我们正在执行选项A,因为我们没有时间或资源做选项B.
在SQL Server 2008中有一种混合的方法,叫做在第74号RunAs广播中讨论过的文件stream数据types ,就好像两全其美。 大多数人没有2008年的情绪,但如果你这样做,这个选项看起来很酷
我们使用A.我会把它放在一个共享的驱动器(除非你不打算运行多个服务器)。
如果时间到了,这将不会为您调整,那么您可以调查caching机制。
绝对的,积极的selectA.其他人已经提到,数据库通常不能很好地处理BLOB,无论它们是否被devise成这样做。 另一方面,文件系统就是为了这个东西而生存的。 您可以select使用RAID条带,在多个驱动器之间传播映像,甚至将其分散到不同地理位置的服务器上。
另一个好处是你的数据库备份/复制将是可怕的。
对于自动resize,请尝试imagemagick …它被用于许多主要的开源内容/照片pipe理系统…我相信有一些.NET的扩展。
选项A.
加载图像后,您可以validation格式并在保存之前调整其大小。 有许多.Net代码示例可以调整http://www.codeproject.com上的图像大小。; 例如: http : //www.codeproject.com/KB/cs/Photo_Resize.aspx
出于安全原因,最好避免IE浏览器内容嗅探造成的问题,这可能会导致攻击者上传JavaScript内部的图像文件,这些文件可能会在网站上下文中执行。 所以你可能想要在变换图像(裁剪/调整它们)之前以某种方式存储它们,以防止这种攻击。 这个答案有一些其他的想法。
那么,我有一个类似的项目,用户上传文件到服务器上。 在我看来,选项a)是最好的解决scheme,因为它更加灵活。 你必须做的是将图像存储在由子目录分类的受保护的文件夹中。 主目录必须由pipe理员设置,因为内容不能在http请求中被访问,因此不能运行脚本(非常重要)和(读取,写入)。
我希望这可以帮助你。
这基本上是我做的。
- 将上传的图像存储在临时目录或内存中。
- 在永久存储图像之前处理该图像。 2.1。 颜色校正2.2。 压缩2.3。 根据图像尺寸创build多个副本2.4。 用.xl,.lg,.md,.sm等后缀重命名
- 将所有处理的图像文件(来自单个文件)打包在文件夹名称为
id
的文件夹中,将其存储在任何行/文档的数据库中以及image file name
(或者可以是随机名称作为图像名称)。 - 如果不存在,创buildyyyy / mm / d
path
文件夹。 例如2016/08/21。 记住path,并将数据库存储在相同的文档和行中。 - 将图像
id
文件夹移动到path
文件夹。 (path文件夹可能位于/ var / web-content文件夹中。) - 刷新内存缓冲区或删除临时文件。
当您需要访问文档中提到的任何图像时,您的文件夹的path和ID不包含图像。 例如/var/web-content/{{path}}/{{id}}/image-file-name.sm.jpg
这样,如果您必须删除所有处理的图像文件,只需删除该文件夹,它的内容recursion。
我知道这是一个老post。 但是很多访问者对这个问题没有任何关联。 特别是对于新手。
如何上传和存储图片或文件在我们的网站。
对于一个静态的网站,也许没有问题,因为一些共享主机的文件存储还是足够的。 问题来自dynamic网站时变大。 数据库可以处理得越大,但是图像等文件中的数据就越大。 网站上有两种types的图片:
-
图片来自dynamic博客的pipe理员。 通常,这个图像在上传之前已经被优化了,当然。
-
允许用户的图像在用户的情况下上传图像,如头像。 或者用户可以创build博客内容,并从文本编辑器中放置一些图像。 这种图像很难预测大小。 用户可以通过调整视图大小来调整小图片大小,但不能调整图片大小。
通过忽略上面的第1项,如果我们的网站没有图像优化function,可以通过以下提示临时解决第2项的快速解决scheme:
-
不要让用户直接从文本编辑器上传,通过redirect到图片库。 在这个页面上,用户必须提前上传文件,然后才能embedded到内容中。 这种方法被称为文件pipe理器。
-
为用户使用裁剪图像function来上传图像。 这将限制用户上传非常大的文件的图像大小。 最终的图像是裁剪图像的结果。 我们可以在服务器端定义大小,只接受例如500Kb或更低。
现在,这只是暂时的。 为了最终的解决scheme,问题是重复的:
- 如何处理一个大的图像存储?
- resize或更改扩展名。
- 大中型网站或电子商务如何处理他们的图像的文件存储?
那么我们可以做什么:
-
从共享主机VPS迁移。 不够? 然后升级到专用更高。
-
创build自己的文件存储服务器。 谷歌search做到这一点。 这并不像你想象的那么困难。 有些人为他们的网站做。
-
简单的方法是使用CDN文件存储服务。
好吧,1和2有点贵。 但没有3我认为是最好的解决scheme。
一些CDN服务允许你存储你的网页文件,只要你想要的。 问题,如何从我们的网站上传文件到CDN?
不要担心,一旦你注册,通常是免费的,你会得到指导如何上传文件,并从您的网站链接。 你会得到一个API和更多。 这很容易。
一些提供商为我们提供14天的免费服务,存储和带宽有限。 但是,这将是起点好。 唯一的问题是因为“人们从不尝试”。
希望它会帮助新手。
如果它们是不需要编辑的小文件,则选项B不是一个错误的选项。 我更喜欢编写逻辑来存储文件,并处理疯狂的目录结构问题。 在一个目录中有很多文件是不好的。 EMKAY?
如果文件很大或需要不断编辑,尤其是来自办公室等程序,那么选项A是最好的select。
对于大多数情况下,这是一个优先事项,但如果你去选项A,只要重新目录没有太多的文件在其中。 如果select选项B,则使带BLOBed数据的表位于其自己的数据库和/或文件组中。 这将有助于维护,特别是备份/恢复。 您的常规数据可能相当小,而随着时间的推移,您的图像数据将会非常庞大 。
这取决于你的要求,特别是音量,用户和search频率。 但是,对于中小型办公室来说,最好的select是使用Apple Photos或Adobe Lighroom等应用程序。 他们专门存储,编目,索引和组织这种资源。 但是,对于大型企业来说,由于存储需求强大,用户数量大,build议使用Nuxeo,Alfresco等数字资产pipe理实例化内容pipe理平台, 都提供了非常好的资源pipe理大量的数据和简化的方法来检索它们。 而且,非常重要的是:这两个平台都有一个免费(开源)选项。