次のツリー状のテーブル構造を考えてみましょう。
CREATE TABLE nodes(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
parent INTEGER,
descendant_count INTEGER NOT NULL DEFAULT 0,
FOREIGN KEY(parent) REFERENCES nodes(id) ON DELETE CASCADE
);
descendant_count
列には、子孫レコードの数が格納されます。
現在、新しい挿入ごとに値を増やす (または削除するたびに値を減らす) ことにより、手動で維持しています。基本的に、親レコードを取得し続けてから実行します
UPDATE nodes SET descendant_count = (descendant_count + 1) ? WHERE...
ルートに到達するまで、各親で。明らかに、これは深くネストされた構造では非常に遅くなります。
これを達成するためにトリガーを使用することは可能ですか? または、それを行うためのより高速で信頼性の高い方法はありますか?
アップデート - 11.08.03
SQLite は再帰トリガーをサポートしているようです。したがって、1 つのノードのみのカウントを更新すると、トリガーはすべての親ノードのカウントを更新できるはずです。
CREATE TRIGGER setCounts AFTER UPDATE ON nodes
WHEN (NEW.descendant_count <> OLD.descendant_count)
BEGIN
-- subtract old counts
UPDATE nodes
SET descendant_count = descendant_count - OLD.descendant_count
WHERE id = NEW.parent;
-- add new counts
UPDATE nodes
SET descendant_count = descendant_count + NEW.descendant_count
WHERE id = NEW.parent;
END;
調べてみたところ数値は合っているようで、やっぱりこれってありえるの?