В прошлом уроке мы уже мельком клали книгу в корзину командой RPUSH. Сегодня разбираемся, что это было. До сих пор в каждом ключе лежало одно значение: строка или число. Но магазину нужны и последовательности: письма, которые надо разослать, книги, которые пользователь открывал последними. Для них в Redis есть первая структура данных, список.
Бусы на нитке
Представь бусы на нитке. Новую бусину можно нанизать слева или справа, снять тоже можно с любого края. А чтобы добраться до бусины в середине, придётся перебирать соседей.
Список в Redis устроен так же. Это упорядоченная последовательность строк в одном ключе, и быстро с ним работать с концов. Левый конец называют головой, правый хвостом. Отсюда и буквы в начале команд: L значит левый край, R правый.
Положить и посмотреть
Очередь писем, которые магазин должен разослать. Новые письма кладём в хвост командой RPUSH, сразу несколько:
127.0.0.1:6379> RPUSH queue:emails welcome:ivan order:15 welcome:olga
(integer) 3
127.0.0.1:6379> LRANGE queue:emails 0 -1
1) "welcome:ivan"
2) "order:15"
3) "welcome:olga"
RPUSH вернул длину списка после добавления. Ключ создался сам, как и у INCR из прошлого урока.
LRANGE показывает элементы с одного номера по другой. Номера начинаются с нуля, а отрицательные считаются с конца: -1 это последний элемент, -2 предпоследний. Поэтому 0 -1 значит «весь список». Пустой или несуществующий список LRANGE показывает так:
127.0.0.1:6379> LRANGE nokey 0 -1
(empty array)
Очередь: первым пришёл, первым ушёл
Работник, который рассылает письма, забирает их с головы командой LPOP:
127.0.0.1:6379> LPOP queue:emails
"welcome:ivan"
127.0.0.1:6379> LLEN queue:emails
(integer) 2
LPOP вернул элемент и удалил его из списка. LLEN показывает, сколько осталось. Кладём в хвост, забираем с головы: получилась очередь, первым обрабатывается то письмо, которое пришло раньше.
Забрать можно и несколько элементов сразу, указав количество:
127.0.0.1:6379> RPOP queue:emails 2
1) "welcome:olga"
2) "order:15"
127.0.0.1:6379> EXISTS queue:emails
(integer) 0
Когда из списка забрали последний элемент, Redis удаляет ключ целиком, пустых списков он не хранит. RPOP на несуществующем ключе вернёт (nil).
Стек: последним пришёл, первым ушёл
Если класть и забирать с одного и того же края, получится стек, как стопка тарелок. Так хранят историю просмотров: последняя открытая книга должна быть сверху.
127.0.0.1:6379> LPUSH viewed:user:7 book:1
(integer) 1
127.0.0.1:6379> LPUSH viewed:user:7 book:3
(integer) 2
127.0.0.1:6379> LPUSH viewed:user:7 book:7
(integer) 3
127.0.0.1:6379> LRANGE viewed:user:7 0 -1
1) "book:7"
2) "book:3"
3) "book:1"
127.0.0.1:6379> LPOP viewed:user:7
"book:7"
Книга 7 открыта последней и стоит первой. LPOP забрал её.
урок из курса
Урок из курса «Redis с нуля». Курс покупается один раз и остаётся навсегда: 500 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.