用户在PHP上传文件:存储在数据库VS存储在文件系统中

时间:2017-01-09 23:26:42

标签: php mysql security file-upload

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

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

2 个答案:

答案 0 :(得分:2)

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

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

文件系统毫不奇怪,非常擅长存储大量任意二进制数据。关系数据库不是。此外,在操作系统级别已经完成了大量工作,以尽可能高效地从磁盘上提供服务文件。

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

  1. 打开文件。
  2. 进行类似sendfile的系统调用。
  3. 内核处理从磁盘读取,写入网络设备。
  4. 以下是从MySQL等数据库发送它所需要做的事情:

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

      如果您需要文档存储,请查看类似Riak的内容,而不是像MySQL这样的RDBMS。

答案 1 :(得分:1)

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

  • 更快,
  • 更好地扩展

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

为什么呢? Web服务器和Web缓存代理服务器旨在从文件系统向用户提供文件。一组Web服务器可以非常有效地完成此任务,就像一台服务器一样。

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

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