これを正しく実行し、mysql で優れたパフォーマンスを発揮する方法についての完璧な記事を1 つ知っています (このアイデアを信用することはできません。チェコ語から翻訳しているだけです)。

次のようなツリー構造が必要です。
categories (
id,
lft, -- index on "left iteration" - number on the left
rgt, -- index on "right iteration" - number on the right
depth,
)
完全なツリーを表示する方法:
$result = mysql_query("SELECT * FROM categories ORDER BY lft");
while ($row = mysql_fetch_assoc($result)) {
echo str_repeat("- ", $row["depth"]) . htmlspecialchars($row["data"]) . "<br />";
}
mysql_free_result($result);
ツリー全体を印刷する必要がある場合は、ソートしてlft
書き留めるだけで十分です。ツリーの一部だけを表示する必要がある場合は、両方lft
を制限してrft
、現在のノード値より大きくすることができます。
番号付きリストで表示:
$result = mysql_query("SELECT * FROM categories ORDER BY lft");
$depth = -1;
while ($row = mysql_fetch_assoc($result)) {
if ($depth < $row["depth"]) {
echo "<ul>";
} else {
echo str_repeat("</li></ul>", $depth - $row["depth"]) . "</li>";
}
echo "<li>\n" . htmlspecialchars($row["data"]);
$depth = $row["depth"];
}
echo str_repeat("</li></ul>", $depth + 1) . "\n";
mysql_free_result($result);
順序付きリスト (複数レベル) で表示する場合、現在のノードdepth
と次のアイテムの間の接続を検出する必要があります。
「ブレッドクラム ナビゲーション」用に取得する:
$row = mysql_fetch_assoc(mysql_query("SELECT * FROM categories WHERE id = " . intval($_GET["id"])));
$result1 = mysql_query("SELECT * FROM categories WHERE lft < $row[lft] AND rgt > $row[rgt] ORDER BY lft");
while ($row1 = mysql_fetch_assoc($result1)) {
echo "<a href='?id=$row1[id]'>" . htmlspecialchars($row1["data"]) . "</a> > ";
}
mysql_free_result($result1);
echo htmlspecialchars($row["data"]);
リストの最後に子を追加します。
mysql_query("INSERT INTO categories (lft, rgt, depth, data)
SELECT IFNULL(MAX(rgt), 0) + 1, IFNULL(MAX(rgt), 0) + 2, 0, '" .
mysql_real_escape_string($_POST["data"]) . "' FROM categories");
必要な場所に子ノードを追加する
mysql_query("START TRANSACTION");
$row = mysql_fetch_assoc(mysql_query("SELECT * FROM categories WHERE id = " . intval($_GET["rodic"]) . " FOR UPDATE"));
mysql_query("UPDATE categories SET lft = lft + 2 WHERE lft > $row[rgt]");
mysql_query("UPDATE categories SET rgt = rgt + 2 WHERE rgt >= $row[rgt]");
mysql_query("INSERT INTO categories (lft, rgt, depth, data) VALUES ($row[rgt], $row[rgt]+1, $row[depth]+1, '" . mysql_real_escape_string($_POST["data"]) . "')");
mysql_query("COMMIT");
完全な子を削除
mysql_query("START TRANSACTION");
$row = mysql_fetch_assoc(mysql_query("SELECT * FROM categories WHERE id = " . intval($_GET["id"]) . " FOR UPDATE"));
mysql_query("DELETE FROM categories WHERE lft >= $row[lft] AND rgt <= $row[rgt]");
$rozdil = $row["rgt"] - $row["lft"] + 1;
mysql_query("UPDATE categories SET lft = lft - $rozdil WHERE lft > $row[rgt]");
mysql_query("UPDATE categories SET rgt = rgt - $rozdil WHERE rgt > $row[rgt]");
mysql_query("COMMIT");
このアルゴリズムの詳細(または名前)を知っている場合は、お知らせください
これは PDO を使用して記述することをお勧めします。