2011-09-02 2 views
1

У меня есть несколько наборов данных, которые выглядят какнеобходимо преобразовать MySQL записей в формате JSON дерево

UID | VALUE | PARENTUID в MySQL.

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

Все значения являются строками. Я попробовал 3 решения от StackOverflow, но не смог заставить их работать.

пример решения

Convert PHP array to JSON tree

ответ

2

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

Вариант 1:

Если вы знаете корень дерева и знать глубину дерева:

SELECT uid, value, parent_uid 
FROM your_table level1 
LEFT JOIN your_table level2 ON uid = parent_uid 
    ON level1.uid = level2.uid 
LEFT JOIN your_table level2 ON uid = parent_uid 
    ON level3.uid = level3.uid 
/* repeat the join until you have gone enough levels down */ 
WHERE uid = 7 /* or whatever the uid is */ 
ORDER BY parent_uid, uid 

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

Вариант 2

Если вы знаете корень дерева, а не глубина:

<?php 
$root_id = 7; 
$id_list = array($root_id); 
$tree = array(); 
while (!empty($id_list)) { 
    $new_list = array(); 
    foreach ($id_list as $id) { 
     $query = "SELECT * FROM your_table WHERE parent_uid = '$id'"; 
     $results = mysql_query($query); 
     while ($next = mysql_fetch_array($results)) { 
      array_push($new_list, $next['uid']); 
     } 
     // find the item in $tree and add it, also ugly 
    } 
    $id_list = $new_list; 
} 
echo json_encode($tree); 

Несмотря быть более гибкими эта опция медленнее и уродливее.

Вариант 3:

<?php 
$query = "SELECT * FROM your_table ORDER BY parent_uid"; 
$result = mysql_query($query); 
$tree = array(); 
while ($next = mysql_fetch_array($result)) { 
    // attach the item to $tree, this is slow and/or ugly code 
} 
echo json_encode($tree); 
?> 

Этот код требует, чтобы получить всю таблицу из MySQL, плюс это своего рода медленно.

Вывод:

я не испытывал какой-либо из этих образцов кода, потому что все они сосут. Найдите другой метод хранения деревьев. SQL просто отстой для этой работы. Возможно, вы захотите сохранить его в xml или json для начала, если набор данных слишком велик, и в этом случае вам понадобится механизм хранения, предназначенный для этой задачи.

+0

+1 для информации, хотя вы выглядите немного пессимистично. SQL Server имеет общие выражения таблицы для такого рода вещей, которые, по-видимому, не имеют аналогов в MySQL. Но, конечно, есть способы сделать это; существует множество приложений, которые требуют какой-то иерархической структуры (например, любое управляемое данными приложение с древовидным меню или карта сайта). –

+0

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

+0

Я попробую второй вариант. спасибо –

0

Проверьте функцию json_encode, которая включена в PHP. Эта функция создаст объект JSON из заданного массива.

Примеры в документах должны предоставить достаточную помощь.

+1

Его не просто массив, его дерево. –

2

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

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

Вам нужно будет работать с функцией to_array(), чтобы сделать json так, как вы хотите, но это должно заставить вас сесть.

<?php 

Class Node { 
    public $id; 
    public $parent_id; 
    public $value; 
    public $children; 
    public $depth; 

    function __construct($id, $parent_id, $value) { 
     $this->id = $id; 
     $this->parent_id = $parent_id; 
     $this->value = $value; 
     $this->children = array(); 
     $this->depth = 0; 
    } 

    function get_children_from_mysql() { 
     $query = "SELECT * FROM your_table WHERE parent_uid = '$this->id'"; 
     $results = mysql_query($query); 
     while ($next = mysql_fetch_array($results)) { 
     $next_node = new Node($next['uid'], $next['parent_uid'], $next['value']); 
     $this->children[$next_node->id] = $next_node; 
     $next_node->get_children_from_mysql(); 
     } 
    } 

    function to_array() { 
     if (count($this->children) > 0) { 
     $arr = array(); 
     foreach ($this->children as $child) { 
      array_push($arr, $child->to_array()); 
     } 
     return array($this->value => $arr); 
     } else { 
     return $this->value; 
     } 
    } 

    function to_json() { 
     return json_encode($this->to_array()); 
    } 

} 

// you need to know the root uid/value or get it from mysql 
$root_uid = 1; 
$root_value = "root node value"; 
$root = new Node($root_uid, 0, $root_value); 
$root->get_children_from_mysql(); // magical recursive call 

echo $root->to_json(); 

?> 
Смежные вопросы