Эффективное представление Иерархий в В спящем режиме

Я испытываю некоторые затруднения при представлении иерархии объектов в, в спящем режиме. Я искал вокруг и не сумел найти любые примеры, делающие это или подобный - у Вас есть мои извинения, если это - общий вопрос.

У меня есть два типа, которые я хотел бы сохранить, использование Будьте в спящем режиме: Группы и Объекты.
* Группы определяются исключительно комбинацией их имени и их родителя.
* группы расположены во многих деревьях, таких, что у каждой Группы есть нуль или одна родительская Группа.
* Каждый Объект может быть членом нуля или большего количества Групп.

Идеально, я хотел бы двунаправленные отношения, разрешающие мне добираться:
* все Группы, которых Объект является членом
* все Объекты, которые являются членом конкретной Группы или ее потомками.
Я также должен смочь пересечь дерево Группы от вершины для отображения его на UI.

Основная структура объекта была бы идеально похожа на это:

class Group {
    ...
    /** @return all items in this group and its descendants */
    Set<Item> getAllItems() { ... }

    /** @return all direct children of this group */
    Set<Group> getChildren() { ... }
    ...
}

class Item {
    ...
    /** @return all groups that this Item is a direct member of */
    Set<Group> getGroups() { ... }  
    ...
}

Первоначально, я только что сделал простые двунаправленные many-many отношения между Объектами и Группами, такими, что выборка всех объектов в иерархии группы потребовала рекурсии вниз дерево, и выбирающие группы для Объекта были простым методом считывания, т.е.:

class Group {
    ...
    private Set<Item> items;
    private Set<Group> children;
    ...
    /** @return all items in this group and its descendants */
    Set<Item> getAllItems() {
        Set<Item> allItems = new HashSet<Item>();
        allItems.addAll(this.items);
        for(Group child : this.getChildren()) {
            allItems.addAll(child.getAllItems());
        }
        return allItems;
    }

    /** @return all direct children of this group */
    Set<Group> getChildren() {
        return this.children;
    }
    ...
}

class Item {
    ...
    private Set<Group> groups;
    /** @return all groups that this Item is a direct member of */
    Set<Group> getGroups() {
        return this.groups;
    }
    ...
}

Однако это привело к нескольким запросам к базе данных для выборки Объектов в Группе со многими потомками, или для получения всего дерева Группы для отображения в UI. Это кажется очень неэффективным, особенно с глубже, большие деревья группы. Существует ли лучший или стандартный способ представить эти отношения в, в спящем режиме?

Я делаю что-либо, очевидно, неправильное или глупый?


Моя только другая мысль до сих пор была этим: Замените идентификатор группы, родительские и поля имени с уникальной Строкой "пути", которая указывает целую родословную группы, например:
/rootGroup
/rootGroup/aChild
/rootGroup/aChild/aGrandChild

Объединяющая таблица между Группами и Объектами затем содержала бы group_path и item_id.

Это сразу решает две проблемы, которые я переносил ранее:
1. Вся иерархия группы может быть выбрана от базы данных в едином запросе и восстановлена в оперативной памяти.
2. Для получения всех Объектов в группе или ее потомках мы можем выбрать из group_item где group_path ='N' или group_path как и / %'

Однако это, кажется, побеждает точку использования, в спящем режиме. Все приветствующиеся мысли!

5
задан Armand 14 January 2010 в 20:20
поделиться

3 ответа

В моих прошлых проектах я реализовал два разных, но сопоставимых решения этой проблемы.

Наиболее важные (с точки зрения производительности) было основано на том факте, что у меня было много разных деревьев умеренного размера. Вместо того, чтобы отображать все листья дерева с использованием двунаправленных отношений, каждый отпуск получил отношение к корню деревьев и второй к их прямому родителю.

Используя эту стратегию, это было довольно легко идентифицировать все корневые узлы (от дерева T где t.parent - это нулевой), и было действительно легко получить полное дерево на основе корневого элемента (от дерева T где t.root = :корень).

Отношения «Установленные дети» было объявлено атрибутом @transient. Используя простую коммунальную операцию, было довольно легко восстановить оригинальную древесную структуру в любое время.

Другое решение с небольшим количеством действительно больших древовидных структур. Но, к счастью, эти структуры имели ограниченную глубину. Вместо того, чтобы использовать только один корень, я сопоставил несколько (6, если я запомню правильно) уровни «родителей». Таким образом, это было легко получить и реконструировать полные поддеревы от базы данных.

(Эти отношения на уровне 1 уровня6 были отображены как «ленивые отношения« ленивые », и приложение было тяжело зависеть от кэшей 2-го уровня.)

3
ответ дан 13 December 2019 в 22:08
поделиться

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

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

Самая большая разница между ними является вашим конкретным случаем использования. Если это веб-сервер, вытягивая весь график в память Убейте сервер. В любом случае, большинство людей не могут обрабатывать более 7-10 вариантов, и весь график может легко подавить пользователь с вариантами, что сложно навигаться по UI.

Также помните эти правила оптимизации:

  1. не
  2. серьезно, не. Это дешевле бросить аппаратное обеспечение на проблему производительности, то оптимизирует ваш код до точки, который больше не поддерживается.
  3. Если вы думаете, что вы должны найти узкое место 1 , используя инструмент профилирования и исправить его.
4
ответ дан 13 December 2019 в 22:08
поделиться

Посмотрите на вложенные множества. Вот хорошая статья:

http://www.developersdex.com/gurus/articles/112.asp

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

2
ответ дан 13 December 2019 в 22:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: