Hashes do Redis (Parte 1)

Um hash é uma coleção chave-valor, ideal para armazenar objetos. Esta lição aborda operações básicas de hash.

O que é um Hash?

Um hash é similar a:

Uma única chave de hash Redis pode armazenar múltiplos pares campo-valor:

user:1
├─ name  → "Alice"
├─ age   → "25"
├─ city  → "Beijing"
└─ email → "alice@example.com"
💡 Vantagem: Hashes permitem modificar campos individuais sem ler o objeto inteiro. Eles também são mais eficientes em memória do que armazenar strings JSON.

HSET e HGET: Definir e Obter Campos

HSET: Definir um Único Campo

REDIS
# Definir um único campo
HSET user:1 name "Alice"
(integer) 1  # Retorna o número de campos recém-adicionados

# Definir múltiplos campos
HSET user:1 age 25 city "Beijing"
(integer) 2  # Adicionou 2 novos campos

# Atualizar um campo existente
HSET user:1 name "Bob"
(integer) 0  # Campo já existe, retorna 0

HGET: Obter um Único Campo

REDIS
HGET user:1 name
"Alice"

HGET user:1 age
"25"

# Campo não existe
HGET user:1 naoexiste
(nil)

HSETNX: Definir Apenas se o Campo Não Existir

REDIS
# Definir apenas se o campo não existir
HSETNX user:1 name "Charlie"
(integer) 0  # Campo já existe, falhou

HSETNX user:1 phone "13800138000"
(integer) 1  # Campo não existe, definido com sucesso

HMSET e HMGET: Operações em Lote

HMSET: Definir Campos em Lote

REDIS
HMSET user:2 name "Bob" age 30 city "Shanghai" email "bob@example.com"
OK
⚠️ Observação: Após Redis 4.0.0, HMSET está obsoleto. Use HSET para definir múltiplos campos.

HMGET: Obter Campos em Lote

REDIS
HMGET user:2 name age city
1) "Bob"
2) "30"
3) "Shanghai"

# Incluindo campos inexistentes
HMGET user:2 name email phone
1) "Bob"
2) "bob@example.com"
3) (nil)  # phone não existe

HGETALL: Obter Todos os Campos e Valores

REDIS
HGETALL user:2
1) "name"
2) "Bob"
3) "age"
4) "30"
5) "city"
6) "Shanghai"
7) "email"
8) "bob@example.com"
⚠️ Observação: HGETALL retorna um array alternado de nomes de campos e valores. Se o hash for grande, isso usa memória e largura de banda significativas — use com cuidado!

HKEYS e HVALS: Obter Todos os Nomes de Campos ou Valores

HKEYS: Obter Todos os Nomes de Campos

REDIS
HKEYS user:2
1) "name"
2) "age"
3) "city"
4) "email"

HVALS: Obter Todos os Valores

REDIS
HVALS user:2
1) "Bob"
2) "30"
3) "Shanghai"
4) "bob@example.com"

HEXISTS: Verificar se Campo Existe

REDIS
HEXISTS user:2 name
(integer) 1  # Existe

HEXISTS user:2 phone
(integer) 0  # Não existe

HDEL: Deletar Campos

REDIS
# Deletar um único campo
HDEL user:2 email
(integer) 1  # Deletou 1 campo

# Deletar múltiplos campos
HDEL user:2 age city
(integer) 2  # Deletou 2 campos

# Deletar um campo inexistente
HDEL user:2 naoexiste
(integer) 0

HLEN: Obter Número de Campos

REDIS
HSET user:3 name "Charlie" age 28
HLEN user:3
(integer) 2  # Tem 2 campos

# Chave não existe
HLEN naoexiste
(integer) 0

HSTRLEN: Obter Tamanho do Valor do Campo

REDIS
HSET user:1 name "Alice" bio "Engenheira de Software"
HSTRLEN user:1 name
(integer) 5  # "Alice" tem tamanho 5

HSTRLEN user:1 bio
(integer) 22  # "Engenheira de Software" tem tamanho 22

Casos de Uso de Hash

Caso de Uso 1: Armazenar Informações do Usuário

REDIS
# Armazenar informações básicas do usuário
HSET user:1001 name "Alice" age 25 email "alice@example.com" role "admin"

# Obter nome do usuário
HGET user:1001 name

# Atualizar idade do usuário
HSET user:1001 age 26

# Obter todas as informações do usuário
HGETALL user:1001

Caso de Uso 2: Carrinho de Compras

REDIS
# Carrinho de compras do Usuário 1
HSET cart:user:1 product:101 2    # Produto 101, quantidade 2
HSET cart:user:1 product:102 1    # Produto 102, quantidade 1
HSET cart:user:1 product:103 5    # Produto 103, quantidade 5

# Ver todos os itens no carrinho
HGETALL cart:user:1

# Atualizar quantidade do item
HSET cart:user:1 product:101 3

# Remover um item
HDEL cart:user:1 product:102

# Verificar quantos itens no carrinho
HLEN cart:user:1

Caso de Uso 3: Metadados de Artigo

REDIS
# Armazenar informações do artigo
HSET article:123 title "Tutorial Redis" author "Alice" views 1000 likes 50

# Incrementar contagem de visualizações (requer HINCRBY)
HINCRBY article:123 views 1

# Incrementar contagem de curtidas
HINCRBY article:123 likes 1

# Obter título e autor do artigo
HMGET article:123 title author

Caso de Uso 4: Cache de Produto

REDIS
# Cache de detalhes do produto
HSET product:2001 name "iPhone 15" price 5999 stock 100 category "phone"

# Obter preço do produto
HGET product:2001 price

# Atualizar estoque
HSET product:2001 stock 95

# Verificar se o produto existe
HEXISTS product:2001 name

Hash vs String para Armazenar Objetos

Método 1: String com JSON

REDIS
SET user:1 '{"name":"Alice","age":25,"email":"alice@example.com"}'

# Obter o objeto inteiro
GET user:1

# Modificar idade: precisa ler, analisar, modificar, serializar, escrever de volta
# Múltiplas etapas, ineficiente

Método 2: Hash

REDIS
HSET user:1 name "Alice" age 25 email "alice@example.com"

# Obter um único campo
HGET user:1 name

# Modificar idade: operação de uma etapa
HSET user:1 age 26

# Obter múltiplos campos
HMGET user:1 name age

Resumo Comparativo

Aspecto String (JSON) Hash
Modificar campo único Precisa ler o objeto inteiro Modificação direta
Uso de memória Maior (overhead de formato JSON) Menor (armazenamento compacto)
Consultar campo único Precisa analisar JSON Acesso direto
Objetos aninhados complexos ✅ Suportado ❌ Não suportado
Atualização parcial ❌ Difícil ✅ Simples
💡 Guia de seleção:

  • Objetos simples (estrutura plana): use Hash
  • Objetos complexos (estrutura aninhada): use String com JSON
  • Modificação frequente de campos individuais: use Hash

Otimização de Codificação de Hash

Redis seleciona automaticamente a codificação com base no tamanho do hash:

Codificação Condição Descrição
ziplist Campos <= 512, tamanho do valor <= 64 bytes Lista comprimida, economiza memória
hashtable Campos > 512 ou tamanho do valor > 64 bytes Tabela hash, melhor desempenho

Verificando Tipo de Codificação

REDIS
HSET pequeno:hash campo1 "valor1" campo2 "valor2"
OBJECT ENCODING pequeno:hash
"ziplist"

# Após adicionar muitos campos
HSET grande:hash campo1 "valor1" campo2 "valor2" ... campo600 "valor600"
OBJECT ENCODING grande:hash
"hashtable"
ℹ️ Observação: A codificação é selecionada automaticamente pelo Redis. Você pode ajustar os limites através de parâmetros de configuração.

❓ Perguntas Frequentes

P Quantos campos um hash pode armazenar?
R Teoricamente ilimitado (2^32 - 1), mas praticamente limitado pela memória. É recomendado manter hashes individuais com menos de alguns milhares de campos.
P HGETALL afeta o desempenho?
R Sim. Se o hash for grande, HGETALL retorna muitos dados, consumindo memória e largura de banda. Use HSCAN para recuperação iterativa.
P Os valores dos campos hash podem ser numéricos?
R Sim. Todos os valores no Redis são strings, mas strings numéricas suportam operações aritméticas (HINCRBY).
P Como deletar uma chave hash inteira?
R Use DEL para deletar a chave, não HDEL para deletar campos: DEL user:1.
P Hash suporta aninhamento?
R Não. Os valores do hash só podem ser strings. Para aninhamento, use String com JSON.

📖 Resumo

📝 Atividades

  1. Informações do usuário: Use um hash para armazenar informações do usuário (nome, idade, email, cidade), depois recupere todas as informações
  2. Carrinho de compras: Implemente um carrinho de compras com um hash — adicione 3 produtos, modifique 1 quantidade, delete 1 produto
  3. Operações de campo: Use HEXISTS para verificar existência de campo, HLEN para contar campos
  4. Prática de comparação: Armazene o mesmo objeto com String JSON e Hash, compare as etapas para modificar um único campo

Próxima Lição

Na próxima lição, nós aprenderemos sobre Hashes do Redis (Parte 2), abordando operações avançadas de hash e cálculos numéricos.

100%