我有一些數據集看起來像需要轉換MySQL的記錄,以JSON樹
UID | VALUE | PARENTUID在MySQL中。
我真的很感激,如果有人能告訴我如何把它轉換成一個JSON樹,就像上面那個一樣。
所有的值都是字符串。我嘗試了3個來自StackOverflow的解決方案,但無法讓它們工作。
示例解決方案
Convert PHP array to JSON tree
我有一些數據集看起來像需要轉換MySQL的記錄,以JSON樹
UID | VALUE | PARENTUID在MySQL中。
我真的很感激,如果有人能告訴我如何把它轉換成一個JSON樹,就像上面那個一樣。
所有的值都是字符串。我嘗試了3個來自StackOverflow的解決方案,但無法讓它們工作。
示例解決方案
Convert PHP array to JSON tree
事實證明,關係數據庫在處理樹木可怕。嘗試一種不同的存儲數據的方法可能會更好。如果你對這個模式有自己的想法,那麼你基本上有三個選擇,其中沒有一個是非常好的。
選項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中,除非數據集太大,在這種情況下,您需要爲此任務設計存儲引擎。
當我發佈我的第一個答案時,我想我會說服你找到一種不同的方法。由於沒有做到這一點,並癡迷於酷遞歸算法,這裏是基於我以前的答案中的選項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();
?>
+1的信息,雖然你看起來有點悲觀。 SQL Server有這樣的事情的公共表表達式,它似乎在MySQL中沒有模擬。但肯定有辦法做到這一點;有許多應用程序需要某種分層結構(例如,任何帶有樹形菜單或站點地圖的數據驅動的應用程序)。 –
對於悲觀主義者,我大部分時間都是在與這個問題作鬥爭時遺留下來的。正如這些示例所示,它當然可以完成,但SQL無法遍歷樹。對於SQL引擎未知的n級連接是非常類似的。任何使用標準SQL的東西要麼很慢,要麼很複雜,可能兩者都有。我只是建議採取不同的方法。 – regality
我會嘗試第二個選項。謝謝 –