Как представить отношение «многие ко многим» в XML или другом простом формате файла? - PullRequest
5 голосов
/ 18 июня 2010

У меня есть приложение для управления списками, которое хранит свои данные в базе данных отношений «многие ко многим».

IE. Заметка может быть в любом количестве списков, а список может иметь любое количество заметок.

Я также могу экспортировать эти данные в файл XML и импортировать их в другой экземпляр моего приложения для совместного использования списков между пользователями.Однако это основано на унаследованной системе, в которой связь между списком и записью была один-ко-многим (идеально подходит для XML).

Теперь заметка, находящаяся в нескольких списках, по существу разбивается на две одинаковые строки вБД и все отношения между ними потеряны.

Вопрос: Как я могу представить это отношение «многие ко многим» в простом стандартном формате файла?(Желательно, чтобы XML поддерживал обратную совместимость)

Ответы [ 5 ]

6 голосов
/ 18 июня 2010

Я думаю, что ваш формат 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>

Если, с другой стороны, вы хотите легко видеть списки, связанные с данной заметкой, то вы можете просто инвертировать роли списков и заметок в моем примере.

В качестве альтернативы, вы можете представить отношение многие ко многим более симметрично как математическое отношение: определите все заметки, определите все списки, а затем определите отображение, состоящее из пар [ссылка на список, ссылка на заметку].

3 голосов
/ 18 июня 2010

В базе данных инструментом для представления отношений «многие ко многим» является таблица ассоциаций. Каждая строка в таблице представляет связь между двумя объектами. Таким образом, если заметка с идентификатором 1 появляется в списках с идентификаторами 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, чтобы эти шаблоны не вызывали друг друга до тех пор, пока вы не переполните стек.)

0 голосов
/ 21 апреля 2014

Просто сделайте это просто так:

<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>
0 голосов
/ 18 июня 2010

Мой первый шаг был бы прост:

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

Подходит ли это для ваших нужд?

0 голосов
/ 18 июня 2010

Единственный способ, которым я могу придумать, чтобы по-настоящему представить отношение многие ко многим в 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 не представляет собой примечание для правильного перечисления отношений, что может быть или не быть важным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...