14

关于大型项目中的文件管理和存储,这里有一些非常好的问题。

在 DB 中存储图像 - 是还是不是?
您会将二进制数据存储在数据库中还是文件系统中?

第一个有一些深刻的见解,在我的项目中,我决定走文件路线而不是数据库路线。

反对使用文件系统的一个要点是备份。但是在我们的系统中,我们有一个很棒的备份方案,所以我并不担心。

下一个路径是如何存储实际文件。而且我考虑过让文件的位置始终保持静态,并在数据库方面创建一个虚拟目录系统。所以文件的链接不会改变。

我正在构建的系统将具有一个全局文件管理,因此所有用户都可以访问所有文件。但是许多走文件路线的人谈论物理目录大小(例如,如果所有文件都在一个目录中)

所以我的问题是,在为这些静态文件创建文件夹时有哪些技巧或最佳实践方法,或者我根本不应该走虚拟目录路线。

(如果有帮助的话,该项目位于 LAMP 堆栈(PHP)上)

4

6 回答 6

12

一种方法是为每个文件分配一个唯一编号并使用它来查找实际文件位置。然后,您可以使用该编号将文件分发到文件系统中的不同目录中。例如,您可以使用类似这样的方案:

/images/{0}/{1}/{2}

{0}: file_number % 100
{1}: (file_number / 100) % 100
{2}: file_number

于 2009-03-22T16:49:11.207 回答
9

前段时间,我在一个托管大量文件的网站上遇到了这个问题。我们所做的是获取一个 GUID(这也是文件的主键字段)(例如 BCC46E3F-2F7A-42b1-92CE-DBD6EC6D6301)并存储如下文件:/B/C/C/BCC46E3F-2F7A-42b1 -92CE-DBD6EC6D6301/文件名.ext

这有一定的优势:

  • 您可以在多个服务器上扩展文件服务器(并为每个服务器分配特定目录)
  • 您不必重命名文件
  • 您的目录保证是唯一的

希望这可以帮助!

于 2009-03-22T17:47:48.520 回答
8

为了避免在单个目录中创建过多的条目,您可能希望基于文件名的片段创建目录。例如,如果您有一个名为 d7f5ae9​​b7c5a.png 的文件,您可能希望将其存储在 media/d7/f5/d7f5ae9​​b7c5a.png 中。如果您的文件名都是十六进制的,那么这会将单个目录中的条目数限制为 256,直到最后一级。

于 2009-03-22T16:50:42.043 回答
3

关于apache和PHP如何管理文件我不能说太多,但是关于ext3文件系统我可以说一些。ext3 在同一目录下的大量文件似乎没有问题。我已经用多达一百万个文件对其进行了测试。在创建目录之前,确保在文件系统上启用了 dir_index 选项。您可以通过运行 dump2fs 进行检查,并通过运行 tune2fs 更改此选项。将文件散列到子目录树中仍然很有用,因为命令行工具在列出目录内容时仍然存在问题。

于 2009-03-22T18:08:25.150 回答
2
  1. 一个用户图像 ~ 100kb,所以让数据库中有 10 000 个用户,每个用户平均有 5 个图像,所以我们将有 5 TB 的 DB,每个图像输出将通过一个 DB 执行,这个额外的 DB 流量将减少一般数据库服务器性能。...您可以使用数据库集群来避免这种情况,但假设它很昂贵

  2. 用户报告关于实时数据库的错误,(在测试中 - 一切正常),您将如何在开发人员机器上创建转储并解压它?需要多少时间?

  3. 在某一时刻,您可以决定将图像放在某个 CDN 上,您的源代码会发生什么变化?

于 2009-03-22T17:02:16.243 回答
1

我通常采用这种方法:

为您的应用程序提供一个全局设置变量,该变量指向您存储上传文件的文件夹。在您的数据库中存储文件的相对路径(相对于设置变量指向的内容)。

因此,如果文件位于 /www/uploads/image.jpg,则您的设置变量指向 /www/uploads,您的数据库行包含 image.jpg。这是一种将系统目录结构与应用程序分离的灵活方式。

此外,您可以根据与这些相关的数据库表对目录中的文件存储进行分段。假设您有一个表 user_reports 和一个表 user_photos。您将与 user_reports 相关的文件存储在 /www/uploads/user_reports 中。如果您有大量用户上传,您可以进一步实现碎片化。假设用户在 2009 年 3 月 20 日上传了一个文件,该文件名为 report.pdf,因此您将其存储在 /www/uploads/user_reports/2009/03/20/report.pdf 中。

于 2009-03-22T16:51:29.047 回答