背景故事
我维护并且正在重新设计几个基于PHP的Web应用程序,有一个主题我还没有找到一个优雅的解决方案,所以我正在寻找一些可能导致我更好的方法。
当前状态
我的一些应用程序允许用户存储除大量数据之外的图像。所有数据最终都在PostgreSQL集群中,但是为了性能和可维护性,我选择不将图像本身存储在数据库中。图像将其元数据存储在数据库中(例如原始文件名,宽度/高度等),一旦数据库事务成功,我将文件系统上的图像移动到图像目录(存储为.jpg)。
问题
所有这些功能都很好,但由于应用程序被大量使用,并且多人同时使用,并且在互联网上,并且PHP的错误/异常处理在所有情况下都不是最可靠的,我偶尔会担心关于无法在数据库事务中包装存储图像(在文件系统上)(因为它发生在文件系统上)。我也很担心,因为如果图像文件在文件系统上被破坏/更改/删除,数据库的记录将无法正确更新(没有参照完整性)。
解
到目前为止,我想出的是:
选项A)将实际图像(不仅仅是元数据,而是整个二进制文件)存储在数据库中。 - 我不喜欢这个,因为目前数据库虽然非常复杂,但仍然非常小(不超过60MB orso)。相关的图像总共有很多GB,所以它会大量增加我的PostgreSQL安装的占用空间。此外,它将使我的数据库备份和复制方案复杂化。
选项B)保持当前设计(文件系统上的图像,postgres中的数据),并尝试在应用程序级别使用它的每个点处计算损坏的数据。 - 它使应用程序更加复杂和错误。
选项C)我找到了一个名为Flourishlib的PHP ORM框架,它包含一个模拟文件系统事务的文件系统类(基本上如果你调用$ file-> rename()它会检查是否可能,但是实际上并没有重命名直到你提交事务) - 这是我到目前为止找到的最好的解决方案,但是我已经使用了另一个ORM框架(Propel),我更喜欢这个大小的项目,所以我会要求2个功能基本重叠的框架。
的sooo
所以,我认为此前很多其他人都会遇到同样的“问题”,我相信有些人想出了一些我还没想过的解决方案。感谢任何指针,建议或批评。
答案 0 :(得分:1)
在我看来,这是两个不同的问题。
第一个:你如何保证整合,你已经以某种方式解决了。我唯一要考虑的是在db和rollback事务期间执行文件系统操作,如果出现问题。这里的交易是性能,因为文件系统操作相当慢但不是那么慢;) 你可以尝试一下......
第二个:如何在外部文件操作后保持完整性。在这里,我建议看一下使用php PHPInotify的inotofy。它允许您实现观察者模式,以便在文件系统发生更改时收到通知。
答案 1 :(得分:0)
您始终可以从Advanced Download page获取蓬勃发展的子集。只需选择fFile,它就会选择依赖项。不幸的是,自动依赖检测随着时间的推移会变得有点不准确(因此它将包含fEmail,它实际上是可选的),但你可以删除它,留下一些文件系统类和一些核心/异常的东西。
答案 2 :(得分:0)
这是我对选项D的建议:
将实际图像及其元数据和哈希值存储在数据库(整个二进制文件)中(请参见What is image hashing used for?)。
构建一个微服务,负责将二进制映像从数据库转换为文件系统或CDN。 通过比较哈希,此微服务可以检查图像完整性。它甚至可以保存先前的版本和日志。交易完成后,可以删除数据库中的二进制数据以保持数据轻量。
设计消息队列体系结构(例如,使用Amazon SQS)以启动和管理此微服务。它会独立于您的主应用程序运行,并准备处理故障,数据库维护,错误等。
希望这会有所帮助,即使8年之后。