2010-04-07 5 views
10

У меня есть таблица MySQL, который представляет данные для компонента GUI дерева, вот структура моего стола:Как выбрать всех родителей узла в иерархической таблице mysql?

treeTable ( 
    id INT NOT NULL PRIMARY KEY, 
    parentId INT, 
    name VARCHAR(255) 
); 

parentId является автореферентным внешним ключом.

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

Например, предположим, что моя таблица заполнена с этими данными:

1, null, 'root' 
2, 1 , 'level_1' 
3, 2 , 'level_2' 

Теперь я хочу, чтобы получить все родительские узлы узла 3 (узлы 1 и 2) и возвращает результирующий набор, содержащий все дерево записей. Может ли кто-нибудь помочь мне, пожалуйста?

+0

Посмотрите на эту тему: [иерархическая-данных в MySQL-] [1] [1]: http://stackoverflow.com/questions/1085287/hierarchical-data-in- MySQL – 2012-04-15 13:41:48

ответ

2

Хороший вопрос. В Oracle вы бы использовали что-то вроде CONNECT BY.

Поскольку вы используете MySQL, я бы предложил вам изменить структуру данных, чтобы эффективно ответить на этот запрос. Here - некоторые идеи.

1

There was a similar discussion к этому, что может быть полезно при решении этой проблемы.

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

1

Посмотрите here в разделе «Извлечение единого пути». Но лучше использовать вложенный набор , будет намного проще работать с деревом. Также я рекомендую прочитать презентацию «Trees In The Database - Advanced data structures».

1

Существует также materialized paths, чтобы о нем подумать. Довольно простая концепция, которая на самом деле является агностикой базы данных. Намного проще управлять вставками и т. Д., В отличие от вложенных наборов, вам не нужно знать, что вы левый/правый узлы и т. Д. Перед вставкой.

1

MySQL не поддерживает функции, связанные с таблицей 18.2.1. Stored Routine Syntax (это то, что вам нужно, чтобы вернуть произвольный набор результатов).

Без них у вас есть три варианта:

  1. раскатать дерево запрос к фиксированной максимальной глубине и ограничивают допустимые вложенности в иерархии,
  2. использовать цикл для записи данных во временную таблицу и ввести какое-либо соглашение, чтобы вернуть результаты вызывающему. Вам нужно будет рассмотреть возможность повторного ввода, или
  3. предварительно вычислить результаты, включив всех предков каждого компонента в таблицу поддержки (как показано) и сохраните ее с помощью триггеров на treeTable. Таким образом, хранимая процедура возвращает соответствующие строки в parentTable. Вам потребуется создать составной первичный ключ и, возможно, индексы для эффективного доступа.

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

parentTable (
    id INT NOT NULL, 
    parentId INT NOT NULL 
); 

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