2014-11-26 4 views
2

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

В таблице я запрашивая от находится на AS/400 и каждая запись хранит единственную часть одного шага, так что если я имел PartOne и три компоненты идут в ней есть запись для каждого типа:

PartOne ComponentOne, PartOne ComponentTwo, PartThree ComponentThree. 

важно отметить, если есть компоненты для ComponentOne последующего строка может содержать:

ComponentOne SubComponentOne, ComponentOne SubComponentTwo. 

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

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

  1. Извлечь номер детали, таблицу запросов для компонентов, когда это созданная часть.
  2. Возьмите эти компоненты и запросите их как созданную часть и получите их компоненты.
  3. Повторяйте до тех пор, пока запрос не возвращает записи.

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

+1

MySQL не поддерживает рекурсивные запросы. есть хаки с фанковыми структурами данных, чтобы подделать его, но они становятся довольно уродливыми: http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ –

+0

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

+0

Спасибо за ссылку, я собираюсь сделать это с этим. Я прочитал, что он не поддерживает рекурсивные запросы, поэтому я предполагаю, что я задавал больше вопросов о лучших способах структурирования своих нерекурсивных запросов, чем 7 вложенных. Когда я упомянул о рекурсии, я больше искал создание рекурсивного метода для генерации тех нерекурсивных запросов. – bmac

ответ

0

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

Это строит дерево для записей в таблице категорий, начиная с id -1000 в качестве корневого элемента, используя только столько запросов, сколько количества уровней, в которых вы хотите получить информацию.

Структура таблицы:

TABLE categories (
    id   INT NOT NULL PRIMARY KEY, 
    parent_id INT NULL, 
    name  NVARCHAR(40) NOT NULL 
) 

PHP код:

class Bom { 
    public $Id; 
    public $Name; 
    public $Components = array(); 

    function __construct($id, $name) { 
     $this->Id = $id; 
     $this->Name = $name; 
    } 
} 

$parentIds = array(-1000); // List of id's to lookup 
$rootBom = new Bom(-1000, 'Root'); 
$bomsById[ -1000 ][] = $rootBom; // For each id there can be multiple instances if we want separate instances of Bom for each time it occurs in the tree 
$maxLevel = 0; 

while (count($parentIds) > 0 
    && $maxLevel++ < 10 
    && $result = $mysqli->query("SELECT * FROM categories WHERE parent_id IN (" . implode(", ", $parentIds) . ") ORDER BY name")) 
{ 
    $parentIds = array(); // Clear the lookup list 
    $newBomsById = array(); 
    while ($row = $result->fetch_assoc()) 
    { 
     $boms = $bomsById[ $row[ 'parent_id' ] ]; 
     if ($boms) 
     { 
     foreach ($boms as $bomToUpdate) 
     { 
      $compontentBom = new Bom($row[ 'id' ], $row[ 'name' ]); 

      $bomToUpdate->Components[] = $compontentBom; 
      $newBomsById[ $compontentBom->Id ][] = $compontentBom; 
     } 

     $parentIds[] = $row[ 'id' ]; // Build new list of id's to lookup 
     } 
    } 

    $bomsById = $newBomsById; 
} 

echo '<!-- 
' . print_r($rootBom, true) . ' 
-->'; 
Смежные вопросы