Рассмотрим приложение блога, в котором есть таблицы для сообщений, категорий и справочная таблица, связывающая сообщение с одной или несколькими категориями. Категории являются иерархическими. Посты могут быть отнесены к любой категории, а не только к конечным узлам.
В таблице категорий есть поле post_count
, которое кэширует количество сообщений, назначенных для определенной категории. Он также имеет столбцы parent_id
, lft
и rght
для MPTT.
Но у него также есть поле under_post_count
, которое кэширует количество отдельных сообщений, назначенных ему или любой из его дочерних категорий. Это полезно, так что вы можете отображать иерархический список категорий с количеством назначенных ему сообщений, или одного из его дочерних элементов , рядом с ним .
Мое приложение дошло до того, что после того, как пост создан с категориями, или его категории отредактированы, или тот, у которого были категории, удалены, у меня есть список идентификаторов категорий старой и новой категорий, чья post_count
поле нуждается в обновлении. Я надеялся, что в следующий раз смогу выполнить один запрос: обновить поля under_post_count
для всех указанных категорий и всех их родителей, указав количество отдельных сообщений, назначенных каждой категории или ее дочерним элементам *. 1019 *.
Вот SQL, необходимый для создания таблиц и некоторых тестовых данных для категорий:
CREATE TABLE `categories` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(11) DEFAULT NULL,
`lft` int(11) DEFAULT NULL,
`rght` int(11) DEFAULT NULL,
`name` varchar(255) NOT NULL,
`post_count` int(11) NOT NULL DEFAULT '0',
`under_post_count` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM;
CREATE TABLE `categories_posts` (
`category_id` int(11) NOT NULL,
`post_id` int(11) NOT NULL,
PRIMARY KEY (`category_id`,`post_id`)
) ENGINE=MyISAM;
INSERT INTO `categories` (`id`, `parent_id`, `lft`, `rght`, `name`) VALUES
(1, NULL, 1, 8, 'Cat 1'),
(4, 1, 2, 3, 'Cat 1.1'),
(5, 1, 4, 5, 'Cat 1.2'),
(6, 1, 6, 7, 'Cat 1.3'),
(2, NULL, 9, 16, 'Cat 2'),
(7, 2, 10, 11, 'Cat 2.1'),
(8, 2, 12, 13, 'Cat 2.2'),
(9, 2, 14, 15, 'Cat 2.3'),
(3, NULL, 17, 24, 'Cat 3'),
(10, 3, 18, 19, 'Cat 3.1'),
(11, 3, 20, 21, 'Cat 3.2'),
(12, 3, 22, 23, 'Cat 3.3');
Выполните это несколько раз, чтобы создать тестовые данные для таблицы categories_posts
:
INSERT IGNORE INTO `categories_posts` (`category_id`, `post_id`)
SELECT `id`, CEILING(10 * RAND()) FROM `categories` ORDER BY RAND() LIMIT 6
Может кто-нибудь понять это, ваша помощь будет высоко ценится?