Лучший способ хранить иерархические теги - PullRequest
6 голосов
/ 14 июня 2011

У меня есть список, где каждая запись списка помечена несколькими тегами.Каждый тег также может иметь дочерние теги.Каждая запись в списке может иметь более одного тега.

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

Я должен иметь возможность просматривать иерархию тегов, как показано ниже.Кроме того, не должно быть никаких ограничений на количество тегов на запись, а также на то, насколько глубокими могут быть теги.

Как мне сохранить эти данные?Я открыт для использования любого типа СУБД.

enter image description here

Ответы [ 6 ]

5 голосов
/ 14 июня 2011

Наивным подходом было бы родительское / дочернее решение, но очень сложно написать эффективные запросы с этой моделью данных.

Управление иерархическими данными в MySQL - довольно хорошая статья об иерархических структурах данных. Я полагаю, что большинство из них можно применить и к другим системам баз данных.

4 голосов
/ 14 июня 2011

Я думаю, что это самый простой способ для любой базы данных: tag (id, name, parent_id), где parent_id относится к id родительского тега.

1 голос
/ 14 июня 2011

Вы используете 2 источника данных, но, похоже, вы смешиваете оба.

Одними данными являются записи в вашем списке, которые кажутся линейными, не иерархическими.

Например, список фильмов.

Другой источник данных, это набор иерархических данных («каталог тегов»).

Например, список стилей фильма.

+---Styles
  +---Comedy
    +---KidsComedy
    +---SomeComedy
    +---LOLComedy
  +---Action
    +---SomeAction
    +---GrabYourCouchSofaAction
  +---Drama
    +---SomeDrama
    +---LotsOfTearsDrama
    +---EvenToughGuysWillCryDrama
  +---Horror
    +---SoftHorror
    +---HardHorror
    +---Gore
  +---SciFi

Каждый фильм может быть связан с несколькими стилями фильма:

  • "StarWars: Призрачная угроза": {"SciFi," SomeDrama "," SoftHorror "," SomeAction "}
  • "StarTrek: Первый контакт": {"SciFi," SomeDrama "," SomeComedy "}

С точки зрения дизайна базы данных, вы должны иметь как минимум 3 таблицы или объекты сущности:

  • Список записей = {ListEntryID, ListEntryTitle, ...}
  • Теги / стили жанров фильма = {TagID, TagTitle, ...}
  • Стили для фильма = {TagForListEntryID, ListEntryID, TagID, ...}

Удачи.

0 голосов
/ 09 августа 2011

См. мой ответ здесь .Я храню родителей для всех уровней - строить дерево и опрашивать всех потомков чрезвычайно легко.

0 голосов
/ 15 июня 2011

Вот как я бы подошел к проблеме: во-первых, я нарисую модель предметной области. В вашем случае это выглядит так:

List(1)----contains----(0..*)-->ListItem
ListItem(0..1)----hasTags--(0..*)-->Tag
Tag(0..1)-----hasSubTags---(0..*)-->Tag

Это делает проблему явной, не оставляя места для сомнений.

Теперь переведите это в модель данных. Это довольно просто: для каждого отношения введите подходящие отображения PrimaryKey-ForeignKey. Отношения «многие ко многим» следует разбить на два отношения «1-M», используя новую таблицу между ними.

Модель данных, которая у вас есть на этом этапе, должна быть функционально правильной, но может иметь проблемы с производительностью. Сейчас самое время сосредоточиться на запросах, которые вы хотели бы, и соответственно оптимизировать структуру таблицы.

(Еще одно подобное уточнение, начинающееся с модели предметной области, даст вам дизайн и для модели окончательного класса)

Надеюсь, этот подход поможет.

0 голосов
/ 14 июня 2011

Используйте формат XML, который поможет вам сохранить узлы как родительский и дочерний. Он может иметь n узлов и легко формироваться и обрабатываться.Примечание. Приведенный ниже пример только для примера. Таким образом, вы можете обрабатывать данные.

<Menu>
  <Menuitem1>
      <submenu1>
         <submenu1>
            <submenu1.1/> 
          </submenu1>        
      </submenu1>
  </Menuitem1>

  <Menuitem1>
      <submenu1>
      </submenu1>
  </Menuitem1>
</Menu>

Думаю, это может вам помочь.

...