В прошлой части этого материала мы рассматривали основные аспекты работы с Redis и раскрывали, что это такое.
Обязательно прочитайте предыдущую часть этого руководства, чтобы было более понятно. Там рассказывалось, как устанавливать Redis на разные операционные системы, что это такое, какие преимущества этой системы хранения ключей, как выполнять настройку Redis на сервере и приводились некоторые примеры работы с Redis.
Сегодня мы продолжаем обучаться работе с Redis в Python. В частности, мы рассмотрим наиболее распространенные команды Redis, типы данных этой системы. Также поймем, что похожего есть в типах данных Redis и Python и то, какие есть отличия между ними.
Redis и словарь Python: что общего и различного
Redis – это аббревиатура, которая расшифровывается и переводится, как «служба удаленного словаря». Следовательно, его можно использовать и как словарь Python. Вообще, словарь Redis и словарь Python имеет много общего:
- База данных Redis может быть представлена в виде ключа и значения и поддерживает такие команды, как GET, SET, DEL, а также несколько сотен дополнительных инструкций.
- Ключи в Redis всегда относятся к строковому типу.
- Значения, соответствующие ключам в Redis могут принадлежать к разным типам данных. Мы рассмотрим наиболее значимые из них: строки, списки, hash и множества. Также есть расширенные типы данных, к которым относятся геопространственные элементы и новый тип потока.
- Часто команды Redis работают в постоянном времени 0(1), аналогично извлечению значения из dict в Python.
Конечно, такая интерпретация может не прийтись по душе создателю Redis Сальваторе Санфилиппо, поскольку он считает проект сервером структуры данных, а не хранилищем значений ключей. Но суть от этого изменяется не сильно. Действительно, у словаря Python есть много общего с хранилищем Redis.
Кроме string:string, в Redis встроена поддержка дополнительных типов key:value. Тем не менее, все равно есть смысл сравнивать со словарем, что позволяет лучше запомнить материал.
Давайте приведем пример, как это работает. Создадим первую базу, ID которой будет 0. В ней будет сопоставляться страна и столица. Здесь для установки пары ключ-значения используется SET.
127.0.0.1:6379> SET Bahamas Nassau OK 127.0.0.1:6379> SET Croatia Zagreb OK 127.0.0.1:6379> GET Croatia "Zagreb" 127.0.0.1:6379> GET Japan (nil)
Если перевести эту последовательность операторов в Python, получится такой результат.
capitals = {} capitals["Bahamas"] = "Nassau" capitals["Croatia"] = "Zagreb" print(capitals.get("Croatia")) # 'Zagreb' print(capitals.get("Japan")) # None
Нами был использован метод get объекта capital. То есть, вместо capitals[“Japan”] был задействован capitals.get(“Japan”).
Также Redis дает возможность настроить и получить множественные пары ключ-значение в одной команде. То есть, MSET и MGET.
127.0.0.1:6379> MSET Lebanon Beirut Norway Oslo France Paris OK 127.0.0.1:6379> MGET Lebanon Norway Bahamas 1) "Beirut" 2) "Oslo" 3) "Nassau"
Если перевести этот код в Python, то получится что-то типа такого.
>>> capitals.update({ ... "Lebanon": "Beirut", ... "Norway": "Oslo", ... "France": "Paris", ... }) >>> [capitals.get(k) for k in ("Lebanon", "Norway", "Bahamas")] ['Beirut', 'Oslo', 'Nassau']
Здесь, как мы поняли, использовался метод update() объекта capitals. А вместо .__getitem__() применяется .get(). Это дает возможность наиболее точно воспроизводить действия, которые выполняются в Redis. Если поиск ключа оборачивается неудачей, мы получим значение null.
Теперь приведем еще один пример. С помощью команды EXISTS выполняется проверка на предмет наличия существующего ключа.
127.0.0.1:6379> EXISTS Norway (integer) 1 127.0.0.1:6379> EXISTS Sweden (integer) 0
В Python, чтобы выполнить аналогичное действие, используется ключевое слово in.
>>> "Norway" in capitals True >>> "Sweden" in capitals False
Зачем были использованы эти несколько примеров? Прежде всего, для того, чтобы продемонстрировать сходства с Redis. В этих примерах еще нет клиент-серверного компонента Python, и пока redis-py не включен в общую картину. Тем не менее, эти примеры помогают понять, что Python имеет много общего с Redis, что гарантирует их совместимость.
Давайте приведем еще список некоторых команд вместе с их эквивалентами в Python.
SET Bahamas Nassau | capitals[«Bahamas»] = «Nassau» |
GET Croatia | capitals.get(«Croatia») |
MSET Lebanon Beirut Norway Oslo France Paris | capitals.update(
{ «Lebanon»: «Beirut», «Norway»: «Oslo», «France»: «Paris», } ) |
MGET Lebanon Norway Bahamas | [capitals[k] for k in («Lebanon», «Norway», «Bahamas»)] |
EXISTS Norway | «Norway» in capitals |
Видите логику, по которой эти команды могут быть объединены в одну группу?
Но принцип работы клиентской библиотеки Redis в Python несколько другой. Он осуществляет инкапсуляцию фактического TCP-соединения с сервером Redis и отправляет необработанные команды. Он делает это в виде байтов, которые были сериализованы с использованием протокола RESP. После того, как придет ответ, он парсится обратно в объект Python.
До этого момента обращение к серверу Redis осуществлялось через интерактивный REPL redis-cli. Также возможно непосредственное использование команд. Или же осуществление передачи имени скрипта в исполняемый файл Python типа myscript.py.
До этого момента мы работали исключительно с несколькими типами данных Redis, но все они отражали пару string:string. Но есть и другие.
Как мы видим, между словарями и базой данных Redis действительно есть много чего общего. Тем не менее, отличия есть. В частности, в том, что в качестве значения могут использоваться те типы данных, которые поддерживаются в Redis. А их набор отличается от аналогичного в Python.
Типы данных
Перед запуском клиента redis-py необходимо понимать, с какими еще типами данных можно работать. Чтобы было более понятно, все ключи Redis относятся к строчному типу.
Хеш – это отражение пары строка-строка. Она также называется парой поле-значение, и она расположена под одним ключом топового уровня.
127.0.0.1:6379> HSET pythonscripts url "https://python-scripts.com/" (integer) 1 127.0.0.1:6379> HSET pythonscripts github pythonscripts (integer) 1 127.0.0.1:6379> HSET pythonscripts fullname "Python Scripts" (integer) 1
Этот пример показывает, как осуществляется настройка трех пар поле-значение на один ключ python-scripts. Это может несколько запутать человека, который работал исключительно с Python и знаком только с терминологией этого языка. В целом, хеш в Redis является аналогом словаря в Python.
data = { "pythonscripts": { "url": "https://python-scripts.com/", "github": "pythonscripts", "fullname": "Python Scripts", } }
Все поля в Redis напоминают ключи Python. Redis задействует ключ term для ключа базы данных верхнего уровня, в котором хранится непосредственно структура хеша.
Для установки множественных пар в хеше используется HMSET.
127.0.0.1:6379> HMSET pypa url "https://www.pypa.io/" github pypa fullname "Python Packaging Authority" OK 127.0.0.1:6379> HGETALL pypa 1) "url" 2) "https://www.pypa.io/" 3) "github" 4) "pypa" 5) "fullname" 6) "Python Packaging Authority"
Применение HMSET в целом, аналогичен тому, как присваиваются данные вложенному словарю вместо установки каждой вложенной пары в HSET.
Два дополнительных типа значений – это списки и множества. Они могут задействовать то место, которое отводится под хеш или строку. Это значения Redis. Хеши, списки и множества управляются определенными командами, которые связаны с конкретным типом данных. Какой именно, в определенных случаях задается с помощью заглавной буквы.
- Хеши. Команды, предназначенные для работы с ними, начинаются с H. Ранее мы работали с ними. Это такие директивы, как HSET, HGET, HMSET.
- Множества. Команды для них начинаются с буквы S. Пример – SCARD.
- Списки. Команды, предназначенные для работы со списками, могут начинаться с L или R. Конкретная буква, которая будет использоваться, зависит от того, на какой стороне списка нужно выполнять те или иные действия. Несколько команд списков также обозначаются, как B. Они позволяют заблокировать одни операции во время выполнения других. Так, BLPOP блокирует левую часть структуры списка.
Учтите то, что список в Redis является именно связанным списком, а не массивом. Простыми словами, добавление равно О(1), тогда как индексирование по произвольному порядковому номеру – О(N).
В этой таблице содержатся основные команды для работы с определенными типами данных.
Конечно, это не полный перечень. Но для новичка этого списка достаточно. Так, в Redis также есть геопространственные элементы, сортированные наборы, HyperLogLog. То есть, можно также сортировать по структурам данных, создавать сводку по типам данным. Но все это продвинутый уровень, которому точно не стоит уделять внимание на первом этапе.
Поскольку мы теперь собираемся переходить уже к Python, то эта база данных может быть удалена. Для этого необходимо воспользоваться следующими командами.
127.0.0.1:6379> FLUSHDB OK 127.0.0.1:6379> QUIT
Так вы вернетесь к строке оболочки. Также можно оставить сервер Redis работающим в фоновом режиме. В будущем он будет еще нужен.
Выводы
Мы разобрались в основных командах Redis и нашли их аналоги в Python. Конечно, это сравнение довольно приблизительное и упрощенное. Отличия между особенностями Python и Redis, конечно же, есть. Тем не менее, для простоты понимания мы увидели, что есть аналогичные команды в этих языках (если Redis можно назвать языком, конечно же).