使用SQL数据库跟踪外部文件,并在删除记录时删除外部文件

Dr.*_* II 5 sql postgresql geospatial

我不知道我是不是以正确的方式去做这件事,或者我完全愚蠢地做了些什么.

我有一个文件系统,可以容纳一堆图像文件.这些是可变大小的大型地图图像.我正在使用我的数据库对它们进行空间查询.

基本上我想要做的就是能够将图像的信息(名称,目录和空间信息)添加到数据库并从数据库中删除图像(所有表中的记录以及与该记录关联的外部文件).我知道如何删除所有记录而不删除外部数据.我不想将图像作为二进制blob插入数据库,因为我经常在文件上使用外部工具.

基本上我的数据库只跟踪文件的名称和目录以及与文件关联的空间数据.

从数据库库中删除记录时,如何从文件系统中删除文件?

我甚至正确地解决了这个问题吗?将图像作为二进制blob插入数据库更常见吗?(复制数据的开销使我难以置信,必须有更好的方法.)

我希望它无关紧要,但我在Linux下使用postgre作为我的SQL数据库.

编辑:我目前的策略是使用一个处理图像删除的shell脚本.在shell脚本期间,它使事务文件删除与图像关联的所有数据库记录,同时将文件的完整路径保存为平面文本文件.如果事务成功,我然后删除平面文件中的图像.这是明智的吗?有没有更好的办法?

peu*_*feu 6

很大程度上取决于你想要放置图像的位置.

由于数据库通常需要快速随机IO,因此您需要将其放在带有一些良好电池备份RAID10控制器的盒子上.

但是,服务于数以万计的静态(不经常更新)文件的网络服务器将需要非常不同的硬件,可能是RAID6,或廉价服务器的云.

因此,您必须在设计中考虑到这一点.

1)ON DELETE触发器

您可以让数据库通过ON DELETE触发器删除文件.大问题:如果事务被回滚,文件会被删除!

2)日志表

ON DELETE触发器将删除的图像记录插入日志表中.cron作业读取此内容并稍后删除文件.

==>没有ROLLBACK问题

3)垃圾收集

cron作业比较磁盘上的文件列表和数据库的内容,并删除没有匹配的数据库记录的磁盘文件.

这是安全的,但可能比日志表慢得多!

4)在申请中做到:

  • DELETE RETURNING返回已删除记录的列表COMMIT
  • 从文件系统中删除

失败点:

  • 如果你的应用程序死了,你可能会得到没有数据库记录的文件,或者如果你在unlink()之后放置COMMIT则会更糟糕.
  • 同样的事情适用于INSERT ...
  • 如果应用程序以外的某些内容从数据库中删除,则不会处理.


mu *_*ort 2

您的“当前策略”听起来像是我的标准方法:从数据库中删除,如果成功(这是一个很大的“如果”),则删除相应的图像文件。您可能需要一个健全性检查器来确保您没有积累垃圾,只是对数据库和文件系统进行简单比较以确保它们彼此一致。

您不需要将图像存储在数据库中,文件系统非常擅长处理文件,并且将它们放在文件系统中可能会方便得多。而且,正如下面 David Ryder 所指出的,文件系统在处理大型图像文件时几乎肯定会比数据库更快:文件系统非常擅长处理文件,这就是它们的作用。


更新:如果您需要非常快,那么您可以尝试使用 cron 作业删除文件。每隔几个小时(或一天或任何有效的时间),一个 cron 作业可以将数据库与文件系统进行比较并删除任何杂散图像。这将使从数据库中进行大规模删除变得更容易:您可以执行 aDELETE FROM whatever WHERE ...来删除多个条目,然后您的管理员稍后会来清理剩余的图像。