平面文件数据库有什么好处吗?[已关闭]

2022-09-05 00:21:58

需要有关平面文件数据库优点的知情选项。我正在考虑使用平面文件数据库方案来管理自定义博客的数据。它将部署在Linux操作系统变体上,并用Java编写。

关于阅读和撰写文章和评论的表现,可能的负面或积极因素是什么?

如果文章检索被斜线点缀,它会因为它是一个平面文件而不是RDBMS吗?(一厢情愿)

我不反对使用RDBMS,只是询问社区他们对这种软件架构方案可行性的看法。

跟进:在这个问题的情况下,我会看到“平面文件==基于文件系统”例如,每个博客条目及其随附的元数据都将在单个文件中。制作许多按文件夹的日期结构组织的文件 (blogs\testblog2\2008\12\01) == 12/01/2008


答案 1

平面文件数据库有它们的位置,并且对于正确的域非常可行。

过去的邮件服务器和NNTP服务器确实突破了你真正能把这些东西带走多远的极限(这实际上已经很远了 - 文件系统可以有数百万个文件和目录)。

平面文件数据库最大的两个弱点是索引和原子更新,但如果域合适,这些可能不是问题。

但是,例如,通过适当的锁定,您可以使用基本的文件系统命令进行“原子”索引更新,至少在Unix上是这样。

一个简单的情况是让索引过程在数据中运行,以临时名称创建新的索引文件。然后,当你完成后,你只需重命名(系统调用 rename(2)或shell mv命令)旧文件而不是新文件。重命名和mv是Unix系统上的原子操作(即它要么有效,要么不起作用,并且永远不会缺少“在状态之间”)。

与创建新条目相同。基本上,将文件完全写入临时文件,然后将其重命名或mv到其最终位置。那么你永远不会在“DB”中有一个“中间”文件。否则,您可能有一个争用条件(例如,一个进程读取仍在写入的文件,并且可能在写入进程完成之前到达结束状态 - 丑陋的争用条件)。

如果您的主索引与目录名称配合良好,那么这就可以正常工作。例如,您可以使用哈希方案创建目录和子目录来查找新文件。

使用文件名和目录结构查找文件非常快,因为现在大多数文件系统都为其目录编制索引。

如果您要将一百万个文件放在一个目录中,那么很可能存在您想要查看的调整问题,但是从这个盒子中可以看出,大多数文件可以轻松处理10个。请记住,如果您需要扫描目录,将会有很多文件要扫描。通过目录进行分区有助于防止这种情况。

但这一切都取决于您的索引和搜索技术。

实际上,提供静态内容的现成 Web 服务器是一个大型平面文件数据库,并且该模型运行良好。

最后,当然,你有大量免费的Unix文件系统级工具可供你使用,但是所有这些工具都有无数文件的问题(分叉grep 1000000次以在文件中找到某些内容将有性能权衡 - 开销只是加起来)。

如果您的所有文件都位于同一文件系统上,那么硬链接也会为您提供将同一文件放在不同位置(基本上用于索引)的选项(因为它们也是原子的)。

例如,您可以有一个“今天”目录、一个“昨天”目录、一个“java”目录和实际的消息目录。

因此,一个帖子可以链接到“today”目录,“java”目录(因为帖子被标记为“java”),以及它的最终位置(比如/articles/2008/12/01/my_java_post.txt)。然后,在午夜,您运行两个进程。第一个获取“today”目录中的所有文件,检查它们的创建日期以确保它们不是“今天”(因为该过程可能需要几秒钟,并且新文件可能会潜入),并将这些文件重命名为“昨天”。接下来,您对“昨天”目录执行相同的操作,只是在这里,如果它们已过期,只需将其删除即可。

同时,该文件仍在“java”和“.../12/01”目录中。由于您使用的是Unix文件系统和硬链接,因此“file”只存在一次,这些都只是指向该文件的指针。它们都不是“文件”,它们都是一样的。

您可以看到,虽然每个单独的文件移动都是原子的,但批量不是。例如,当“today”脚本正在运行时,“yesterday”目录可以很好地包含来自“昨天”和“前一天”的文件,因为“昨天”脚本尚未运行。

在事务性数据库中,您可以同时完成所有操作。

但是,简单地说,这是一种经过验证的真实方法。特别是Unix,它与这个习语配合得很好,现代文件系统也可以很好地支持它。


答案 2

答案从这里复制和修改)

我建议不要将平面文件用于只读访问以外的任何内容,因为这样您就必须处理并发问题,例如确保一次只有一个进程写入文件。相反,我推荐SQLite,一个功能齐全的SQL数据库,存储在文件中。SQLite已经内置了并发功能,因此您不必担心文件锁定之类的事情,而且读取速度非常快。

但是,如果您正在执行大量数据库更改,则最好在事务中一次完成所有更改。这只会将更改写入文件一次,而不是每次发出更改查询时。这大大提高了进行多次更改的速度。

发出更改查询时,无论它是否在传输中,整个数据库都将被锁定,直到该查询完成。这意味着非常大的事务可能会对其他进程的性能产生负面影响,因为它们必须等待事务完成才能访问数据库。在实践中,我没有发现这是显而易见的,但是尝试最小化您发出的数据库修改查询的数量总是很好的做法,而且肯定比尝试使用平面文件更快。


推荐