Php 在文件系统与数据库中存储图像的问题

Php 在文件系统与数据库中存储图像的问题,php,mysql,image,blob,Php,Mysql,Image,Blob,关于典型的BLOB与文件系统问题,有几个问题的答案非常好。然而,它们似乎都不代表我的情况,所以我问这个问题 假设有一个社交网络(当然是一个假设的场景),用户都可以自由更改任何人的个人资料图片。每个用户的配置文件存储在MySQL表中,其模式如下: ID [unsigned int, primary] USERNAME [varchar(20)] PROFILENAME [varchar(60)] PROFILEPIC [blob] 现在,问题是:如果我想将配置文件图像作为文件存储在服务器上,而不

关于典型的BLOB与文件系统问题,有几个问题的答案非常好。然而,它们似乎都不代表我的情况,所以我问这个问题

假设有一个社交网络(当然是一个假设的场景),用户都可以自由更改任何人的个人资料图片。每个用户的配置文件存储在MySQL表中,其模式如下:

ID [unsigned int, primary]
USERNAME [varchar(20)]
PROFILENAME [varchar(60)]
PROFILEPIC [blob]

现在,问题是:如果我想将配置文件图像作为文件存储在服务器上,而不是数据库中的blob,该怎么办?我可以理解,必须有某种命名约定,以确保所有文件都有一个唯一的名称,并将其映射到表上的主键,以便于访问。例如,主键是存储在磁盘上的相应映像的文件名。但在我的上下文中,可以同时读/写,而且很多。MySQL通常不会出现任何问题,因为它会在更新行时锁定该行。但是在文件系统模型中如何处理这种情况呢?

在应用程序层,您可以锁定执行DB事务和文件IO的块,以缓解并发问题()

在此块中,在事务中运行插入/更新/删除。然后添加/替换/删除磁盘上的照片。让我们编写一些伪代码:

lock (obj) 
{
    connection.StartTransaction();

    connection.PerformAction();
    if failed, return false;

    photoMgmt.PerformAction();
    if failed, return false;

    connection.CommitTransaction();
}
应用与PHP类似的技术;另外,还可以使用来执行文件锁定

换句话说,在提交到文件系统之后再提交到DB。如果数据库或文件系统操作失败,请执行清理,以便不保存任何更改

我将使用bigint ID作为磁盘上的主键和GUID文件名。如果用户希望应用程序保留他们提供的名称,我将创建一个名为user\u filename的字段来存储用户提供的文件名,并且出于所有其他目的,我将使用GUID


希望这将提供一些方向

我将研究flock()…作为一个PHP noob,从未听说过它,但听起来很有希望。但也有一些问题:除了预期表中的行数最终会超过INT所能限定的行数之外,还有什么特别的原因更喜欢bigin而不是INT?他们说,与INT相比,BIGINT呈现查询和索引的速度较慢。另一个问题是GUID。为什么您更喜欢GUID而不是简单地使用主键作为文件名?只是想更好地理解您。另外,考虑到每个图像文件都将小于20kB,您是否认为消除所有应用程序层开销并将其存储为BLOB有什么好处?BIGINT将有利于大量记录—您说得对。INT是4个字节,BIGINT是8个字节。所以从技术上讲,使用INT会有轻微的速度提升,但我认为不会太快。您可以在测试数据库上运行场景,我相信速度差异可以忽略不计。我将在另一个注释中描述GUID。您可以使用ID或其他主键作为文件名。当不同的团队处理项目时,他们可能会使用不同的表执行相同的操作,现在您的应用程序可能会存储100.jpg,而他们的应用程序可能会尝试存储100.jpg,从而导致您的文件被删除。良好的沟通和架构可以解决这个问题。为了安全起见,我更喜欢GUID。当将文件从一个应用程序/服务器/公司移动到另一个应用程序/服务器/公司时,GUI发生冲突的可能性很低。图像当然可以存储在MySQL中。关于这一点,我们进行了很好的讨论