2012-12-14 116 views
0

我有嵌套集表(MySQL),其中有大約150萬條記錄。 表結構是:MySQL查詢獲取嵌套集的節點的完整路徑

id | name | root_id | lft | rgt | level 

我需要得到的字符串,包含所有的父記錄加上記錄名稱名稱,姑且稱之爲「FULL_NAME」。 例如,對於「洛杉磯」記錄將是

"United States, California, Los Angeles" 

我可以查詢所有名字ONE紀錄:

SELECT parent.name 
FROM location AS node, 
    location AS parent 
WHERE node.lft BETWEEN parent.lft AND parent.rgt 
     AND parent.root_id=node.root_id AND node.id=:id 
ORDER BY parent.level 

,並建立使用FULL_NAME破滅()

但這一要求適用於只有一個記錄,有以下幾個呼叫過於緩慢的工作。 所以現在我想給獅身人面像索引添加'full_name'(或者直接添加到MySQL)。

問題:

  • 是否有可能建立這樣的SQL查詢,將選擇「FULL_NAME」每個記錄把它放到獅身人面像索引?我認爲這將是這種情況的理想解決方案。

  • 我也嘗試更新MySQL表添加'full_name'字段,但我的更新請求將需要幾天才能完成作業。這是好主意嗎?是否有可能使此更新足夠快?

  • 我在想,也許我應該搬到PostgreSQL和使用分層請求(我沒有這個數據庫的經驗,所以不能確定)?

謝謝

+0

另外還有一個提示:層數不是預定義的。 – yuga

+0

對不起,這不是表格定義:'id |名稱| root_id | lft | rgt | level'。也許真正的人需要的不僅僅是你的簡短表示法。 – wildplasser

回答

0

當你說要更新表中添加的FULL_NAME場,你的意思是,你正在運行上面的查詢,用於單獨每一個記錄?

真的不應該那麼慢,你有適當的索引在桌子上嗎?

無論如何,只需運行一個實際查詢即可更快地獲取所有記錄。這裏的功能: http://www.sitepoint.com/hierarchical-data-database-2/

可以很容易地修改,以更新所有的記錄。只是不是打印出一個縮進列表,循環的每個迭代都應該運行一個更新語句。除了維護$ right數組外,還需要維護一個字符串列表。在右側添加/刪除的地方可以同時添加另一個陣列。

// start with an empty $right stack 
$right = array(); 
$names = array(); 

// now, retrieve whole tree 
$result = mysql_query('SELECT id, name, full_name, lft, rgt FROM location ORDER BY lft ASC'); 

// update each row 
while ($row = mysql_fetch_array($result)) { 
    // only check stack if there is one 
    if (count($right)>0) { 
     // check if we should remove a node from the stack 
     while ($right[count($right)-1]<$row['rgt']) { 
      array_pop($right); 
      array_pop($names); 
     } 
    } 

    // add this node to the stack 
    $right[] = $row['rgt']; 
    $names[] = $row['name']; 

    if (empty($row['full_name'])) { 
     mysql_query("UPDATE location SET full_name='".mysql_real_escape_string(implode(', ',$names))."' WHERE id=".intval($row['id'])); 
    } 
} 

如果這仍然緩慢,而不是更新原始表,插入FULL_NAME(包含ID)到一個新表 - 這並不具有任何索引。更改表以在id列上添加索引,然後運行多表更新,以便從臨時表中更新主表。這樣做會更快,因爲它不會逐個更新主要索引,而是在一個大批量上進行。

+0

非常感謝。你對索引是正確的(愚蠢的我錯過了他們沒有成立)。我也在研究你給出的其他建議,他們看起來也很有希望。 – yuga