【问题标题】:User uploaded files in PHP: Storing in database VS storing in file system用户在 PHP 中上传的文件:存储在数据库中 VS 存储在文件系统中
【发布时间】:2017-01-09 23:26:41
【问题描述】:

我想存储由(可能不受信任的)随机用户上传的文件。我主要关心的是安全性。在我看来,将文件存储在 MySQL 数据库中是最安全的做法,因为如果没有我的脚本将它们从 SQL 数据库中加载出来,它们肯定无法被访问/执行,而这只会对授权用户执行。

但是,我已经阅读了很多关于将文件存储在文件系统中的信息,这将是最好的方法,但大多没有真正的解释。我发现的唯一缺点是性能。它实际上是慢得多还是有其他我不知道的缺点?

【问题讨论】:

    标签: php mysql security file-upload


    【解决方案1】:

    认为数据库本质上比磁盘上的文件更安全是错误的。毕竟,数据库磁盘上的文件。与通过 shell 访问机器相比,侵入 MySQL 服务器通常也容易得多,MySQL 使用密码,如果配置正确,shell 仅使用 SSH 密钥。

    另一个问题是,当您将越来越多的二进制数据加载到数据库中时,正确备份的成本会变得相当高。 MySQL 不能很好地进行差异备份,而磁盘上的文件使用rsync 之类的工具快速有效地复制是微不足道的。

    毫不奇怪,文件系统非常擅长存储大量任意二进制数据。关系数据库不是。此外,为了尽可能高效地从磁盘上提供文件,我们在操作系统层面做了很多工作。

    这是计算机从磁盘获取文件并将其发送到网络所必须执行的操作:

    1. 打开文件。
    2. 进行类似sendfile的系统调用。
    3. 内核处理从磁盘读取、写入网络设备。

    从 MySQL 之类的数据库发送数据需要执行以下操作:

    1. 打开 MySQL 连接并进行身份验证。
    2. 编写类似SELECT file FROM tablename WHERE id=? 的命令
    3. 使用 MySQL 二进制协议对其进行编码,并通过网络连接将其发送到 MySQL 服务器。这可能是本地的或远程的,在远程情况下会涉及更多的开销。
    4. 服务器接收到命令并对其进行解码,首先将命令解包。
    5. 服务器必须解析命令并解释它。
    6. 服务器必须打开有问题的表以及索引文件,在其中查找数据的位置。
    7. 一旦找到,数据必须从 MySQL 行格式解码,然后重新编码为 MySQL 结果格式。
    8. 该数据通过网络传输回客户端。
    9. 客户端必须接收并解码结果集。
    10. 客户端必须提取相关的二进制信息。
    11. 客户端必须将该数据复制到另一个缓冲区以将其发送回网络连接。
    12. 内核需要将该数据从用户空间传输到内核空间并将其提供给网络驱动程序。

    这是相当多的工作,并且由于多次跨越用户空间/内核空间边界而涉及大量强制副本。

    如果您想要文档存储,请查看 Riak 之类的东西,而不是 MySQL 之类的 RDBMS。

    【讨论】:

      【解决方案2】:

      网站运营人员的一般经验是,将上传的文件存储在文件系统上是

      • 更快,并且
      • 更好地扩展

      而不是将它们存储在数据库列中。

      为什么? Web 服务器和 Web 缓存代理服务器旨在将文件从文件系统传递给用户。一个 Web 服务器集群可以非常高效地完成此操作,一台服务器也可以。

      从 dbms 传送文件使其成为瓶颈。您通常有多个 Web 服务器和一个 dbms。另外,BLOB 数据的处理速度比普通数据慢。

      这是一种广泛使用的技术,可以解决安全问题。它们是真正的问题,但已解决。最大的问题是坏人很容易猜测私有文件的路径名。

      【讨论】:

        猜你喜欢
        • 2012-06-26
        • 2011-10-19
        • 1970-01-01
        • 2014-06-22
        • 1970-01-01
        • 2021-05-31
        • 2023-04-04
        • 2021-10-12
        • 2011-01-04
        相关资源
        最近更新 更多