Використання MySQL events для запуску SQL-процедур за розкладом
Ви можете запускати деякі дії в MySQL за розкладом. Головна перевага порівняно з можливостями фреймворку полягає в тому, що ви не будете обмежені лімітами PHP.
Розглянемо приклад. Ми будемо використовувати MySQL для архівування замовлень, виконаних більше місяця тому.
Існують таблиці, пов’язані як many-to-many:
- orders
- products
- order_product (the pivot table)
Також є табліця «payments».
Архівувати записи ми будемо у таблиці
- archive_orders
- archive_order_product
- archive_payments
Спочатку ми створюємо процедуру move_orders_to_archive:
CREATE PROCEDURE IF NOT EXISTS move_orders_to_archive() BEGIN DECLARE n int default 0; UPDATE `orders` SET `status`='archived' WHERE `status`='completed' AND `updated_at` <= DATE_ADD(Now(), INTERVAL -1 MONTH); SET n = ROW_COUNT(); IF n > 0 THEN INSERT IGNORE INTO `archive_orders` SELECT * FROM `orders` WHERE `status`='archived'; INSERT IGNORE INTO `archive_order_product` SELECT `order_product`.* FROM `order_product` INNER JOIN `orders` on (`order_product`.`order_id`=`orders`.`id`) WHERE `orders`.`status`='archived'; INSERT IGNORE INTO `archive_payments` SELECT `payments`.* FROM `payments` INNER JOIN orders on (`payments`.`order_id`=`orders`.`id`) WHERE `orders`.`status`='archived'; DELETE `payments`.* FROM `payments` INNER JOIN `orders` on (`payments`.`order_id`=`orders`.`id`) WHERE orders.status='archived'; DELETE `order_product`.* FROM `order_product` INNER JOIN `orders` on (`order_product`.`order_id`=`orders`.`id`) WHERE `orders`.`status`='archived'; DELETE FROM `orders` WHERE `status`='archived'; END IF; END
Зверніть увагу: потенційно довгі запити йдуть один за одним. PHP був би змушений чекати і, можливо, не отримав би відповідь на запит.
Ми мусимо увімкнути MySQL Scheduler:
SET GLOBAL event_scheduler = ON
Тепер ми можемо створювати event:
CREATE EVENT archiving ON SCHEDULE EVERY 1 DAY STARTS '2026–07–26 01:00:00' COMMENT 'Archive orders completed more than a month ago' DO CALL move_orders_to_archive();
Ось і все! Тепер щодня о 1 годині ночі замовлення будуть архівуватися.
4 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарівЗупинить цього мудреця
Читав про це у книжці, ніколи не бачив на практиці, дякую, цікаво
Краще так не робити, у вас має бути сепарація консернів. В даному випадку ви робите базу single point of failure
==В даному випадку ви робите базу single point of failure==
Навіть якщо в цій простій процедурі щось піде не так — хіба це позначиться якось на роботі системи?