我已经在PHP中构建了一个小型Web应用程序,用户必须首先登录。一旦登录,我打算在他们的“个人资料”中显示一个小缩略图。
我必须确保图像低于特定尺寸以节省空间,或确保它是特定分辨率,或两者兼而有之,或者甚至可能使用像magick这样的尺寸来缩小它。
不知道最好的方法是什么,欢迎任何想法。
此外,我一直试图解决是否最好将图像存储在MySQL的users
表中作为blob,或者可能是具有唯一ID的单独images
表,以及只需将相应的图像ID存储在users
表中,或者只是将上传的文件保存在服务器上(也可以通过上传页面)并将文件保存为theUsersUniqueUsername.jpg
。
最佳选择?
我在这里找到了一个关于将图像保存到mysql的教程: http://www.phpriot.com/articles/images-in-mysql
我只是一个业余爱好程序员,之前从未做过这样的事情,所以非常感谢示例和/或很多细节。
答案 0 :(得分:40)
总是依赖于上下文,但通常,我将文件系统上的用户图像存储在名为/content/user/{user_id}.jpg
的文件夹中,并尝试尽可能少地打扰数据库。
答案 1 :(得分:23)
我建议将图像存储为文件,然后在数据库中包含文件URI。如果将所有图像存储在数据库中,则可能会在以后进行缩放时遇到一些问题。
同时查看this answer:
对于速度和大小,Microsoft对SQL Server的建议曾经是将数据存储在文件系统中,并在数据库中包含链接。我认为他们已经稍微软化了他们的偏好,但我仍然认为这对于大小来说肯定是个更好的主意,因为它不会占用数据库中的空间。
答案 2 :(得分:17)
使用BLOB的开销远远低于大多数人认为的开销,特别是如果你设置正确的话。如果您使用单独的服务器运行数据库来存储二进制文件,那么您实际上根本不使用文件系统并避免文件系统的任何开销
除非你自己拥有几台服务器,否则说最简单/最好的方法是将它们存储在文件系统中
不要将文件的绝对URL存储在数据库中,只能存储唯一的部分(可能还有一两个文件夹),例如: 2009/uniqueImageName.jpg
或uniqueImageName.jpg
。
然后在您的页面中只需将主机和其他文件夹添加到前面,这样您就可以灵活地移动图像 - 所有您需要更改的内容都是PHP / ASP.NET页面中的一行或两行。
没有必要在文档根目录外存储以确保安全性 - 带有DENY FROM ALL的.htaccess
文件将起作用并提供更大的灵活性
为了安全起见,不需要“分流”图像,只需要getImage.php
页面或其他内容,然后不要在src
image
中插入实际网址使用getImage.php?file=uniqueImageName.jpg
之类的东西。
然后getImage.php
文件可以检查用户是否已获得授权并抓取图像(或不是)。
在存储时使用保证唯一的名称(最好是整数即主键),某些文件系统(即Windows)不区分大小写,因此JoeBloggs.jpg
和{{1}对于数据库是唯一的,但对于文件系统则不是,因此会覆盖另一个。
为图像使用单独的表,并将图像的主键存储在users表中。如果您想要在未来添加更多字段或进行更改,那将更容易 - 这也是一种很好的做法。
如果您担心搜索引擎优化等问题,请在上传时将图像的原始文件名存储在其他字段中,然后您可以在输出中使用它(例如joebloggs.jpg
标记)。 / p>
答案 3 :(得分:16)
当然它依赖于上下文,但是我有一个非常大的应用程序,在MySQL数据库中存储了数千个图像和文档作为BLOBS(平均大小= 2MB),并且应用程序在具有256MB内存的服务器上运行良好。秘诀是正确的数据库结构。始终保留两个单独的表,其中一个表存储有关文件的基本信息,另一个表应该只包含blob以及用于访问它的主键。所有基本查询都将针对详细信息表运行,而另一个表仅在实际需要文件时访问,并且使用索引键访问它,因此性能非常好。
在数据库中存储文件的优点是多方面的:
如果性能是一个大问题而安全和备份不是(或者如果你有一个好的fs备份系统),那么你可以将它存储在FS中,但即使这样我经常存储文件(如果是图像)在DB中并构建一个缓存脚本,在第一次使用它之后将其写入缓存文件夹(是的,这会占用更多的HD空间,但这几乎不是限制因素)。
无论如何,很明显FS在很多情况下运行良好,但我个人认为数据库管理更容易,更灵活,如果写得好,性能损失也非常小。
答案 4 :(得分:10)
我们创建了一个在DB中存储图像的商店。它在开发过程中运行良好,但是一旦我们在生产服务器上测试它,页面加载时间就太高了,它给数据库服务器增加了不必要的负载。
虽然将二进制文件存储在数据库中似乎很有吸引力,但获取和操作它们会增加额外的复杂性,只需将文件保留在文件系统上并在数据库中存储路径/元数据即可避免这种复杂性。
这是永恒的辩论之一,双方都有很好的论据,但是为了我的钱,我会把图像远离数据库。
答案 5 :(得分:9)
我最近看到了这个提示列表:http://www.ajaxline.com/32-tips-to-speed-up-your-mysql-queries
提示17: 对于Web应用程序,图像和其他二进制资产通常应存储为文件。也就是说,只存储对文件的引用而不是数据库中的文件本身。
所以只需将文件路径保存到图像:)
答案 6 :(得分:6)
我在以前的项目中实现了两种解决方案(文件系统和数据库持久化映像)。在我看来,您应该将图像存储在数据库中。原因如下:
无论如何,我的两分钱。
答案 7 :(得分:4)
答案 8 :(得分:2)
我认为大多数数据库引擎已经非常先进,因此存储BLOB的数据不会产生任何缺点(膨胀的数据库等)。一个优点是,当图像已经存在于数据库中时,您没有任何断开的链接。话虽如此,我总是这样做,以便将文件存储在磁盘上并将URI提供给数据库。这取决于用途。如果页面非常动态并经常更改,则可能更容易处理img-in-db - 没有名称空间 - 问题。我不得不说它最终归结为你喜欢的东西。
答案 9 :(得分:2)
我建议您不要将图像存储在数据库中。相反,由于每个用户都将在数据库中拥有与他/她的配置文件关联的唯一ID,因此请使用该ID在服务器上物理存储图像。
e.g。如果用户的ID为23,则可以在www.yourname.com/users/profile_images/23.jpg中存储图像。然后要显示,您可以检查图像是否存在,并相应地显示它,否则显示您的通用图标。
答案 10 :(得分:2)
正如其他人所说:
为什么?
数据库越大,获得的速度越慢。 将映像存储在数据库中会增加数据库大小。 存储文件名将增加数据库大小。
将静态数据放在不同的服务器上(别名):
答案 11 :(得分:1)
经过几天的研究,我制作了一个在数据库中存储图像和二进制文件的系统。
真是太好了。我现在100%控制文件,如访问控制,图像大小调整(当然,我不动态缩放图像),统计,备份和维护。
在我的速度测试中,系统现在慢了10倍。但是,它仍未投入生产,我将实现系统缓存和其他优化。
使用MVC在SHARED主机上检查仍在开发中的这个真实示例: http://www.gt8.com.br/salaodocalcado/calcados/meia-pata/
在此示例中,如果用户已登录,则他可以看到不同的图像。所有产品图像和其他二进制文件都在DB中,而不是缓存,而不是FS。
我在专用服务器上进行了一些测试,结果远远超出预期。
因此,在我个人看来,尽管需要付出巨大努力来实现它,但是将数据存储在数据库中是值得的,并且其益处更有价值。
答案 12 :(得分:0)
正如其他人告诉你的那样,永远不要将图像存储在数据库中。 文件系统用于存储文件 - >图像是文件 - >将它们存储在文件系统中: - )
答案 13 :(得分:0)
刚刚测试了我的img's blob,所以。此解决方案比服务器上的图像工作速度慢。加载时间应与来自DB或http的图像相同,但不是。为什么?我敢肯定,当图像是服务器上的文件时,浏览器可以缓存它并且只加载一次,第一次。当图像从DB格式化时,每次都会再次加载。那是我的意见。也许我错误的浏览器缓存,但工作较慢(blob)。不管怎样,我的英语不好; P
答案 14 :(得分:0)
这两种解决方案的优点
在BLOBS中:
1)优点:易于管理群集,因为您不必处理服务器之间的文件同步等棘手问题
2)数据库备份也将是详尽无遗的
在档案中
1)原生缓存手工(这是以前注释的缺失点,刷新和标题,您不必在DB中重新设计(默认情况下DB不处理上次修改时间)
2)以后轻松调整大小
3)审核的简便性(只需检查文件夹是否正确)
由于所有这些原因,由于数据库的两个专业人员更容易在文件系统上复制,我强烈推荐文件!
答案 15 :(得分:0)
就我而言,我将文件存储在文件系统中。在我的images文件夹中,我根据item id(来自db的行)为每个项目创建新文件夹。并按照从0开始的顺序命名图像。所以,如果我有一个名为Items的表,那么:
Items
|-----|------|-----|
| ID | Name | Date|
|-----|------|-----|
| 29 | Test1| 2014|
|-----|------|-----|
| 30 | Test2| 2015|
|-----|------|-----|
| 31 | Test3| 2016|
|-----|------|-----|
我的images目录看起来像:
images/
29/
30/
31/
images/29/0.png
images/29/1.jpeg
images/29/2.gif
等