在我工作的这些年里,我注意到一种明显的趋势,我认为这是一种反模式:将内部数据维护为大的 XML 字符串。我见过很多不同的方法,尽管两个最严重的罪犯非常相似。

网络服务

第一个应用程序是一个 Web 服务,提供对 SQL 数据库中潜在大量数据的访问。启动时,它或多或少地从数据库中提取所有数据并将其作为 XML 存储在内存中。(三次。)该应用程序的所有者将其称为缓存。我称其为慢,因为在解决这个问题时遇到的每个性能问题都可以直接追溯到这个问题。(在企业环境中,客户端因性能故障而受到指责,而不是服务,这应该不足为奇。)该应用程序确实使用了 XML DOM。

进口商

第二个应用程序读取从第三方数据库导出后生成的 XML 文件。目标是将这些数据导入专有系统(由我们拥有)。执行此操作的应用程序会读取整个 XML 文件,并在整个导入序列中维护至少两个(有时多达四个)XML 文件的副本。请注意,数据可以在导入之前进行操作、转换和配置,因此导入者在整个生命周期中都拥有 XML 格式的数据。不出所料,当提供中等大小的 XML 文件时,该导入器就会崩溃。该应用程序仅将 XML DOM 用于其副本之一,其余部分都是原始 XML 字符串。

我对常识的理解表明 XML 是 不是 这是一种在内存中保存数据的良好格式,但数据在输出/传输时应转换为 XML,在读入和导入时应转换为内部数据结构。问题是,我经常遇到完全忽略可扩展性问题的生产代码,并经历了 需要额外的努力来做到这一点。(这些应用程序中字符串解析的庞大数量令人恐惧。)

这是其他人遇到的一种常见的失败情况吗?或者只是我运气不好?或者我是否错过了一些令人眼花缭乱的明显和 好的 在什么情况下,将大量数据以 XML 形式存储在内存中是正确且可行的?

有帮助吗?

解决方案

存储在内存中的任何数据都应该在类中。我们谈论的数据量越大,这一点就越重要。 Xml是一种非常臃肿的格式,会降低性能。 Xml应仅用于在应用程序之间传输数据。 IMHO。

其他提示

不,我同意。对于您的第一个示例,数据库应该处理几乎所有的缓存,因此将所有数据存储在程序存储器中是错误的。这适用于它是以XML还是以其他方式存储在内存中。

对于第二种,您应该尽快将XML转换为有用的表示形式,可能是数据库,然后以这种方式使用它。只有当它是少量数据时才适合在内存中作为XmlDocument进行所有工作(例如使用XPath)。应该非常谨慎地使用字符串解析。

@Matthew Flaschen提出了一个很好的观点。我想补充一点,当您加入任何现有项目时,您可能会发现一些您不同意的设计和实施决策。

我们都在不断学习新事物,我们都会犯错误。虽然我同意这看起来像是“呃”有点问题,我确信其他开发人员正试图通过缓存的概念来优化代码。

关键是,有时需要一种温和的方法来说服人们,特别是开发人员改变他们的方式。这不是编码问题,而是人的问题。您需要找到一种方法来说服这些开发人员,您所建议的这些更改并不意味着他们不称职。

我建议他们同意缓存可能是一个好主意,但是你想要加速它以加速功能。与旧方法相比,创建一个快速演示,了解您的(更合理的)实现方式。很难与戏剧性的速度提升争论。要小心直接攻击他们在对话中实施的方式。你需要这些人与你合作。

祝你好运!

我同意,我确实认为运气不好。

...但抓住吸管,我可以看到将数据存储为XML的唯一用途是用于自动化单元测试,其中XML提供了一种模拟测试数据的简便方法。但绝对不值得。

我发现我必须这样做才能与传统的COM对象进行交互。 COM对象可以使用xml或类。填充类的每个成员的互操作开销太大,处理xml是一个更快的替代方案。我们本可以使一个c#类与COM类相同,但在我们的时间范围内确实太难了。所以它是xml。这并不是一个好的设计决策,但在处理大量数据结构的互操作时,它是我们能做的最快的。

我不得不说我们在C#端使用LinqtoXML,因此它使得使用起来更容易。

OOP和数据库怎么样? Xml有它的用途但是可能存在问题(正如你所看到的)将它用于所有事情。

数据库可以允许索引,事务等,从而加快数据访问速度

在大多数情况下,对象更容易使用,它们可以更好地描述您的域等。

我并不反对使用xml,但它就像模式一样,它们是我们应该了解何时何地使用它们的工具,不会爱上它们并尝试在任何地方使用它们......

格雷格,

在几个应用程序中,我确实或多或少地遵循了您描述的模式:

编辑:没有划痕。我从未将 XML 存储为字符串(或多个字符串)。我只是将其解析为 DOM 并使用它。这很有帮助。

我已将 XML 源导入到 DOM(Microsoft Parser)中,并将它们保留在那里以进行所有必需的处理。我很清楚 DOM 造成的内存开销,但我发现该方法仍然非常有用。

  • 处理过程中的一些检查需要随机访问数据。selectPath 语句非常适合此目的。

  • DOM 节点可以作为参数在应用程序中来回传递。另一种方法是编写包装每种类型对象的类,并随着 XML 模式的发展而更新它们。这是一个穷人(VB6/VBA)的多态性方法。

  • 将 XSLT 转换应用于全部或部分 DOM 非常简单

  • 文件 I/O 也由 DOM 处理(xmldoc.save...)

对象的链接列表将消耗相当数量的内存并且需要更多代码。所有的搜索和 I/O 功能我都必须自己编写代码。

我所认为的反模式实际上是应用程序的旧版本,其中 XML 或多或少被手动解析为结构数组。

对于大量数据,答案是否定的,没有充分理由将数据直接存储为内存中的XML字符串。

然而,这是一个有趣的演示文稿。作为'冷冻流'。

还有一个视频,以及XML Prague 2009 此处提供的其他演示文稿

链接文字

通常,我会尝试使用独立于XML序列化的内部数据模型。

但是,在我看来有一种情况,使用XML作为内部数据结构是有意义的:如果您的数据模型需要捕获层次关系,其格式可以由第三方扩展,如果您的应用程序需要转发此数据,同时保留扩展信息。

伐木工人日志框架为例:我们的想法是拥有一个基于XML的事件数据每个应用程序都可以提供有关事件(警告,错误等)的分层信息的模型。该框架负责收集事件并将它们分发给适当的处理程序。第三方可以轻松定义自己对格式的添加,并提供适当的生成器和处理程序。

这里的重要部分是框架必须将所有XML信息从生成器转发到处理程序的XML。 在这种情况下,实现捕获所有必要信息的内部数据结构会导致大部分XML本身的重新实现。因此,使用适当的DOM框架进行内部数据表示是有道理的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top