Mysql Как в MySQL-триггере обновить родительскую запись в той же таблице?

Valery Shostak

Новичок
Дано:
Таблица comments с полями id, parent_id и child_count.

Задача:
После добавления дочернего комментария инкрементировать значение child_count у родительского.

Поскольку обновлять ту же таблицу в триггере запрещено, появляется следующая ошибка:
Can't update table in stored function/trigger because it is already used by statement which invoked this stored function/trigger

Какие существуют пути решения (или обхода) данной задачи?
 

fixxxer

К.О.
Партнер клуба
Из триггера - никак.

Если хочется извращений (судя по использованию триггеров, хочется), можно сделать хранимую процедуру, которая будет вставлять детку и инкрементить счетчик у родителя.

Ну еще есть скучный вариант - сделать так, как делают все нормальные люди - из php-кода.
 

Valery Shostak

Новичок
Я не согласен, что триггеры - это извращение. Это инструмент, решающий вполне конкретные задачи.
А вот предложенный вами скучный вариант - это и есть самое настоящее извращение. Сейчас объясню почему.
В этой теме я всего лишь привёл простой пример, чтобы остальным легко было разобраться. На самом деле, задача куда сложнее.
Во-первых, нужно обновлять счётчик не только по добавлении, но и при изменении и удалении.
Во-вторых, существует ещё флаг hidden, который так же влияет на счётчик.
В-третьих, все эти операции делаются в разных местах кода и разными способами.
Поэтому использовать триггеры в данной ситуации - самый разумный выбор. Даже если это придётся делать через хранимую процедуру.
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
У тебя, имхо, это логика приложения, и совать ее в базу - явно неверно.

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

Valery Shostak

Новичок
Почему это логика приложения, можешь объяснить?
К примеру, аналогичные вещи (счётчики комментариев и оценок для материалов) сделаны у меня именно через триггеры. Их тоже, по-твоему, нужно было делать через PHP?
Рефакторинг тут совершенно не при чём.
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Счетчик комментов не более, чем денормализованное поле в таблице. При вставке коммента обновляется эвентом приложения или просто запросом. Но ты конечно можешь сделать триггер.
 

fixxxer

К.О.
Партнер клуба
Чем события ORM так принципиально отличаются от триггеров?

Если программировать по курсам Попова, тогда даю понимаю, проблема
 

Yoskaldyr

"Спамер"
Партнер клуба
Мммм... Бизнес логика на триггерах в мускуле... Месье знает толк в извращениях!
 

Valery Shostak

Новичок
Господа, вроде вопрос был не про бизнес-логику, события приложения и то как это нужно делать правильно на ваш взгляд.
По сути, был предложен только вариант с хранимой процедурой. Неужели это единственное решение?..
 

fixxxer

К.О.
Партнер клуба
Ещё можно сменить СУБД. Скажем, Постгрес позволяет так делать (и легко отстрелить себе ногу рекурсией).
 

Yoskaldyr

"Спамер"
Партнер клуба
Ну зачем постгрес - лучше сразу на оракл и вообще все писать на нем, только зачем тогда пхп???? Разве что для использования в качестве шаблонизатора (и то сомнительно)
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Ну зачем постгрес - лучше сразу на оракл и вообще все писать на нем, только зачем тогда пхп???? Разве что для использования в качестве шаблонизатора (и то сомнительно)
НАписать страничку, чтобы пиццу заказывать...
 

Yoskaldyr

"Спамер"
Партнер клуба
то сравнение-то во многих аспектах получится не в пользу оракла
Ну оракл это больше о "супер пупер корпоративном" ПО за мульйоны, а не о пользе :)
Чего столько стоят ЗП сертифицированных оракловских ДБ админов...
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
а чего они стоят?
мне показалось, что оракловская бд - это просто неудобно в установке, даже из ORM-пакета, который ставится без активаций,
в самом оракле предпочитают mysql, oracle db - только для специализированных задач вроде гео-расчетов
хотя, драйвер для php они допилили
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Во-первых, нужно обновлять счётчик не только по добавлении, но и при изменении и удалении.
Во-вторых, существует ещё флаг hidden, который так же влияет на счётчик.
В-третьих, все эти операции делаются в разных местах кода и разными способами.
Поэтому использовать триггеры в данной ситуации - самый разумный выбор. Даже если это придётся делать через хранимую процедуру.
еще надо будет добавить такие хранимые процедуры:
* обновление комментария
* добавление коммента без инкремента (рекламный, НЛО a-la habr, еtc)
* выставление значения счетчика
* скрытие коммента без декремента
* объединение комментов с пересчетом счетчика
и не проще ли разреженное бинарное дерево реализовать?
 

SSecurity

Новичок
Создайте таблицу с информацией по чаилдам и обновляйте там, хоть активные, хоть скрытые, хоть все от Маши Ивановой:)
Так вы обойдете ограничение на обновление по триггеру, но не очень понятно зачем вам знать сколько у коммента чаилдов, особенно если вы их перед выводом в массив соберете и там сразу будет все видно.
 

fixxxer

К.О.
Партнер клуба
Ну как зачем, чтобы число комментариев показать на странице со списком постов. Тут же каждый пишет не менее чем фейсбук, count+group by тормозить будет!
 

SSecurity

Новичок
Ну как зачем, чтобы число комментариев показать на странице со списком постов. Тут же каждый пишет не менее чем фейсбук, count+group by тормозить будет!
Отдельная таблица, по сути и есть стата, в которой суммировать надо (записей меньше, отработает быстрее), только пользователю непонятно зачем это :)
Хотя если там 50-60 млн. комментов...:) А если влом тратить ресурс на это так надо триггер натравить на обновление 1 строки с ИТОГО:)
 

WMix

герр M:)ller
Партнер клуба
Отвечая на изначальный вопрос. При before insert/update надо изменить new.имя_поля

Но это касается той же записи
 
Сверху