У меня есть дерево, закодированное в базе данных MySQL как ребра:
CREATE TABLE items (
num INT,
tot INT,
PRIMARY KEY (num)
);
CREATE TABLE tree (
orig INT,
term INT
FOREIGN KEY (orig,term) REFERENCES items (num,num)
)
Для каждого листа в дереве кто-то устанавливает items.tot
. Для внутренних узлов items.tot
должно быть суммой его дочерних элементов. Повторный запуск следующего запроса приведет к желаемому результату.
UPDATE items SET tot = (
SELECT SUM(b.tot) FROM
tree JOIN items AS b
ON tree.term = b.num
WHERE tree.orig=items.num)
WHERE EXISTS
(SELECT * FROM tree WHERE orig=items.num)
(обратите внимание, что это на самом деле не работает, но это не относится к делу)
Предположим, что база данных существует и инвариант уже выполнен.
Вопрос:
Каков наиболее практичный способ обновления БД при соблюдении этого требования? Обновления могут перемещать узлы или изменять значение tot
на конечных узлах. Можно предположить, что листовые узлы останутся как листовые узлы, внутренние узлы останутся как внутренние узлы, и все это останется как собственное дерево.
Некоторые мысли, которые у меня были:
- Полная недействительность, после любого обновления пересчитать все (Гм ... Нет)
- Установить триггер в таблице элементов для обновления родителя любой строки, которая обновляется
- Это было бы рекурсивно (обновления запускают обновления, запускают обновления, ...)
- Не работает, MySQL не может обновить таблицу, которая сработала триггер
- Установить триггер для планирования обновления родительского элемента любой строки, которая обновляется
- Это было бы итеративно (получить элемент из расписания, обрабатывая в нем больше элементов)
- Что вызывает это? Доверьтесь клиентскому коду, чтобы получить его правильно?
- Преимущество состоит в том, что, если обновления упорядочены правильно, на компьютере должно быть меньше сумм. Но это упорядочение само по себе является осложнением.
Идеальное решение будет обобщать на другие "агрегирующие инварианты"
FWIW Я знаю, что это «немного за бортом», но я делаю это для развлечения (Fun: глагол, найти невозможное, делая это.