Java / MySQL - делает выбор на ResultSet - PullRequest
1 голос
/ 15 апреля 2011

Итак, я сделал массивный выбор на MySQL и получил много данных, упорядоченных по индексу.
Например:

select * from nodes where config_id = 1;  

Дает (показаны только релевантности)

| definition_id (PK) | position | parent | 
-------------------------------------------
   90                      1         0 << "root"
   08                      2         0
   34                      3         0
   22                      4         0
   17                      1         7  << another defn_id
   38                      2         7
   23                      3         7
   07                      1         90

Если это не имеет смысла, представьте себе определение дерева, где 90, 8, 34 и 22 являются потомками корня.
7 - это потомок 90, а 17, 38, 23 -дети 7 лет (внуки корня).

Чтобы обработать это, мы находим все узлы с родительским 0, добавляем их, затем просматриваем все эти узлы, проверяем, есть ли у них дочерние элементы (отбирая их у родителя или не видя значений).и рассматривая это как лист).Если у них есть дети, добавьте их и продолжайте рекурсивно до тех пор, пока не будет построено дерево.
Это не самое эффективное хранилище данных, но одно из требований - это «изменение одной строки» для перемещения подмножестваузлы и все дети.Я бы лучше определил строку 0.1.6 и т. Д., Но так оно и есть.

Так что в тестировании это работает довольно хорошо, но когда нам нужно делать это 100 000 раз в день (без кеширования - нет смысла, все немного по-другому) - нам нужно сделать это с минимальным количеством обращений к базе данных, каквозможно (т.е. ОДИН).Легко, вы говорите, просто захватите всю партию и обработайте.Но, они не все порядок - как вы можете видеть выше, 90 ниже 7. Да, эти примеры потворствовали, но это иллюстрирует проблему, что нам нужен какой-то порядок.

По сути, в двух словах, вопрос заключается в том, является ли их простой (и, предпочтительно, дешевый) способ сделать дополнительный выбор в ResultSet - т.е. захватить все результаты, где parent == 7, в другой ResultSet и работатьна что?

Вечная любовь и благодарность в обмен на мысли / комментарии.

Ответы [ 4 ]

3 голосов
/ 15 апреля 2011

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

// class to represent your rows
class Row {
    int definitionId;
    int position;
    int parent;
}

// map of parents to list of their rows
Map<Integer, List<Row>> parentMap = new HashMap<Integer, List<Row>>();

// iterate over all results, build row objects and populate the map
while (rs.next()) {
    Row row = new Row();
    row.definitionId = rs.getInt("definition_id");
    row.position = rs.getInt("position");
    row.parent = rs.getInt("parent");

    // find the list of rows for the parent, create it if it doesn't exist
    List<Row> rows = parentMap.get(row.parent);
    if (rows == null) {
        rows = new ArrayList<Row>();
        parentMap.put(row.parent, rows);
    }

    // add row to the list for its parent
    rows.add(row);
}

// find all rows for parent == 7
for (Row row : parentMap.get(7)) {
    // process row
}
1 голос
/ 15 апреля 2011

Мы делаем нечто очень похожее на моей работе.У нас есть преимущество в том, что мы используем oracle, поэтому синтаксис «начать с ... подключиться» - это благословение.Тем не менее, мы используем это только для загрузки в структуру данных в памяти, которая поддерживает функции типа дерева, такие как get_children, брать братьев и сестер, получить родителей и т. Д.эти типы функций.Я не очень хорошо разбираюсь в Java, поэтому я не уверен в реализации, но, надеюсь, это поможет вам начать работу.

0 голосов
/ 15 апреля 2011

Вы можете сделать свой первый выбор во временную таблицу

http://dev.mysql.com/doc/refman/5.1/en/create-table.html

, а затем выполняйте вторичный выбор во временной таблице. Временные таблицы являются «для каждого соединения», так что это может или не может работать для вас.

0 голосов
/ 15 апреля 2011

Вы можете сделать это на уровне СУБД, посмотрите здесь, например, на MySQL http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/.

Ответ WhiteFang34 хорош, потому что mySQL не поддерживает иерархические запросы (вы можете найти его в ORACLE: start ... connect by). Возможно, это будет реализовано в будущем, но теперь мы можем использовать только обходные пути (например, по ссылке). Основная идея состоит в том, чтобы использовать память на компьютере, где работает СУБД и где рекурсивный запрос реализован поставщиком (с оптимизацией, надежными алгоритмами, поддержкой и т. Д.).

Дополнительным обходным решением является написание хранимой процедуры.

...