Статистика коротких ссылок Битрикс по дням: триггеры к b_short_uri
Что уже есть в ядре
Короткие адреса хранятся в b_short_uri. При срабатывании редиректа поле NUMBER_USED растёт, а LAST_USED обновляется — отдельной «матрицы день × ссылка» в базе по умолчанию нет. Если нужна накопительная дневная картина, один из вариантов с минимальным кодом на PHP — добавить вторую таблицу и логировать изменения триггерами.
Схема b_short_uri как ориентир
В разных редакциях движка размер типов может чуть различаться; логику ниже этого достаточно. Важнее запомнить, что переход связан именно с UPDATE нужной строки, а добавление записи создаёт нулевой счётчик.
CREATE TABLE `b_short_uri` (
`ID` int NOT NULL AUTO_INCREMENT,
`URI` varchar(250) NOT NULL,
`URI_CRC` int NOT NULL,
`SHORT_URI` varbinary(250) NOT NULL,
`SHORT_URI_CRC` int NOT NULL,
`STATUS` int NOT NULL DEFAULT 301,
`MODIFIED` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`LAST_USED` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
`NUMBER_USED` int NOT NULL DEFAULT 0,
PRIMARY KEY (`ID`),
KEY `ix_short_uri_crc` (`SHORT_URI_CRC`),
KEY `ix_uri_crc` (`URI_CRC`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;Таблица распределения по датам
Составной первичный ключ (ID, DATE) позволит одному идентификатору короткой ссылки накапливать по одному счётчику на календарный день без дублей строк.
CREATE TABLE `short_uri_daily_hits` (
`ID` int UNSIGNED NOT NULL,
`HIT_DAY` date NOT NULL,
`HITS` int UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`ID`, `HIT_DAY`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;Два триггера
При появлении новой строки в b_short_uri имеет смысл сразу зафиксировать «нулевой» день, чтобы статистические отчёты видели хотя бы старт записи — при желании строку можно не добавлять и ограничиться только вторым триггером. Перед любым изменением строки исходной таблицы прибавляют единицу к столбцу текущего дня; при первом переходе в этот день срабатывает вставка, при повторных — ON DUPLICATE KEY.
DROP TRIGGER IF EXISTS `tr_b_short_uri_after_insert_daily`;
DROP TRIGGER IF EXISTS `tr_b_short_uri_before_update_daily`;
DELIMITER $$
CREATE TRIGGER `tr_b_short_uri_after_insert_daily`
AFTER INSERT ON `b_short_uri`
FOR EACH ROW BEGIN
INSERT IGNORE INTO `short_uri_daily_hits` (`ID`, `HIT_DAY`, `HITS`)
VALUES (NEW.ID, CURDATE(), 0);
END$$
CREATE TRIGGER `tr_b_short_uri_before_update_daily`
BEFORE UPDATE ON `b_short_uri`
FOR EACH ROW BEGIN
INSERT INTO `short_uri_daily_hits` (`ID`, `HIT_DAY`, `HITS`)
VALUES (NEW.ID, CURDATE(), 0)
ON DUPLICATE KEY UPDATE `HITS` = `HITS` + 1;
END$$
DELIMITER ;Выборки и ограничения
Отчёт за неделю — обычный SELECT с фильтром по HIT_DAY и при необходимости соединением с b_short_uri для человекочитаемого URI.
Не забывайте: любому UPDATE строки посчитается как событие, не только переход пользователя по ссылке — на практике ядро трогает запись главным образом при редиректе, но кастомные скрипты могут давать паразитные импульсы.
На шаринг-хостинге триггеры иногда недоступны без повышенных привилегий и их приходится включать только на сервере, где вы управляете схемой. После дампа базы между стендами проверьте наличие триггеров отдельно от таблиц.
Не хотите копаться сами?
Починю за 1-3 дня. Без предоплаты — оплата по результату.
15+ лет опыта с 1С-Битрикс · Без предоплаты · 7 дней гарантии