На сегодняшний день любой бизнес активно использует аналитику, чтобы развивать свои продукты. На основе данных можно лучше понимать пользователей и их потребности. Одна из базовых метрик, использующаяся повсеместно, — это количество уникальных посетителей страницы. Представим, что есть необходимость хранить такие данные в Redis.
Прежде всего, стоит определить, как данные будут использоваться. Важно эффективно выполнять 2 условия:
Прикинем несколько вариантов решения.
Для начала можно попробовать хранить каждое посещение отдельным ключом с форматом page:{page_path}:user:{user_id}:
127.0.0.1:6379> set page:/courses:user:22 1
OK
127.0.0.1:6379> set page:/courses:user:33 1
OK
127.0.0.1:6379> exists page:/courses:user:22
(integer) 1
127.0.0.1:6379> keys page:/courses:user:*
1) "page:/courses:user:33"
2) "page:/courses:user:22"
Хотя проверка на существование пользователя в списке будет происходить быстро, этот вариант не подходит, потому что получение количества уникальных пользователей займет O(N) (N — количество ключей в Redis).
Второй вариант — использовать тип данных Lists для хранения уникального списка ID пользователей:
127.0.0.1:6379> lpush page:/courses 22 33 44
(integer) 3
127.0.0.1:6379> llen page:/courses
(integer) 3
В данном случае размер списка можно получить очень быстро за O(1), но вставка будет происходить неэффективно, так как перед вставкой необходимо делать поиск по всему списку для проверки существования.
Можно использовать структуру Hashes. Ключом будет страница, а значения будут в формате {user_id}: 1:
127.0.0.1:6379> hset page:/courses 11 1 22 1 33 1
(integer) 3
127.0.0.1:6379> hlen page:/courses
(integer) 3
Это решение удовлетворяет обоим требованиям:
hlen
Но имеются и недостатки:
Для решения задачи с уникальными посетителями в Redis есть структура данных Sets. Sets — это список уникальных элементов, поддерживающий быстрые функции вставки, проверки на уникальность и пересечений.
Для записи значений используется команда sadd key member [member ...]
:
127.0.0.1:6379> sadd page:/courses 11 22 33 44
(integer) 4
Если набора не существовало, то он будет создан. После записи возвращается количество добавленных элементов. Если попытаться добавить существующий элемент, то вернется 0:
127.0.0.1:6379> sadd page:/courses 22
(integer) 0
Получить количество уникальных пользователей страницы можно с помощью команды scard key
:
127.0.0.1:6379> scard page:/courses
(integer) 4
Команда sismember key member
проверяет, что пользователь посещал данную страницу:
127.0.0.1:6379> sismember page:/courses 33
(integer) 1
127.0.0.1:6379> sismember page:/courses 12222
(integer) 0
Удалить пользователя из набора можно командой srem key member [member ...]
:
127.0.0.1:6379> srem page:/courses 44
(integer) 1
127.0.0.1:6379> smembers page:/courses
1) "11"
2) "22"
3) "33"
Допустим, что есть 3 страницы: /courses, /courses/java и /courses/php. Нужно получить уникальных пользователей, которые посетили все 3 страницы. Задача решается одной командой sinter key [key ...]
:
127.0.0.1:6379> sadd page:/courses 1 2 3 4 5 6 7 8 9 10
(integer) 10
127.0.0.1:6379> sadd page:/courses/java 1 2 3 4 5 6 7
(integer) 7
127.0.0.1:6379> sadd page:/courses/php 5 6 7 8 9
(integer) 5
127.0.0.1:6379> sinter page:/courses page:/courses/java page:/courses/php
1) "5"
2) "6"
3) "7"
sadd
sismember
можно проверить существование элемента в набореscard
sinter
Вам ответят команда поддержки Хекслета или другие студенты.
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
Наши выпускники работают в компаниях:
Зарегистрируйтесь или войдите в свой аккаунт