Skip to content

Ru:TaggableSmartHandler

Alexey Denisov edited this page Feb 4, 2014 · 10 revisions

TaggableDaoWorker + TaggableSegmentHandler

Пока проще всего получилось описать работу этих классов на примерах.

Пусть у нас есть две таблицы и соотвествующие бизнес объекты - User и City (таблицы users и cities). Каждый из пользователей имеет обязательное свойство city ссылающееся на город. У этих таблиц/объектов могут быть дополнительные поля/аттрибуты, вроде name.


Если мы хотим получить список всех пользователей, то делаем запрос вида SELECT * FROM users; При этом единственный тэг который можно привязать к такому запросу - это тег с названием таблицы. При изменении любого пользователя запросы по этому тэгу должны раскешиваться.
Тоже самое касается и запросов SELECT * FROM users WHERE users.name = 'Ivan' или, например, ... WHERE users.birthday IS NOT NULL. Все эти запросы привязываются к единственному тегу на основе названия таблицы users.

Если нужно искать пользователей которые живут в конкретном городе SELECT * FROM users WHERE city_id = 33, то запрос будет привязан к тегу "cities|33". Почему такой запрос повешенный на тэг из другой таблицы будет актуален (или что нужно делать что бы он был актуален)?

Обновим пользователя (c id=55) у которого city_id = 33. В таком случае необходимо обновить следующие теги:

  • тег users|55 (т.е. раскешиваем самого пользователя)
  • тег users (нужно сделать неактуальными все общие запросы на таблицу users описанные двумя абзацами выше)
  • теги связанных объектов (городов) на которые ссылается текущий (пользователь), в данном случае cities|33
  • если у пользователя меняется само свойство city_id, то нужно раскешить как тэг старого города так и нового

Т.к. в списке тегов для раскешивания есть cities|33, то приведённый выше запрос будет всегда актуален при измении пользователя связанного с запросом. При этом при изменении пользователя не связанного с городом раскешивание происходить не будет. Тоже самое касается и обновления города. Как только мы изменяем город 33, то раскешиваются запросы с тегом cities|33 и запрос сохранит актуальность при изменении города.


Если попадаются сложные запрос с JOIN'ами, то тэги создаются по названию таблиц, т.к. запрос вида SELECT * FROM users JOIN cities ON cities.id = users.city_id WHERE cities.name = 'Moscow' будет бесхитростно повешен на два тега cities и users. При измении/добавлении записей в любой из этих таблиц следующий такой запрос будет браться из базы.

Плюсы подобного подхода:

  • Не раскешиваются запросы основанные на связях OneToMany (дай мне список пользователей из такого-то города)
  • Запросы на несколько таблиц изменяются при редактировании любой из таблиц

Минусы подобного подхода:

  • Для кэширования необходима хитрая логика анализа SQL запроса что бы решить по каким тегам необходимо закешировать запрос.
  • Для раскешивания необходимо смотреть свойства объекта и соседние с ним объекты.
Clone this wiki locally