代码之家  ›  专栏  ›  技术社区  ›  Greg D

是否有正当理由将内部数据保存为XML?

  •  6
  • Greg D  · 技术社区  · 15 年前

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

    WebService

    第一个应用程序是Web服务,它提供对SQL数据库中可能大量数据的访问。在启动时,它将或多或少的所有数据从数据库中提取出来,并以XML的形式存储在内存中。(三次。)此应用程序的所有者将其称为缓存。我称之为慢,因为在处理这个问题时遇到的每个性能问题都可以直接追踪到这个问题。(这是一个公司环境,客户机会因为性能故障而受到指责,而不是服务,这一点也不奇怪。)此应用程序确实使用了XML DOM。

    进口商

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

    我对常识的理解表明XML是 一种在内存中保存数据的好格式,但是当数据被输出/传输时,应该将其转换为XML,并在读取和导入时将其转换为内部数据结构。问题是,我经常碰到完全忽略可伸缩性问题的生产代码,并经历了 为此付出了额外的努力。(在这些应用程序中,字符串解析的数量太大,令人恐惧。)

    这是一个常见的失败应用正确的工具的工作,其他人遇到了ALOS?或者只是我运气不好?或者我错过了一些显而易见的 好的 将大量数据以XML形式存储在内存中的情况是正确的,也可以吗?

    9 回复  |  直到 12 年前
        1
  •  4
  •   Nate CSS Guy    15 年前

    存储在内存中的任何数据都应该在类中。我们谈论的数据量越大,这就越重要。XML是一种非常膨胀的格式,它会降低性能。XML只能用于在应用程序之间传输数据。恕我直言。

        2
  •  2
  •   Matthew Flaschen    15 年前

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

    第二,您应该尽快将XML转换为一种有用的表示,可能是一个数据库,然后以这种方式使用它。只有在数据量很小的情况下,才适合将内存中的所有工作作为XML文档(例如,使用xpath)来完成。字符串分析应该非常谨慎地使用。

        3
  •  1
  •   Michael La Voie Frederik Gheysels    15 年前

    @马修·弗莱森说得很有道理。我想补充一点,当您加入任何现有的项目时,您可能会发现一些您不同意的设计和实现决策。

    我们都一直在学习新事物,我们都会犯错。虽然我同意这似乎是一个“duh”类的问题,但我确信其他开发人员正试图通过缓存的概念来优化代码。

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

    我建议同意他们的观点,即缓存是一个很好的主意,但是您希望通过它来加快函数的速度。创建一个与旧方法相比(逻辑性更强)实现工作原理的快速演示。很难与大幅提高速度争论。只是要小心直接攻击他们在对话中实现的方式。你需要这些人和你一起工作。

    祝你好运!

        4
  •  0
  •   akf    15 年前

    我也同意,我确实认为有一点运气不好。

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

        5
  •  0
  •   Steve    15 年前

    我发现我必须这样做才能与旧的COM对象交互。COM对象可以采用XML或类。填充类中每个成员的互操作开销太大,处理XML是一种更快的选择。我们本可以让一个C类与COM类完全相同,但在我们的时间范围内做起来实在太困难了。所以是XML。这并不是一个好的设计决策,但在处理大型数据结构的互操作时,这是我们能做的最快的。

    我不得不说我们在C边使用linqtoxml,因此它使使用起来稍微容易一些。

        6
  •  0
  •   bytebender    15 年前

    OOP和数据库呢?XML有它的用途,但是使用它来处理所有事情可能会有问题(如您所见)。

    数据库可以允许索引、事务等加速数据访问。

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

    我不反对使用XML,但它就像模式一样,它们是一种工具,我们应该了解在哪里和何时使用它们,而不是爱上它们,并尝试在任何地方使用它们…

        7
  •  0
  •   ncarste    15 年前

    格雷戈

    在一些应用程序中,我或多或少遵循了您描述的模式:

    编辑:不要刮那个。我从未将XML存储为字符串(或多个字符串)。我只是把它解析成一个dom并处理它。这很有帮助。

    我已经将XML源导入到DOM(Microsoft Parser)中,并将它们保存在那里进行所有必需的处理。我很清楚DOM导致的内存开销,但是我发现Apporach非常有用。

    • 处理过程中的一些检查需要随机访问数据。为此,selectpath语句工作得很好。

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

    • 将XSLT转换应用于DOM的全部或部分是一个快照

    • 文件I/O也由DOM负责(xmldoc.save…)

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

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

        8
  •  0
  •   pgfearo    15 年前

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

    然而,这里有一个有趣的 presentation 亚历克斯·布朗,关于如何以更有效的方式在内存中保存XML。作为“冻结的溪流”。

    此外,还有一段视频,以及2009年在XML布拉格举行的其他演示。 here .

    link text

        9
  •  0
  •   Florian Brucker    12 年前

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

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

    例如, the lumberjack logging framework :其思想是建立一个基于XML的事件数据模型,在该模型中,每个应用程序都可以提供有关事件(警告、错误等)的分层信息。框架负责收集事件并将其分发给适当的处理程序。第三方可以轻松地定义自己对格式的添加,并提供适当的生成器和处理程序。

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