代码之家  ›  专栏  ›  技术社区  ›  Manglu

在XML中存储二维表(决策表)以实现高效查询

  •  2
  • Manglu  · 技术社区  · 15 年前

    我需要实现一个路由表,其中有许多参数。

    例如,我在下面的传入消息中声明了五个属性

    Customer Txn Group Txn Type Sender Priority  Target
    UTI       CORP     ONEOFF   ABC    LOW       TRG1
    UTI       GOV      ONEOFF   ABC    LOW       TRG2
    

    用XML表示这些数据的最佳方法是什么,以便有效地查询这些数据。

    我想把这些数据存储在XML中,使用Java我将它加载到内存中,当消息传入时,我想基于属性识别目标。

    感谢任何意见。

    谢谢, 曼格鲁

    5 回复  |  直到 15 年前
        1
  •  2
  •   Jon Skeet    15 年前

    如果您要将它加载到内存中,那么XML采用什么形式并不重要——我建议您让它更易于手工读写。当你把它载入记忆时, 然后 您应该将其转换为适当的数据结构。(数据结构的确切性质取决于需求的确切性质。)

    编辑:这是为了反驳Dimitre在评论中提出的论点:

    我不确定你是否认为我建议人们实现他们自己的哈希表-我当然不认为。保持一个直的哈希表或者 MultiMap 对于要用作键的每一列。开发人员知道如何使用哈希表。

    至于运行时效率,您认为哪一个更有效:

    • 你建立了一些XSLT(记住这一点 对于大多数开发商来说,至少相对而言,是外国领土)
    • XSLT引擎解析它。这一步骤 可以 如果您使用的是一个允许您参数化现有查询的XSLT库,那么就可以避免。即使如此,你已经 一些 要做的额外工作。
    • XSLT引擎命中哈希表(至少希望如此)并返回一个节点
    • 将节点转换为更有用的数据结构

    或:

    • 您可以根据给定的键在哈希表中查找适当的条目,直接得到一个有用的数据结构。

    我个人认为我会相信第二个。在这里使用XSLT就像用螺丝刀敲钉子…

        2
  •  3
  •   Dimitre Novatchev    15 年前

    这里有一个纯XML表示,可以非常有效地进行处理 ,无需转换为任何其他内部数据结构:

    <table>
     <record Customer="UTI" Txn-Group="CORP" 
          Txn-Type="ONEOFF" Sender="ABC1" 
          Priority="LOW"  Target="TRG1"/>
    
     <record Customer="UTI" Txn-Group="Gov" 
          Txn-Type="ONEOFF" Sender="ABC2" 
          Priority="LOW"  Target="TRG2"/>
    
    
    </table>
    

    有一种非常有效的方法可以使用 <xsl:key> 指令和XSLT key() 功能 :

    这种转变 :

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes"/>
    
     <xsl:key name="kRec" match="record"
      use="concat(@Customer,'+',@Sender)"/>
    
        <xsl:template match="/">
          <xsl:copy-of select="key('kRec', 'UTI+ABC2')"/>
        </xsl:template>
    </xsl:stylesheet>
    

    当应用于上述XML文档时,将产生所需的结果 :

    <record Customer="UTI" 
            Txn-Group="Gov" Txn-Type="ONEOFF" 
            Sender="ABC2" Priority="LOW" 
            Target="TRG2"/>
    

    请注意以下事项 :

    1. 可能有多个 <XSL:Key & GT; S定义 使用要连接在一起的值的不同组合来标识记录(无论什么都将被视为“键”和/或“主键”)。

    2. 如果一个 <XSL:Key & GT; 定义为使用“主键”的串联 然后在计算key()函数时,将找到一个唯一的记录(或没有记录)。

    3. 如果一个 <XSL:Key & GT; 定义为使用“非主键”的串联 “,则在计算key()函数时可能会找到多个记录。

    4. 这个 <XSL:Key & GT; 指令相当于在数据库中定义索引 . 这使得使用key()函数 非常有效 .

    5. 在许多情况下,不需要将上述XML表单转换为中间数据结构。 因为既不是因为可理解的原因,也不是因为效率。

        3
  •  0
  •   Stephan Eggermont    15 年前

    这取决于什么是重复的,什么可能是空的。XML因其高效的查询能力而不为人所知,因为它既不固定长度,也不紧凑。

        4
  •  0
  •   Jamie Love    15 年前

    我同意前面的两个海报——当消息进入查询时,您绝对不应该将这些数据的内部表示形式保存在XML中。

    XML表示可以是任何东西,您可以这样做:

    <routes>
      <route customer="UTI" txn-group="CORP" txn-type="ONEOFF" .../>
      ...
      </routes>
    

    我的内部表示将取决于传入消息的格式和语言。一个简单的表示形式是一个映射,将一个数据结构(即作出路由决策的关键字段)映射到目标路由上的信息。

    根据您的性能要求,您可以将键/目标信息保持为字符串,但在任何高性能系统中,您可能希望做一个直的内存比较(C/C++)或某种形式的整数比较。

        5
  •  0
  •   chaos    15 年前

    是的,您的基本问题是在同一句话中使用了“xml”和“efficient”。

    编辑:不,说真的,你杀了我。这个线程中有几个人正在使用“高效”来描述 任何东西 要处理需要字符串解析的数据格式上的操作,只需找出字段的位置,就会发现这个线程中有几个人甚至不知道“efficient”一词的含义。你想说就投我一票。我可以接受,教练。