you can optimize your solution as follows. since the updates cascade recursively up your tree, this is a substantial savings...
CREATE TRIGGER setCounts AFTER UPDATE ON nodes
WHEN (NEW.descendant_count <> OLD.descendant_count)
BEGIN
IF NEW.parent_id IS NOT NULL THEN
UPDATE nodes
SET descendant_count = descendant_count
+ NEW.descendant_count - OLD.descendant_count
WHERE id = NEW.parent;
END IF;
END;
furthermore you must be handle the case where you reassign parents. eg:
update node set parent_id = 20 WHERE parent_id = 10
for that you need another trigger
CREATE TRIGGER setCounts2 AFTER UPDATE ON nodes
WHEN (NEW.parent_id <> OLD.parent_id)
BEGIN
IF OLD.parent_id IS NOT NULL THEN
UPDATE nodes SET descendant_count = descendant_count - OLD.descendant_count
WHERE id = OLD.parent;
END IF;
IF NEW.parent_id IS NOT NULL THEN
UPDATE nodes SET descendant_count = descendant_count + NEW.descendant_count
WHERE id = NEW.parent;
END IF;
END;