我有一个列表管理应用程序,可将其数据存储在多对多关系数据库中。
即。注释可以包含任意数量的列表,列表可以包含任意数量的注释。
我也可以将此数据导出到XML文件,然后将其导入我的应用程序的另一个实例,以便在用户之间共享列表。但是,这是基于遗留系统,其中要注释的列表关系是一对多(XML的理想选择)。
现在,多个列表中的注释在数据库中基本上被分成两个相同的行,并且它们之间的所有关系都将丢失。
问题:如何以简单的标准文件格式表示这种多对多关系? (最好使用XML来保持向后兼容性)
答案 0 :(得分: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 :(得分:3)
在数据库中,用于表示多对多关系的工具是关联表。表中的每一行代表两个对象之间的关联。因此,如果ID为1的注释出现在ID为1,2和3的列表中,则关联表中将有三行:
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
属性来防止这些模板相互调用,直到出现堆栈溢出。)
答案 2 :(得分: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文件并不代表正确列出关系的注释,这可能重要也可能不重要。
答案 3 :(得分:0)
我的第一步将是简单的:
<notes>
<note>
<title>Groceries to get</title>
<list>shopping</list>
<list>urgent</list>
<body>eggs, cheese, milk</body>
</note>
</notes>
这符合您的需求吗?
答案 4 :(得分: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>