如果我有一个由文件夹和文件组成的静态数据库,考虑到这将在 CGI 脚本中使用,访问和操作会比 SQL 服务器类型的数据库更快吗?
处理文件和文件夹时,提高性能的技巧是什么?
如果我有一个由文件夹和文件组成的静态数据库,考虑到这将在 CGI 脚本中使用,访问和操作会比 SQL 服务器类型的数据库更快吗?
处理文件和文件夹时,提高性能的技巧是什么?
我将添加到这取决于人群。
这是一种没有通用答案但在很大程度上取决于手头情况的问题。我什至最近将一些数据从 SQL 数据库移动到平面文件系统,因为 DB 的开销,加上一些 DB 连接可靠性问题,使得使用平面文件成为更好的选择。
在做出选择时我会问自己的一些问题包括:
我如何使用数据?例如,我会按照输入的顺序从头到尾读取行吗?或者我会搜索匹配多个条件的行吗?
在一个程序执行期间,我将多久访问一次数据?我会去一次以获取所有以塞林格为作者的书籍,还是会去几次以获取多个不同的作者?我会根据几个不同的标准去不止一次吗?
我将如何添加数据?我可以只在末尾附加一行,这对于我的检索来说是完美的,还是需要使用它?
六个月后代码的逻辑性如何? 我强调这一点是因为我认为这在设计事物时经常被遗忘(不仅仅是代码,这匹爱好马实际上来自我作为海军机械师诅咒机械工程师的日子)。在六个月内,当我必须维护您的代码(或者您在完成另一个项目之后)时,哪种存储和检索数据的方式会更有意义。如果从平面文件到数据库会导致 1% 的效率提高,但在必须更新代码时增加一周的时间来解决问题,那么你真的改进了一些事情。
作为一般规则,数据库比文件慢。
如果您需要对文件进行索引,那么如果您正确执行,自定义索引结构上的硬编码访问路径将始终具有更快的潜力。
但是在选择数据库而不是基于文件的解决方案时,“性能”并不是目标。
您应该问问自己您的系统是否需要数据库提供的任何好处。如果是这样,那么小的性能开销是完全可以接受的。
所以:
基本上,问题是哪个更容易开发。两者之间的性能差异不值得浪费开发时间。
取决于您的信息是什么以及您的访问模式和规模是什么。关系数据库的两个最大好处是:
缓存。除非你很聪明,否则你写不出像数据库服务器一样好的缓存
优化器。
然而,对于某些专门的应用程序,与文件+文件夹数据存储相比,这两个好处都没有体现出来——因此答案是响亮的“取决于”。
至于文件/文件夹,技巧是:
根据我的一点经验,与本地文件系统相比,基于服务器的数据库(即使是在本地机器上提供服务的数据库)往往具有非常慢的吞吐量。然而,这取决于一些事情,其中之一是渐近复杂性。将扫描大量文件列表与使用带有索引的数据库查找项目进行比较,数据库胜出。
我的一点经验是使用 PostgreSQL。我有一个包含 300 万行的表,而我只更新了 8,000 条记录。花了8秒。
至于“过早的优化是万恶之源”这句话,我会持保留态度。如果您使用数据库编写应用程序,然后发现它很慢,则可能需要大量时间才能切换到基于文件系统的方法或其他方法(例如 SQLite)。我想说你最好的选择是创建一个非常简单的工作负载原型,并使用这两种方法对其进行测试。我相信在这种情况下知道哪个更快是很重要的。
正如其他人指出的那样:这取决于!
如果您确实需要找出哪个对您的目的性能更高,您可能需要生成一些示例数据以存储在每种格式中,然后运行一些基准测试。Benchmark.pm 模块是 Perl 自带的,它使得与这样的东西进行并排比较变得相当简单:
use Benchmark qw(:all) ;
my $count = 1000; # Some large-ish number of trials is recommended.
cmpthese($count, {
'File System' => sub { ...your filesystem code... },
'Database' => sub { ...your database code... }
});
您可以键入perldoc Benchmark
以获取更完整的文档。
如果站点结构合适,在图像方面使用文件而不是 db 非常有用。创建代表匹配数据的文件夹并将图像放入其中。例如,您有一个文章站点,您将文章存储在 db 中。您不必将图像路径放在 db 上,使用主键(如 1、2、3..)命名文件夹并将图像放入其中。电子书、音乐文件、视频,所有媒体文件都可以采用这种方式。如果您不搜索某些内容,则相同的逻辑适用于 xml 文件。
这取决于数据的配置文件以及您将使用什么逻辑来访问它。如果您只需要保存和获取命名节点,那么基于文件系统的数据库可能会更快、更高效。(为此,您还可以查看 Berkeley DB。)如果您需要进行基于索引的搜索,特别是如果您需要根据键连接不同的数据集,那么 SQL 数据库是您的最佳选择。
我会选择最适合您的应用程序的任何解决方案。
正如其他人所说,这取决于:数据的大小和性质以及您计划在其上运行的操作。
特别是对于CGI 脚本,在每个页面视图上连接到数据库服务器都会导致性能下降。但是,如果您创建一个简单的基于文件的方法,则很容易产生更糟糕的性能问题;-)
除了 Berkeley DB File 解决方案,您还可以考虑使用SQLite。这将为存储在本地文件中的数据库创建一个 SQL 接口。您可以使用 DBI 和 SQL 访问它,但没有服务器、配置或网络协议。如果将来需要数据库服务器,这可以更容易迁移(例如:如果您决定拥有多个前端服务器,但需要共享状态)。
在不知道任何细节的情况下,我建议使用 SQLite/DBI 解决方案,然后查看性能。这将通过相当简单的启动和良好的性能提供灵活性。
要快速访问文件,取决于您正在做什么,mmap 非常方便。我刚刚在Effective Perl博客中将其作为Memory-map 文件而不是 slurping 来写。
但是,我希望数据库服务器会快得多。当我们不知道你在做什么、你需要访问什么样的数据等等时,很难说什么对你来说更快。
就像其他人说的一样,数据库是一个工具,它会产生一些开销,但是如果您的数据是静态的并且它是只读数据,从文件中读取目录会更快:这是我做过的一些测试:我有文件文件的名称为 .csv 在数据库中,我将列索引为“日期”,以便在数据库中找到相同的记录。每天有 30K-50K 记录/行和 100 列不同类型的数据(90% 浮动)。
数据库信息:PostgreSQL 11.5,16GB RAM
Table:
335,162,867 records
Table size: 110GB
Index size: 7GB
Total size: 117GB
Files:
Number of files: 8033
Total Files size: 158GB
Number of records/lines per file/date: 30K - 50K
从文件中读取随机日期(1986-2019)的数据比在 PostgreSQL 中读取同一日期的数据快 4-5 倍
引用 SQLite 测试,
SQLite 读取和写入小 blob(例如,缩略图)比使用 fread() 或 fwrite() 从磁盘上的单个文件读取或写入相同的 blob 快 35%¹。
此外,与将 Blob 存储在单个文件中相比,一个保存 10 KB Blob 的 SQLite 数据库使用的磁盘空间减少了约 20%。
出现性能差异(我们相信)是因为在 SQLite 数据库中工作时,open() 和 close() 系统调用仅调用一次,而当使用存储在个别文件。看起来调用 open() 和 close() 的开销大于使用数据库的开销。大小减少的原因是单个文件被填充到文件系统块大小的下一个倍数,而 blob 被更紧密地打包到 SQLite 数据库中。
本文中的测量是在 2017-06-05 的一周内使用 3.19.2 和 3.20.0 之间的 SQLite 版本进行的。您可能期望 SQLite 的未来版本会表现得更好。
我为我的办公室管理站点(美国和巴西的 100 万员工)选择了文件/文件夹系统,这是我的第一个项目(作为工作)。
事实上,这是我从那以后做出的最不负责任但幸运的是最合适的决定。
为了处理这个文件系统,我还设置了一个 php 函数集以简化内容。我考虑使这些功能的事情是:
就这样。
但是在使用它时,我不得不考虑优化这么多。例如,当谈到最后一次见到某人时..
当某个X
用户想要查看lastseen
其他用户时,Y
我创建了一个名为的文件夹,在该文件夹dataRequestingCluster
下X
包含X
想要查看最后一次看到的所有内容(X
如果X
正在查看他的朋友页面,则可能是 的好友列表)并将该集群添加到Y
的最后一次看到的表中(其中包含所有 "Y
的最后一次出现的请求者单独的 clusterFiles" 并在每次 Y 与服务器交互时更新)
然后添加了一个机制,在 3 分钟内不使用时删除 dataRequestClusters(当 X 离开他的朋友页面时,不需要为他更新最后一次看到的)
我必须遵循这种方法,因为更新最后一次出现在 ALL_USERS 文件中是一个完全的笑话。
最重要的是,这种方法比使用 MySql 的数据库系统要快得多……但是你必须动用大脑和多 30% 的时间,但由此带来的快乐和完整性真是太棒了
这只是“最后一次见到”的一个案例
很多次我使用不同的算法来解决每个问题,它总是比 sql/db 系统高效。
结论:文件系统使事情变得复杂,但它以令人震惊的方式提高质量的唯一方法......如果您不善于思考或时间较少,或者您对自己所做的事情不感兴趣,您可能应该使用 SQL/DB系统。
6 个月后,我的服务器数据存储空间变成了 20GB(没有媒体文件.. 只是用户信息),但任何单个文件从未超过 200kb.. 它以最少的处理时间取得了惊人的成功。