Рекурсивное обновление для родительских строк в MySQL

#mysql #recursion

#mysql #рекурсия

Вопрос:

 CREATE TABLE record (
  id INT PRIMARY KEY,
  parent_id INT,
  count INT NOT NULL
)
  

У меня есть таблица, определенная как указано выше. Поле ‘parent_id’ ссылается на родительский элемент строки, поэтому все данные выглядят как n-арное дерево.

Согласно моей бизнес-логике, когда поле ‘count’ строки запрашивается для увеличения (например, на единицу), все узлы-предки (или строки) должны быть обновлены для увеличения поля ‘count’ также на единицу.

Поскольку ожидается, что это поле ‘count’ будет часто обновляться (скажем, 1000 в секунду), я полагаю, что это рекурсивное обновление сильно замедлит работу всей системы из-за огромной каскадной операции записи в СУБД.

На данный момент я думаю, что хранимая процедура — лучший вариант, который я могу выбрать. Если MySQL поддерживает операцию типа ‘connected by’ Oracle, может быть какой-то хитрый способ, но, очевидно, это не так.

Есть ли какой-либо эффективный способ реализовать это?

Заранее спасибо.

Комментарии:

1. Возможно, если вы ПИШЕТЕ намного чаще ПРОЧИТАННОГО, вам не следует обновлять родительские строки. Вместо этого просто выполняйте вычисления при чтении? Если вы изменили структуру данных на модель вложенного набора , это могло бы помочь с вычислением в SELECT.

2. @пользователь730685 Пожалуйста, используйте {} кнопку для ввода исходного кода. Если на этот раз это сделано за вас.

3. @cmmi Это должно было быть ответом, а не комментарием.

Ответ №1:

Когда вы используете хранимые процедуры, вам все равно понадобится рекурсия. Вы только перемещаете рекурсию из исходного кода в базу данных.

Вы можете использовать вложенные наборы для хранения иерархических данных. По сути, вы создаете два дополнительных поля left и right где left < right . Тогда узел e1 является подчиненным узла e2 iff e1.left > e2.left amp;amp; e1.right < e2.right .

Это избавляет от рекурсий ценой более высоких затрат на вставку, удаление и перемещение узлов. С другой стороны, обновления содержимого узла, подобные описанному вами, могут быть выполнены в одном запросе. Это эффективно, потому что индекс может использоваться для извлечения узла и всех его предков в одном запросе.