【问题标题】:Are flat file databases any good? [closed]平面文件数据库好用吗? [关闭]
【发布时间】:2010-09-24 20:56:55
【问题描述】:

需要了解平面文件数据库优点的选项。我正在考虑使用平面文件数据库方案来管理自定义博客的数据。它将部署在 Linux OS 变体上并用 Java 编写。

对于文章和 cmets 的读写性能,可能有哪些负面或正面的影响?

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

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

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

【问题讨论】:

  • 请阐明您对“平面文件”和“基于文件系统”数据库之间区别的理解。否则无法回答问题。
  • 很好,在这个问题的情况下,我会看到“平面文件 == 基于文件系统”例如,每个博客条目及其随附的元数据都将位于一个文件中。制作按文件夹的日期结构组织的许多文件 (blogs\testblog2\2008\12\01) == 12/01/2008

标签: java database linux architecture


【解决方案1】:

平面文件数据库占有一席之地,并且非常适用于正确的域。

过去的邮件服务器和 NNTP 服务器确实将这些东西的实际应用范围推到了极限(实际上已经很远了——文件系统可以拥有数百万个文件和目录)。

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

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

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

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

如果您的主索引与目录名称配合得很好,那么就可以了。例如,您可以使用散列方案创建目录和子目录来定位新文件。

使用文件名和目录结构查找文件非常快,因为当今大多数文件系统都会索引它们的目录。

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

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

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

最后,当然,您可以使用大量免费的 Unix 文件系统级工具,但它们都存在与数以千计的文件有关的问题(将 grep 分叉 1000000 次以在文件中查找内容会产生性能折衷——开销只是加起来)。

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

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

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

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

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

在事务型数据库中,您可以一次性完成所有操作。

但是,简单地说,这是一种久经考验的真实方法。尤其是 Unix,可以很好地使用该习惯用法,并且现代文件系统也可以很好地支持它。

【讨论】:

  • 您的帖子强调了使用内置并发的 SQLite 之类的东西的必要性——如果我没有必要,我不想处理这些问题。
【解决方案2】:

(从here复制和修改答案)

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

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

发出更改查询时,无论是否在事务中,整个数据库都会被锁定,直到该查询完成。这意味着非常大的事务可能会对其他进程的性能产生不利影响,因为它们必须等待事务完成才能访问数据库。在实践中,我并没有发现这很明显,但尽量减少您发出的数据库修改查询的数量始终是一个好习惯,而且肯定比尝试使用平面文件更快。

【讨论】:

  • 我了解到 Java 人员更喜欢 HSQLDB 而不是 SQLite(我不知道为什么)。就像指向 OP 的指针一样。
  • 现在据说H2比HSQLDB好。
【解决方案3】:

这已经用 asp.net 和 Dasblog 完成了。它使用基于文件的存储。

这个旧链接上列出了一些详细信息。 http://www.hanselman.com/blog/UpcomingDasBlog19.aspx

您还可以通过http://dasblog.info/Features.aspx获取更多详细信息

我听到了一些关于表演的不同意见。我建议你多研究一下,看看这种类型的系统是否适合你。这是我所听到的最接近的事情。

【讨论】:

  • 这是基于文件的(或更准确地说,基于目录),而不是单个平面文件(例如 /etc/passwd)。基于文件系统的数据库(即按目录层次结构组织)可能是可行的。不过,我还是更喜欢 DB。
【解决方案4】:

用本机代码编写自己的引擎可以胜过通用数据库。

但是,引擎的质量和功能级别永远不会接近这一点。数据库为您提供的所有核心功能 - 索引、事务、引用完整性 - 您都必须自己实现。

重新发明轮子并没有错(毕竟,Linux 就是这样),但请记住您的期望和时间承诺。

【讨论】:

  • 它仅优于通用数据库,特别是因为它没有实现所有功能。一旦您将自己的数据库提高到与大型数据库相同的功能级别,我怀疑您自己的国产引擎会更快。
  • 数据库中有一些你不需要的特性。但是,大多数程序员无法为通用数据库生成性能替代品,该数据库具有大多数高质量非平凡应用程序真正需要的所有功能。
【解决方案5】:

我回答这个不是为了回答为什么平面文件数据库是好是坏,其他人在这方面做了很多工作。

但是,有些人一直在指出 SQLite 做得很好。由于您使用的是 Java,因此最好的选择是使用 HSQLDB,它与 SQLite 完全相同,但使用 Java 实现并嵌入到您的应用程序中。

【讨论】:

    【解决方案6】:

    现在,大​​多数时候平面文件数据库就足够了。但是,如果您从数据库开始您的项目,您会感谢年轻的自己。这可能是SQLite,如果您不想设置像PostgreSQL 这样的整个数据库系统。

    【讨论】:

      【解决方案7】:

      查看http://jsondb.io 一个基于开源 Java 的数据库,其中包含您正在寻找的大部分内容。 将数据保存为平面 .json 文件、多线程支持、加密支持、ORM 支持、原子性支持、基于 XPATH 的高级查询支持。

      免责声明:我创建了这个数据库。

      【讨论】:

        【解决方案8】:

        可怕的想法。每次您想要添加某些内容时,追加都会涉及到文件的末尾。更新需要每次重写整个文件。读取涉及表扫描(或维护单独的索引,这将与写入/更新有相同的问题)。只需使用数据库,当然,除非您重新实现 RDBMS 已经提供的所有内容,以使您的解决方案具有适度的可扩展性。

        【讨论】:

        • 注意:我说的是“平面文件”而不是“基于文件系统”的数据库。后者可能在小范围内是可行的。
        • @tvanfosson:您有什么理由评论自己的答案吗?为什么不更新您的答案?这条评论把我搞糊涂了。
        【解决方案9】:

        它们似乎适用于高写入、低读取、无更新的数据库,其中追加了新数据。

        Web 服务器及其近亲非常依赖它们来存储日志文件。

        DBMS 软件也将它们用于日志。

        如果您的设计在这些限制范围内,那么您似乎是一个很好的伙伴。您可能希望将元数据和指针保存在数据库中,并设置某种快速异步队列编写器来缓冲 cmets,但文件系统在缓冲和写锁定方面已经相当出色了。

        【讨论】:

          【解决方案10】:

          平面文件数据库是可能的,但请考虑以下几点。

          数据库需要获得所有 ACID 元素(原子性、一致性、隔离性、持久性),如果您要确保所有这些都在一个平面文件中完成(尤其是并发访问),那么您基本上已经编写了一个完整的- 膨胀的 DBMS。

          那么为什么不首先使用成熟的 DBMS?

          如果您只使用其中一种免费选项(SQLite、MySQL、PostgresSQL 等),您将节省编写(我保证会多次重写)所涉及的时间和金钱。

          【讨论】:

            【解决方案11】:

            如果它足够小并且不会丢失随机访问,您可以使用法定文件数据库。具有大量随机访问的大文件将非常慢。并且没有复杂的查询。没有连接,没有总和,分组等。您也不能期望从平面文件中获取分层数据。 XML 格式更适合复杂的结构。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2010-10-09
              • 2013-02-07
              • 2011-01-22
              • 1970-01-01
              • 2014-08-12
              • 2012-03-10
              • 1970-01-01
              相关资源
              最近更新 更多