数据库与平面文本文件:当性能不是问题时,选择一个而不是另一个的技术原因是什么?

时间:2009-09-30 16:26:20

标签: sql database

我在我正在工作的一个团队中遇到了问题。其中一个人在我看来有点SQL快乐,并希望将一个小型python FTP下载器生成的日志信息存储到数据库中,而不是只是一个很好的格式化文本文件。现在我一直认为只有在加速数据库时才能使用数据库,或者为数据提供更可靠的接口。你有什么看法?

谢谢!

编辑:在这个特定的实例中,数据每天将增加大约100行,并被处理一次并丢弃。虽然这个案例是直接关注的,但我对一般答案更感兴趣。

编辑2:感谢您的所有回复!我用最多的选票作为答案标记了答案,因为我觉得它简明扼要地说明了你们所做的大部分要点,但我会观察并看看是否还有其它问题。

23 个答案:

答案 0 :(得分:22)

如果您想要运行数据报告,或稍后问问题,数据库是一个合理的选择,特别是如果您在同一个数据库文件中存储多个运行以查找趋势。

如果您只是从单独的运行中编写日志,并且在查看后不关心数据,那么数据库可能没有意义。

答案 1 :(得分:15)

看,很多“想到未来需求”的论点都是过度工程的过时。 KISS。

在这方面,你唯一需要做的就是解决未来的需求就是简单地编写你的日志记录例程,以便以后很容易将它完全重定向到别的东西。 DIY文​​本,syslog类型服务或DB。记住这个概念,但不要写任何东西,而是你现在需要的东西。

根据你的描述,听起来你应该只使用一个简单的文本文件。

答案 2 :(得分:7)

鉴于那里有大量的log file analysis程序以及纯文本的服务器日志数量,很明显纯文本日志文件可以扩展并且相当容易查询。

通常,大多数SQL数据库都针对updating data robustly进行了优化,而不是简单地追加到时间序列的末尾。该实现假定数据不应该重复,并且存在与需要强制执行的其他关系/表的引用相关的完整性约束。由于日志永远不会更新现有条目,因此没有可以违反的约束或级联删除,因此有很多内容永远不会使用。

您可能更喜欢用于事务可伸缩性的数据库 - 比如说您希望将许多日志集中到一个数据库中,因此实际上获得了一些并发性(尽管它不是问题的固有内容 - 在一台服务器上使用单独的日志也可以允许这样做,但是然后你必须将它们合并为所有系统的总数)。

使用SQL数据库比仅添加一个或两个文件并调用fflush要复杂一些。 OTOH如果您非常习惯使用SQL并且已经在项目中使用数据库,那么使用数据库进行日志记录的开销也很小。

答案 3 :(得分:7)

平面文件 是一种数据库形式。

选择一个预先存在的DBMS而不是自己动手的原因主要是你在问题领域花费的时间更好,而不是重新发明轮子。

如果您的需求很简单并且您不想花费很多钱,您可以随时使用低端或OSS数据库。

答案 4 :(得分:5)

我脑海中浮现出许多问题,可以指导答案,最终是你自己的答案。

  • 您是否需要稍后搜索数据,如果没有,为什么要记录?如果这样做,搜索的数量或类型是否适合平面文件。
  • 数据量是否较小,数据库是否过早优化,或者您是否要存储大量日志数据?
  • 您将使用哪种备份/ DR /还原SLA,如果您没有,并且从不打算备份文件或保护它,例如它的信息充其量只有一个文件可能没问题,但如果你必须确保数据是安全的,并且时间点恢复是可以实现的,那么你需要查看平面文件的替代方案。
  • 现在数据是否很小,但随着时间的推移会缩小/变大?为短期解决方案选择一个文件,从长远来看确实会对你造成伤害。

没有一个解决方案,数据库可能会进行初步优化,但同样可能非常有效。

一个。

答案 5 :(得分:5)

作为客户端/服务器和现在的n层应用程序的开发人员,我非常喜欢数据库系统的强大功能,可靠性和速度。说完这个后,我对在db中进行进程日志记录非常犹豫。在db中存储复杂工作流的当前状态或关键状态转换非常好,但是对DB中的所有步骤进行loggin / tracing可能是个问题。如果记录的原因是能够跟踪故障并可能调试系统,我需要能够在最恶劣的情况下处理我的“日志”。如果我的db / network /怎么办?在某种程度上不起作用。如果我可以进入服务器,一个文本文件让我用vi / emacs / notepad / *进行调试。不是最强大的工具集,但始终可用。格式良好的日志文件也可以使用grep / awk / sed等生成报告。同样,不是最强大但随时可用的。最后,如果我希望我的日志记录在故障情况下使用,我需要尽可能高的可用性,并且假设我处于故障状态,我不能假设我的数据库仍然在运行。

答案 6 :(得分:4)

数据库提供可伸缩性,而平面文件则不提供。如果您开发的应用程序需要在2年内完成更多工作,会发生什么? 数据库还提供许多其他好处,包括权限级别和内置备份,否则您必须手动配置,增加了需要完成的工作。 如果是一个选项,我将始终选择平面文件上的数据库。总是

答案 7 :(得分:4)

建议使用log4j / log4cxx(您没有指定语言)。有可用的appender可以将数据放入数据库,平面文件或syslogd。您可以将其设置为群组在任何时候决定的任何内容。你甚至可以同时做两件事。这是两全其美的。

答案 8 :(得分:4)

当日志文件导致磁盘空间不足时会发生什么?

将记录信息存储在数据库表中的优点:

  1. 如果您正确格式化表格,则可轻松查询。想知道为什么你的FTP下载在上周二11:53 AM破了吗?玩得开心浏览你的平面文件。我将编写一个查询,并在很短的时间内获取信息。
  2. 易于扩展。如果你有一个企业级数据库,你永远不会(除非你的DBA很傻)必须担心磁盘空间不足的日志。
  3. 交易:您不必担心文件锁和附加。
  4. 我觉得我可以继续讨论这个话题。说真的,获得标准的日志记录方法并使用数据库表,你不会后悔。

答案 9 :(得分:2)

大多数答案似乎只是为了最大的优势而提供口头服务:复杂的临时查询。在这种情况下,可伸缩性与它没有任何关系。

答案 10 :(得分:1)

如果将平面文件视为数据库,则它们是数据库。使用平面文件的优点:

  • 高度便携
  • 人类可读/可直接编辑
  • 零配置/管理(sqlite也有这个优势)。安全性相当于正确设置文件权限

缺点:

  • 时间/空间效率(这对您的用例来说似乎不重要)
  • 无数据完整性检查
  • 没有明确的数据类型
  • 用于处理平面文件作为数据库的工具(大多数情况下)比具有本机存储格式的数据库要成熟得多

说您需要写入数据库以查询数据是错误的。有几个工具可以让您使用平面文件:

答案 11 :(得分:1)

如果您只是“丢弃”您的数据而不打算稍后操作/查询,则最好使用文本文件,因为它比使用数据库更快。

答案 12 :(得分:1)

存储到数据库还可以允许某人在以后查找日志以用于各种目的。 (假设日志事件的各个元素,例如日期/时间,事件类型,数字代码,明文消息等分开保存。)

与平面文本输出相比,通常存储到数据库会产生很小的性能损失。如果底层数据库表有许多索引,这将更加明显。有时一种有效的方法是存储到数据库堆(没有任何索引的表,或者可能只是一个简单的索引),并且通过每天晚上(或每当SQL加载时将其内容移动到完全索引的表)来保持这个堆很小预计会很低。)

在相关问题上,您可以查看许多有用的日志库,例如log4j(可以将btw配置为使用滚动管理或数据库后端转换为平面文件)...

我建议仅以平面文本文件格式保留的唯一日志,这些日志与罕见/偶然的错误消息和其他异常情况相关联。然后,文本文件格式提供对信息的随时访问(使用本地文本编辑器),用于诊断目的,对几周内的日志事件感兴趣。

答案 13 :(得分:1)

有两件事会让我使用数据库:

(a)您的日志文件具有不同的字段,例如记录日期,事件时登录用户的ID,触发事件的模块等;和

(b)您需要查询这些字段,尤其是复杂查询。比如,“列出周末模块xyz触发的所有内存溢出”。

另一方面,如果您的日志文件是由各种模块发出的一系列不相关的消息,没有一致的格式,那么日志文件唯一可能的create语句是“create table log(logmessage varchar) (500))“,然后我没有看到使用数据库有任何明显的好处。

数据库肯定会变慢:它总是需要更多的时间来更新索引并进行动态插入,而不是仅仅追加到文本文件的末尾。写入数据库涉及数据因数据库问题而丢失或损坏的可能性。当然,这种情况很少见,但可能日志文件的目的是帮助您跟踪数据损坏等问题。如果您的错误识别和恢复过程基于您永远不会有任何错误的假设,那么您为什么要这样做呢?它让人想起所有关于帮助台发送电子邮件的蹩脚笑话,警告人们电子邮件系统无法正常工作。

就个人而言,我几乎总是将日志写入一个简单的文本文件。当我登录数据库时,我只能想到几次。我最后一次这样做是因为我无法访问生产服务器上的文件系统,但可以访问数据库。

答案 14 :(得分:1)

  • 性能
  • 可扩展性
  • 冗余
  • 归一化
  • 数据完整性
  • 多用户(并发)访问
  • 数据存储效率(取决于当然的索引)

答案 15 :(得分:1)

这取决于背景。如果它非常有限,因为你建议只是记录一些基本的文件传输数据处理日志一次并扔掉它我也倾向于被平面文件选项吸引。 RDBMS会有点矫枉过正,但未来的可能性可能会增加一个压倒一切的因素。

作为折衷方案,您可能需要考虑像SQL Lite等嵌入式解决方案,或者使用对平面文件进行操作的数据库抽象API(例如平面文件ODBC驱动程序),以后可以轻松更改以针对RDBMS进行操作没有任何或任何siginficant代码更改作为条件警告。

您可能还想考虑日志服务器,例如使用带有数据库支持存储的可靠syslog。使用这种方法,简单应用程序的复杂性较低,所有系统都可以从这种安排中受益。

答案 16 :(得分:1)

sqlite怎么样? 它是一个C库,它实现了一个非常简单的数据库,推荐用于简单的项目。

答案 17 :(得分:0)

在我看来总是有一个权衡

如上所述,取决于您打算如何收集和使用您生成的数据

数据库已经开箱即用,有几个实用程序和功能可以帮助操作数据,即输入,存储,分析,排序,比较,完整性检查,报告,检索,搜索,过滤器,安全性,多用户编辑等

但是,您可以使用平面文件实现所有这些,但您必须准备好提供执行大多数数据库所做这些事情的界面。通过巧妙地调整结构并使用每行数据项定义良好的列/字段,您甚至可以实现关系状态。这里的区别在于,虽然某些数据库具有标准的这些功能,但您必须通过脚本或代码创建此功能。可以创建所有这些功能,包括所有类型的备份。

但是,您必须确定哪种方式可以为您提供最佳效益,即您是通过编写自己的脚本来操作数据(如上所列)并获得更轻,也许更快的性能,或通过减少您的收益来获得更多收益自己的开发时间,而是部署标准或自定义数据库解决方案?

我自己认为,当有人告诉你用户友好时,比例是成反比的,即在理想情况下,程序员/开发人员在开发各种场景的幕后花费越多,就越容易最终用户,程序员/开发人员的努力越少,那么系统的最终用户将不得不使用更多的精力来操纵数据

答案 18 :(得分:0)

写入syslog(如果在Unix系统上运行),将syslog重定向到旋转日志文件和数据库。

使用标准的unix工具(如tail可以与grep等结合使用),日志文件对于实时监控非常有用。

syslog可以将日志消息重定向到不同的服务器,多个目标等。

如果数据库失败了日志记录,那么在应用程序中构建数据库依赖关系并不总是明智的吗?

如果您的唯一日志记录转到数据库,如何记录数据库故障?

答案 19 :(得分:0)

我想你可能已经回答了自己的问题:

  

现在我一直认为是   数据库只应该用于它   加快速度,或提供更多   可靠的数据接口

根据定义,数据库为结构化数据提供了更可靠的接口 - 提供命名列和保证数据类型。

如果您的需求非常简单(少数绝对一致的字段没有标准化问题),您可能不会因使用文本文件而受到太多影响。但是你打算如何分析文件呢?据推测,第一步是将其读入数据库或一些内存中的数据结构。使用数据库开始意味着已经为您完成了步骤。

答案 20 :(得分:0)

关系技术提供了以任何可能的方式查询底层的可能性,而无需用户知道存储和物理布局的东西。

即使对于SQL系统也是如此。

如果您不需要可查询性,那么任何选项都可能适合您的目的,而“最简单”(例如普通字节平面文件)可能会为您提供最佳性能。

还有一件事:如果您有多个并发的日志条目源,那么序列化问题就变得很重要了。当记录到flatfile时,flatfile上的锁将持续执行写操作所需的时间,当登录到数据库时,日志记录本身成为事务的一部分,并且锁定(在日志表上)可能持续时间为该交易,可能导致“排队溢出”,或“护航综合症”,或任何你想要命名的。

答案 21 :(得分:0)

已经有很多好的(接受的答案质量)答案,我只想补充一点,应该考虑:

如果您的磁盘空间不足,或者您只是想在记录日志5年后不想在平面文件上浪费16GB,您是否愿意发出“DELETE FROM Logs WHERE Date&lt; < em> x “可以在没有停机的情况下同时运行,或者您希望在从文本文件的顶部修剪16GB值的行时让您的应用程序脱机(您打赌它会锁定文件)

“它不是太快”和“它根本没有运行”之间存在很大差异。

编辑:为了响应您的编辑,如果您计划在处理数据后丢弃数据,那么从数据库(DELETE)剪切数据然后是平面文件(除非您开始使用固定行大小和恭维你自己的块分配方案,此时你刚刚开始诋毁一个糟糕的勒芒数据库)

答案 22 :(得分:0)

我喜欢为未来做一点计划。如果平面类型文件为您提供了今天所需的内容,那么如果您的规格发生变化或客户希望更晚,该怎么办?您不希望解释为重新设计解决方案需要花费大量时间。如果此解决方案有可能需要持续一段时间并且可能受到客户端的影响,那么数据库解决方案将具有您可能需要的灵活性。