2010-06-17 52 views
5

我有一个列表管理应用程序,它将数据存储在多对多关系数据库中。如何用XML或其他简单文件格式表示多对多关系?

I.E.记录可以在任何数量的列表中,并且列表可以具有任意数量的记录。

我还可以将此数据导出到与XML文件并导入它在我的应用程序的另一个实例,为用户之间共享列表。但是,这是基于遗留系统,其中列表关注是一对多(对于XML的理想选择)。

现在需要注意的是在多个列表中esentially分成在DB两个相同的行和它们之间的所有关系都将丢失。

问:我怎么能代表一个简单的,标准的文件格式,这许多一对多的关系? (最好使用XML来保持向后兼容性)

回答

6

我认为你的XML格式必须使用某种“引用”。如果你喜欢该列表对票据关系是可见的,那么像下面这样可以适合:

<notes> 
    <note id="Note1"> ... </note> 
    <note id="Note2"> ... </note> 
    ... 
</notes> 

<lists> 
    <list id="List1"> 
     <note_refs> 
      <note_ref id="Note1"/> 
      <note_ref id="Note4"/> 
     </note_refs> 
    </list> 
    ... 
</lists> 

如果在另一方面,你希望看到轻松地与给定的音符相关联的列表,然后你可以在我的示例中简单地颠倒列表和笔记的角色。

或者,你可以更对称代表许多一对多关系的数学关系:定义所有的笔记,定义所有的列表,然后定义包括一个映射[列表参考,请参考]对。

+1

这里的最后一个建议是关系数据库如何实现它:您定义两个表,“注释”和“列表”,然后定义一个连接表“noteId”,“listId”作为主键(可能只有数据)。 这里的问题是,大多数基于XML的解决方案都会使得查询关系数据库时遇到的困难。如果我被迫使用XML,我会坚持使用“note_ref”方法(假设列表驱动显示器,并且注释可以保存在内存中)。 否则我会切换到数据库并连接表。 XML对于某些事情是很好的,但不是每一件事。 – Godeke 2010-06-17 22:45:26

+0

@Godeke数据已存储在关系数据库中。这只是一个导出的文件格式。 – CodeFusionMobile 2010-06-17 23:02:36

+0

@CSharperWithJava在这种情况下,我的评论中有99%被提出,我只是同意上面的Note_Ref方法可以让你确保你不会丢失原始的细节结构(事实记录是被链接到)。 – Godeke 2010-06-18 20:30:04

0

我能想到的真正代表XML或其他任何层次结构中的多对多关系的唯一方法是使用许多一对多关系。

这里有一个简单的例子:

<list name="listA"> 
    <notes name="noteA" /> 
    <notes name="noteB" /> 
    <notes name="noteC" /> 
</list> 
<list name="listB"> 
    <notes name="noteB" /> 
    <notes name="noteC" /> 
    <notes name="noteD" /> 
</list> 

换句话说,每个列表将有附注子节点。

许多笔记子节点会在XML文件中被复制。从XML文件填充数据库的过程必须考虑到重复的子节点记录。

另一种选择是为每个笔记选择一个列表。一个便笺将只是其中一个清单的子节点。好处是没有任何重复的笔记。缺点是XML文件不能正确表示关于列出关系的注释,这可能也可能不重要。

+0

这就是我已经做的。我有每个列表,然后列表中的每个音符作为该列表的一个元素。我的问题不是重复的笔记,而是当我失去多对多关系时丢失的信息。 – CodeFusionMobile 2010-06-17 23:04:37

+0

@CSharperWithJava:我不明白你输的是什么信息。任何便签小孩都可以有多个列表父项。该笔记将被列为与其有关系的所有列表中的孩子。 – 2010-06-17 23:34:27

+0

我不能认为两个相同的音符元素实际上是相同的音符。在你的例子中,两个noteB都可以是两个列表中的同一个音符,而noteC实际上是两个不同的音符。 – CodeFusionMobile 2010-06-18 02:10:11

0

我的第一个步骤将是一些简单:满足您需求的

<notes> 
    <note> 
    <title>Groceries to get</title> 
    <list>shopping</list> 
    <list>urgent</list> 
    <body>eggs, cheese, milk</body> 
    </note> 
</notes> 

会?

3

在一个数据库中,代表许多一对多的关系,该工具是一个关联表。表中的每一行代表两个对象之间的关联。因此,如果在列表中的1次出现的ID为1,2,3 ID的音符,将有三排的关联表:

ID NoteID ListID 
-- ------ ------ 
    1  1  1 
    2  1  2 
    3  1  3 

你可以得到一个音符和与其相关的全部名单像这样的查询:

SELECT [columns] FROM Association 
    JOIN Notes ON Note.ID = Association.NoteID 
    JOIN Lists ON List.ID = Association.ListID 
WHERE Association.NoteID = @NoteID 

而对于一个列表中的所有注意事项:

SELECT [columns] FROM Association 
    JOIN Notes ON Note.ID = Association.NoteID 
    JOIN Lists ON List.ID = Association.ListID 
WHERE Association.ListID = @ListID 

这就是你如何代表它在XML:

<Lists> 
    <List ID='1'>...</List> 
    <List ID='2'>...</List> 
    <List ID='3'>...</List> 
    ... 
<Lists> 
<Notes> 
    <Note ID='1'>...</Note> 
</Notes> 
<Associations> 
    <Association ID='1' NoteID='1' ListID='1'/> 
    <Association ID='2' NoteID='1' ListID='2'/> 
    <Association ID='3' NoteID='1' ListID='3'/> 
</Associations> 

在,XSLT,你可以访问这个协会是这样的:

<xsl:template match="List" mode="AssociatedNotes"> 
    <xsl:variable name="Associations" select="/*/Associations/Association[@ListID=current()/@ID]"/> 
    <xsl:apply-templates select="/*/Notes[@ID=$Associations/@NoteID]"/> 
</xsl:template> 

<xsl:template match="Note" mode="AssociatedLists"> 
    <xsl:variable name="Associations" select="/*/Associations/Association[@NoteID=current()/@ID]"/> 
    <xsl:apply-templates select="/*/Lists[@ID=$Associations/@ListID]"/> 
</xsl:template> 

(注意使用mode属性,以保持这些模板从称呼对方,直到你得到一个堆栈溢出。)

0

只是这样做:

<notes> 
    <note id="1"> 
     <name>George</name> 
     <text>1984</text> 
     <notesLinks> 
      <listId id="1"/> 
     </notesLinks> 
    </note> 
    <note id="2"> 
     <name>George</name> 
     <text>animal farm</text> 
     <notesLinks></notesLinks> 
    </note> 
</notes> 
<lists> 
    <list id="1"> 
     <notesLinks> 
      <noteId id="1"/> 
      <noteId id="2"/> 
     </notesLinks> 
     <name>some info</name> 
    </list> 
</lists> 
相关问题