Yandex Metrika
sanches.free 25 просмотров

Статистика коротких ссылок Битрикс по дням: триггеры к 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 дней гарантии