Hashes do Redis (Parte 2)
Esta lição aborda operações numéricas em campos hash, consultas iterativas e outros recursos avançados.
HINCRBY: Incrementar Valores de Campo
Campos hash podem armazenar strings numéricas e suportar operações aritméticas atômicas.
HINCRBY: Incremento de Inteiro
REDIS
# Criar estatísticas de artigo
HSET article:123 views 1000 likes 50 comments 20
# Incrementar contagem de visualizações
HINCRBY article:123 views 1
(integer) 1001
# Incrementar contagem de curtidas
HINCRBY article:123 likes 1
(integer) 51
# Incremento em lote
HINCRBY article:123 views 10
(integer) 1011
# Decrementar (passar um número negativo)
HINCRBY article:123 likes -1
(integer) 50
HINCRBYFLOAT: Incremento de Ponto Flutuante
REDIS
# Preço do produto
HSET product:2001 price 99.99
# Aumentar preço
HINCRBYFLOAT product:2001 price 10.5
"110.49"
# Diminuir preço (passar um número negativo)
HINCRBYFLOAT product:2001 price -5.0
"105.49"
Caso de Uso: Grupo de Contadores
REDIS
# Estatísticas do usuário
HSET user:stats:1 posts 0 followers 0 following 0
# Publicar um artigo
HINCRBY user:stats:1 posts 1
# Ganhar um seguidor
HINCRBY user:stats:1 followers 1
# Seguir alguém
HINCRBY user:stats:1 following 1
# Visualizar estatísticas
HGETALL user:stats:1
💡 Vantagem: Usar um hash para armazenar múltiplos contadores é mais eficiente em memória do que usar múltiplas chaves string.
HSCAN: Iterar por Hashes Grandes
Quando um hash tem muitos campos, HGETALL retorna todos os dados de uma vez, o que pode bloquear o servidor. HSCAN permite iteração em lote.
Uso Básico
REDIS
# Criar um hash grande
HSET grande:hash campo1 "valor1" campo2 "valor2" ... campo1000 "valor1000"
# Iniciar iteração
HSCAN grande:hash 0
1) "127" # Cursor para a próxima iteração
2) 1) "campo1"
2) "valor1"
3) "campo2"
4) "valor2"
...
# Continuar iteração
HSCAN grande:hash 127
1) "0" # Cursor 0 significa que a iteração está completa
2) 1) "campo999"
2) "valor999"
...
Corresponder Padrão
REDIS
# Obter apenas campos que correspondem a um padrão
HSCAN user:1 0 MATCH age*
1) "0"
2) 1) "age"
2) "25"
Especificar Contagem por Iteração
REDIS
# Retornar aproximadamente 100 campos por iteração
HSCAN grande:hash 0 COUNT 100
💡 Caso de uso: HSCAN é ótimo para iterar em hashes grandes sem bloquear o servidor.
Aplicações Avançadas de Hash
Caso de Uso 1: Detalhes de Produto de E-commerce
REDIS
# Armazenar informações completas do produto
HSET product:3001 \
name "iPhone 15 Pro" \
brand "Apple" \
price 8999 \
stock 100 \
category "phone" \
sales 0 \
rating 4.8
# Visualizar informações básicas do produto
HMGET product:3001 name price stock
# Incrementar vendas
HINCRBY product:3001 sales 1
# Decrementar estoque
HINCRBY product:3001 stock -1
# Atualizar avaliação
HSET product:3001 rating 4.9
# Verificar estoque
HGET product:3001 stock
Caso de Uso 2: Configuração do Usuário
REDIS
# Armazenar configuração do usuário
HSET user:config:1 \
theme "dark" \
language "pt-br" \
notifications "on" \
privacy "public" \
timezone "America/Sao_Paulo"
# Obter uma única configuração
HGET user:config:1 theme
# Modificar uma configuração
HSET user:config:1 theme "light"
# Obter configurações em lote
HMGET user:config:1 theme language notifications
Caso de Uso 3: Estatísticas em Tempo Real
REDIS
# Estatísticas diárias do site
HSET stats:20260623 \
page_views 0 \
unique_visitors 0 \
new_users 0 \
orders 0 \
revenue 0.0
# Incrementar visualizações de página
HINCRBY stats:20260623 page_views 1
# Incrementar visitantes únicos
HINCRBY stats:20260623 unique_visitors 1
# Incrementar pedidos
HINCRBY stats:20260623 orders 1
# Incrementar receita
HINCRBYFLOAT stats:20260623 revenue 299.99
# Visualizar estatísticas
HGETALL stats:20260623
Caso de Uso 4: Configuração de Teste A/B
REDIS
# Armazenar configuração do experimento
HSET experiment:homepage \
button_color "blue" \
layout "grid" \
show_banner "yes" \
discount_rate 0.1
# Obter configuração do experimento
HGET experiment:homepage button_color
# Atualizar configuração do experimento
HSET experiment:homepage button_color "red"
Hash vs JSON Comparação
Comparação de Armazenamento
Método 1: Hash
REDIS
HSET user:1 name "Alice" age 25 email "alice@example.com"
Método 2: String JSON
REDIS
SET user:1 '{"name":"Alice","age":25,"email":"alice@example.com"}'
Comparação de Operações
| Operação | Hash | String JSON |
|---|---|---|
| Obter campo único | HGET user:1 name |
Precisa analisar JSON |
| Modificar campo único | HSET user:1 age 26 |
Ler → analisar → modificar → serializar → escrever de volta |
| Obter todos os campos | HGETALL user:1 |
GET user:1 + analisar JSON |
| Operação numérica | HINCRBY user:1 age 1 |
Precisa analisar → modificar → serializar |
| Uso de memória | Menor | Maior (overhead de formato JSON) |
Comparação de Casos de Uso
| Cenário | Recomendado | Motivo |
|---|---|---|
| Perfil de usuário | Hash | Campos independentes, atualizações frequentes |
| Informações de produto | Hash | Campos independentes, atualizações parciais |
| Objetos aninhados complexos | String JSON | Hash não suporta aninhamento |
| Dados de array | String JSON | Hash não suporta arrays |
| Objeto de configuração | Hash | Campos independentes, consultas rápidas |
💡 Princípio de seleção:
- Campos independentes, atualizações parciais frequentes → Hash
- Aninhamento complexo, arrays necessários → String JSON
- Operações numéricas necessárias → Hash
Otimização de Desempenho
1. Evitar Hashes Grandes
REDIS
# ❌ Não recomendado: hash único com muitos campos
HSET grande:hash campo1 ... campo10000
# ✅ Recomendado: fragmentar em múltiplos hashes
HSET hash:parte1 campo1 ... campo1000
HSET hash:parte2 campo1001 ... campo2000
2. Usar HSCAN em Vez de HGETALL
REDIS
# ❌ HGETALL em hash grande
HGETALL grande:hash # Pode bloquear
# ✅ Usar HSCAN para iteração
HSCAN grande:hash 0
3. Operações em Lote Reduzem Viagens de Rede
REDIS
# ❌ Múltiplas operações individuais
HSET user:1 name "Alice"
HSET user:1 age 25
HSET user:1 city "Beijing"
# ✅ Operação em lote
HSET user:1 name "Alice" age 25 city "Beijing"
4. Configurar Limites de Codificação
Em redis.conf:
CONF
# Limite de contagem de campos hash (padrão 512)
hash-max-ziplist-entries 512
# Tamanho máximo do valor do campo hash (padrão 64 bytes)
hash-max-ziplist-value 64
ℹ️ Observação: Aumentar os limites pode economizar memória, mas pode reduzir o desempenho. Ajuste com base nos seus dados reais.
Limitações do Hash
1. Sem Suporte a Aninhamento
REDIS
# ❌ Não pode armazenar objetos aninhados diretamente
HSET user:1 address '{"city":"Beijing","zip":"100000"}'
# ✅ Usar string para partes aninhadas
HSET user:1 city "Beijing" zip "100000"
2. Sem Suporte a Array
REDIS
# ❌ Não pode armazenar arrays
HSET user:1 tags ["redis","database","cache"]
# ✅ Usar set ou list para arrays
SADD user:1:tags "redis" "database" "cache"
3. Valores Só Podem Ser Strings
REDIS
# Todos os valores são strings
HSET user:1 age 25
HGET user:1 age
"25" # Retorna string, não inteiro
❓ Perguntas Frequentes
P O que acontece se HINCRBY for usado em um campo não numérico?
R Retorna um erro:
(error) ERR hash value is not an integer. Certifique-se de que o valor do campo é uma string numérica.P Campos hash são ordenados?
R Não. Campos hash não são ordenados — HGETALL não garante nenhuma ordem específica.
P Como verifico se uma chave é do tipo hash?
R Use o comando TYPE:
TYPE user:1 retorna hash.P HSCAN garante que não há duplicatas?
R Não. HSCAN pode retornar campos duplicados — a camada de aplicação precisa tratar a deduplicação.
P Qual é a diferença entre hash e set?
R Um hash armazena pares campo-valor; um set armazena elementos únicos. Hashes são para objetos, sets são para tags e relacionamentos.
📖 Resumo
- HINCRBY/HINCRBYFLOAT realizam operações numéricas em campos
- HSCAN itera por hashes grandes, evitando bloqueio
- Hashes são adequados para produtos, configurações, objetos de estatísticas
- Hash vs String JSON: Hash para objetos simples com atualizações parciais
- Dicas de desempenho: evite hashes grandes, use HSCAN, operações em lote
- Limitações do hash: sem aninhamento, sem arrays, valores são apenas strings
📝 Atividades
- Operações numéricas: Use um hash para armazenar estatísticas de artigo (visualizações, curtidas, comentários) e incremente com HINCRBY
- Gerenciamento de produto: Use hash para armazenar informações de produto, pratique visualizar, modificar, incrementar vendas, decrementar estoque
- Gerenciamento de configuração: Use hash para configuração de usuário, pratique obter configuração única, obter em lote e modificar configurações
- Comparação de desempenho: Compare as etapas para modificar um único campo usando hash vs String JSON
Próxima Lição
Na próxima lição, nós aprenderemos sobre Listas do Redis (Parte 1), abordando operações básicas de lista.



