Углубленный анализ серии Redis (6) — хэш структуры данных Redis

Redis задняя часть база данных Эксплуатация и техническое обслуживание

предисловие

Большинство языков программирования предоставляютхэш(hash) типы, их можно назватьхэш,Словарь,ассоциативный массив. существуетRedisсередина,тип хешаозначает, что само значение ключа являетсяструктура ключ-значение.

хэшВ формеvalue={ {field1,value1},...{fieldN,valueN} },Redis пара ключ-значениеитип хешаОтношения между ними показаны на рисунке:

в виде хешаСопоставление отношенийназываетсяfield-value,здесьvalueОтносится кfieldсоответствующийценность,нетключсоответствующее значение.

Другие статьи

текст

1. Связанные команды

1.1 Основные команды

1.1.1. Установка значений

hset key field value

Нижеuser:1добавить паруfield-value, если настройка выполнена успешно, возвращается1, иначе вернется0.

127.0.0.1:6379> hset user:1 name tom
(integer) 1

такжеRedisпри условииhsetnxкоманды, их взаимосвязь подобнаsetиsetnxКоманда та же, за исключениемсфераЗависит отключстатьfield.

1.1.2. Получить значение

hget key field

Для получения используются следующие операции.user:1изname домен (атрибут)соответствующее значение.

127.0.0.1:6379> hget user:1 name
"tom"

еслиключилиfieldне существует, вернетсяnil:

127.0.0.1:6379> hget user:2 name
(nil)
127.0.0.1:6379> hget user:1 age
(nil)

1.1.3. Удалить поле

hdel key field [field ...]

hdelудалитодин или больше field, возвращаемый результатУспешно удалено fieldномер, например:

127.0.0.1:6379> hdel user:1 name
(integer) 1
127.0.0.1:6379> hdel user:1 age
(integer) 0

1.1.4 Подсчет количества полей

hlen key

например ключuser:1имеют3Кусокfield:

127.0.0.1:6379> hset user:1 name tom
(integer) 1
127.0.0.1:6379> hset user:1 age 23
(integer) 1
127.0.0.1:6379> hset user:1 city chengdu
(integer) 1
127.0.0.1:6379> hlen user:1
(integer) 3

1.1.5 Пакетная установка или получение значения поля

hmget key field [field ...] hmset key field value [field value ...]

hmsetиhmgetсоответственноПакетные настройкииПолучать field-value,hmsetТребуемые параметрыkeyимного пар field-value,hmgetТребуемые параметрыkeyинесколько field. Например:

127.0.0.1:6379> hmset user:1 name tom age 12 city chengdu
OK
127.0.0.1:6379> hmget user:1 name city
1) "tom"
2) "chengdu"

1.1.6. Определить, существует ли поле

hexists key field

Напримерuser:1Включаютnameдомен, поэтому возвращаемый результат1, вернуть, если не включены0:

127.0.0.1:6379> hexists user:1 name
(integer) 1

1.1.7 Получить все поля

hkeys key

hkeysКоманда должна быть вызванаhfieldsТочнее, он возвращает указанныйхэш-ключвсеfield,Например:

127.0.0.1:6379> hkeys user:1
1) "name"
2) "age"
3) "city"

1.1.8. Получить все значения

hvals key

Получите это, выполнив следующие действияuser:1всеvalue:

127.0.0.1:6379> hvals user:1
1) "tom"
2) "12"
3) "chengdu"

1.1.9 Получить все значения полей

hgetall key

Получите это, выполнив следующие действияuser:1всеfield-value:

127.0.0.1:6379> hgetall user:1
1) "name"
2) "tom"
3) "age"
4) "12"
5) "city"
6) "chengdu"

в настоящее время используетhgetallкогда, еслихэш-элементКоличество больше, будетблокировать Redisвозможный. Если разработчику нужно только получитьчасть field,можно использоватьhmget, если вы должны получитьвсе field-value,можно использоватьhscanкоманда, которая будетпрогрессивный обходТип хеша.

1.2. Необычные команды

1.2.1. Автоматическое увеличение значения ключа

hincrby key field hincrbyfloat key field

hincrbyиhincrbyfloat, какincrbyиincrbyfloatКоманды те же, но ихсферадаfield.

1.2.2 Вычислить длину строки значения

hstrlen key field

Напримерhget user:1 nameизvalueдаtom,ТакhstrlenВозвращаемый результат3.

127.0.0.1:6379> hstrlen user:1 name
(integer) 3

НижеКоманда типа хешаизвременная сложность, разработчики могут обратиться к этой таблице, чтобы выбрать соответствующую команду.

2. Внутреннее кодирование

тип хешаизВнутреннее кодированиеЕсть два вида:

2.1. почтовый список

когдатип хешаколичество элементовменьше, чем hash-max-ziplist-entriesконфигурация (по умолчанию512), в то же времявсе значенияВсеменьше, чем hash-max-ziplist-valueконфигурация (по умолчанию64байт),RedisБудет использоватьсяziplistв видехэшизВнутренняя реализация,ziplistиспользовать большекомпактная структурареализовать несколько элементовнепрерывное хранение, так что всохранить памятьсоотношение сторонhashtableлучше.

2.2. хэш-таблица

когдатип хешане в состоянии удовлетворитьziplistусловия,RedisБудет использоватьсяhashtableв видехэшизВнутренняя реализация, потому что в это времяziplistизЭффективность чтения и записиуменьшится, при этомhashtableпрочти и напишивременная сложностьзаO(1).

Следующий пример демонстрируеттип хешаизВнутреннее кодирование, и соответствующие изменения.

когдаfieldномерчуть меньше, и не большойvalueчас,Внутреннее кодированиезаziplist:

127.0.0.1:6379> hmset hashkey f1 v1 f2 v2
OK
127.0.0.1:6379> object encoding hashkey
"ziplist"
  • когда естьvalue больше, чем 64байты,Внутреннее кодированиебудетziplistстатьhashtable:
127.0.0.1:6379> hset hashkey f3 "one string is bigger than 64 byte...忽略..."
OK
127.0.0.1:6379> object encoding hashkey
"hashtable"
  • когдаfieldномерПревосходить 512,Внутреннее кодированиетакжеziplistстатьhashtable:
127.0.0.1:6379> hmset hashkey f1 v1 f2 v2 f3 v3 ... f513 v513
OK
127.0.0.1:6379> object encoding hashkey
"hashtable"

3. Применимые сценарии

Как показано на рисунке, дляреляционная таблица данныхдваИнформация о пользователе, атрибут пользователя используется как столбец таблицы, а информация о каждом пользователе используется как строка.

использоватьRedis хэш-структураместо храненияИнформация о пользователеСхематическая диаграмма выглядит следующим образом:

по сравнению с использованиемСериализация строктайникИнформация о пользователе,тип хешастать большеинтуитивный, И воперация обновлениявстречаболее удобно. У каждого пользователяidопределяется какключевой суффикс, много парfield-valueдля каждого пользователяАтрибуты, аналогичный следующему псевдокоду:

public UserInfo getUserInfo(long id) {
    // 用户id作为key后缀
    String userRedisKey = "user:info:" + id;
    // 使用hgetall获取所有用户信息映射关系
    Object userInfoMap = redis.hgetAll(userRedisKey);
    UserInfo userInfo;
    if (userInfoMap != null) {
        // 将映射关系转换为UserInfo
        userInfo = transferMapToUserInfo(userInfoMap);
    } else {
        // 从MySQL中获取用户信息
        userInfo = mysql.get(id);
        // 将userInfo变为映射关系使用hmset保存到Redis中
        redis.hmset(userRedisKey, transferUserInfoToMap(userInfo));
        // 添加过期时间
        redis.expire(userRedisKey, 3600);
    }
    return userInfo;
}

3.1 Структура хеша и реляционная таблица

должен быть в курсетип хешаиРеляционная база данныхЕсть два отличия:

  • тип хешадаредкийРеляционная база данныхдаполностью структурированный, Напримертип хешакаждыйключможет иметь разныеfieldРеляционная база данныхПосле добавления новогоСписок,все линиивсе для этогоНастройки(даже еслиNULL), как показано на рисунке:

  • Реляционная база данныхможет делать сложныереляционный запрос, при использованииRedisДля имитации сложных реляционных запросовСложность разработки,Высокая стоимость обслуживания.

3.2 Несколько методов кэширования

До сих пор мы могли использоватьтри методатайникИнформация о пользователе, три схемы приведены нижеВыполнениеиАнализ преимуществ и недостатков.

3.2.1 Собственные строковые типы

Назначьте каждый атрибут информации о пользователеключ.

set user:1:name tom
set user:1:age 23
set user:1:city beijing
  • преимущество: Простой и интуитивно понятный, каждое свойство поддерживаетоперация обновления.

  • недостаток: занятослишком много ключей,объем памятибольше, а информация о пользователеПлохая сплоченность, поэтому это решение обычно не используется в производственной среде.

3.2.2 Сериализация строковых типов

информация о пользователеСериализацияпосле использованияключспасти.

set user:1 serialize(userInfo)
  • преимущество:Упрощенное программирование, если разумно использоватьСериализацияМожетУлучшить использование памяти.

  • недостаток:СериализацияидесериализоватьЕсть определенные накладные расходы, при этом каждый разобновить свойстванужноВсе данныевыигратьдесериализовать,ОбновленоСноваСериализацияприбытьRedisсередина.

3.2.3 Типы хешей

Каждый пользовательский атрибут используетпара field-value, но только сключспасти.

hmset user:1 name tom age 23 city beijing
  • преимущество:Простой и интуитивно понятный, если использовать разумноуменьшить объем памятииспользование.

  • недостаток: контролировать и уменьшатьхэшсуществуетziplistиhashtableдваВнутреннее кодированиеизконвертировать,hashtableбудет потреблятьбольше памяти.

резюме

В этой статье описываетсяRedisсерединахэш-структураНекоторые изосновные команды,Внутреннее кодированиеиПрименимая сцена. Наконец-то сравнилреляционная таблицаихэш-структураразница и несколькоспособ храненияпреимущества и недостатки.

Ссылаться на

«Разработка и эксплуатация Redis»


Добро пожаловать в технический публичный аккаунт: Zero One Technology Stack

零壹技术栈

Эта учетная запись будет продолжать делиться сухими товарами серверных технологий, включая основы виртуальных машин, многопоточное программирование, высокопроизводительные фреймворки, асинхронное ПО, промежуточное ПО для кэширования и обмена сообщениями, распределенные и микросервисы, материалы для обучения архитектуре и расширенные учебные материалы и статьи.