Strings, Hashes, Lists, Sets e Sorted Sets no Redis
1. Redis como Banco de Dados NoSQL: Visão Geral dos Tipos de Dados
1.1. Diferenças fundamentais entre modelo relacional (SQL) e modelo chave-valor do Redis
O Redis é um banco de dados NoSQL do tipo chave-valor, que opera inteiramente em memória principal. Diferentemente do modelo relacional SQL, onde os dados são organizados em tabelas com esquemas rígidos, linhas e colunas, o Redis armazena dados como pares chave-valor, onde cada chave é única e o valor pode ser um de seus tipos de dados nativos: String, Hash, List, Set, Sorted Set, entre outros.
Enquanto no SQL você escreveria:
SELECT nome, email FROM usuarios WHERE id = 123;
No Redis, você acessa diretamente pela chave:
GET usuario:123
1.2. Por que Redis não substitui SQL: cenários de uso complementares
O Redis não substitui bancos SQL porque não oferece:
- Consultas ad-hoc complexas com joins
- Garantias ACID completas (embora tenha atomicidade por comando)
- Suporte nativo a schemas relacionais
Os cenários ideais para Redis incluem:
- Cache de consultas SQL: armazenar resultados de queries frequentes
- Gerenciamento de sessões: dados temporários de usuários logados
- Filas de mensagens: processamento assíncrono de tarefas
- Leaderboards e rankings: ordenação em tempo real com Sorted Sets
1.3. Comandos básicos de gerenciamento
SET chave "valor" # Armazena string
GET chave # Recupera valor
DEL chave # Remove chave
EXISTS chave # Verifica existência (1 ou 0)
TYPE chave # Retorna tipo do valor (string, hash, list, etc.)
2. Strings: O Tipo de Dado Mais Simples e Versátil
2.1. Operações básicas
SET nome "Maria Silva"
GET nome # "Maria Silva"
MSET cidade "São Paulo" estado "SP"
MGET cidade estado # ["São Paulo", "SP"]
GETSET nome "João Santos" # Retorna "Maria Silva" e atualiza para "João Santos"
2.2. Contadores e operações atômicas
SET visitas 0
INCR visitas # 1
INCR visitas # 2
INCRBY visitas 10 # 12
DECR visitas # 11
DECRBY visitas 5 # 6
Essas operações são atômicas, evitando condições de corrida em ambientes concorrentes.
2.3. Strings como cache de consultas SQL
# Simulando cache de uma consulta SQL
SET cache:usuario:42 '{"id":42,"nome":"Ana","email":"ana@email.com"}' EX 3600
GET cache:usuario:42
O parâmetro EX 3600 define TTL (time-to-live) de 1 hora, expirando automaticamente o cache.
3. Hashes: Modelando Objetos e Registros como no SQL
3.1. Estrutura de campo-valor dentro de uma chave
Hashes permitem armazenar múltiplos pares campo-valor sob uma única chave, similar a uma linha de tabela SQL:
HSET usuario:1 nome "Carlos" email "carlos@email.com" idade 30
HGET usuario:1 nome # "Carlos"
HGETALL usuario:1 # Lista todos campos e valores
HDEL usuario:1 idade # Remove campo específico
3.2. Comparação com linhas de tabelas SQL
| SQL | Redis |
|---|---|
INSERT INTO usuarios (id, nome, email) VALUES (1, 'Carlos', 'carlos@email.com') |
HSET usuario:1 nome "Carlos" email "carlos@email.com" |
SELECT nome FROM usuarios WHERE id = 1 |
HGET usuario:1 nome |
SELECT * FROM usuarios WHERE id = 1 |
HGETALL usuario:1 |
DELETE FROM usuarios WHERE id = 1 |
DEL usuario:1 |
3.3. Operações em lote e contadores
HMSET usuario:2 nome "Beatriz" cargo "Analista" salario 5000
HMGET usuario:2 nome cargo # ["Beatriz", "Analista"]
HINCRBY usuario:2 salario 500 # Incrementa salário para 5500
HKEYS usuario:2 # ["nome", "cargo", "salario"]
HVALS usuario:2 # ["Beatriz", "Analista", "5500"]
4. Lists: Filas, Pilhas e Mensageria Simples
4.1. Operações de inserção e remoção
LPUSH tarefas "relatório" # Adiciona à esquerda
RPUSH tarefas "reunião" # Adiciona à direita
RPUSH tarefas "código"
LRANGE tarefas 0 -1 # ["relatório", "reunião", "código"]
LPOP tarefas # Remove e retorna "relatório" (esquerda)
RPOP tarefas # Remove e retorna "código" (direita)
4.2. Uso como fila (FIFO) e pilha (LIFO)
Fila (FIFO): LPUSH + BRPOP (bloqueante)
# Produtor
LPUSH fila_pedidos "pedido:1001"
LPUSH fila_pedidos "pedido:1002"
# Consumidor (bloqueia até receber item ou timeout)
BRPOP fila_pedidos 0 # ["fila_pedidos", "pedido:1001"]
Pilha (LIFO): LPUSH + LPOP
LPUSH pilha_acoes "ação1"
LPUSH pilha_acoes "ação2"
LPOP pilha_acoes # Retorna "ação2" (último inserido)
4.3. Listas como substitutas de tabelas de log
# Armazenar últimas ações do usuário (limitado a 100)
LPUSH log:usuario:42 "login:2024-01-15 10:30"
LTRIM log:usuario:42 0 99 # Mantém apenas os 100 primeiros
5. Sets: Conjuntos Não Ordenados para Relacionamentos e Unicidade
5.1. Operações básicas
SADD tags:post:1 "redis" "database" "nosql" "redis"
SREM tags:post:1 "nosql"
SMEMBERS tags:post:1 # ["redis", "database"] (ordem não garantida)
SISMEMBER tags:post:1 "redis" # 1 (verdadeiro)
SCARD tags:post:1 # 2 (quantidade de membros)
5.2. Operações de conjuntos (análogo a joins SQL)
SADD tags:post:1 "redis" "database"
SADD tags:post:2 "redis" "python"
SADD tags:post:3 "python" "web"
# Interseção (posts que têm redis E python)
SINTER tags:post:1 tags:post:2 # ["redis"]
# União (todas as tags únicas)
SUNION tags:post:1 tags:post:2 tags:post:3 # ["redis", "database", "python", "web"]
# Diferença (tags que estão em post:1 mas não em post:2)
SDIFF tags:post:1 tags:post:2 # ["database"]
5.3. Aplicações práticas
# Tags de artigos
SADD artigos:tags:42 "tecnologia" "programação"
# Permissões de usuários
SADD perms:usuario:5 "ler" "escrever" "admin"
# Deduplicação de IPs únicos
SADD visitantes_unicos:2024-01-15 "192.168.1.1"
SADD visitantes_unicos:2024-01-15 "192.168.1.2"
SCARD visitantes_unicos:2024-01-15 # 2
6. Sorted Sets: Ordenação por Score e Ranking em Tempo Real
6.1. Estrutura
Sorted Sets combinam a unicidade dos Sets com um score numérico que define a ordem:
ZADD ranking 100 "jogador1" # Score 100
ZADD ranking 200 "jogador2" # Score 200
ZADD ranking 150 "jogador3" # Score 150
ZRANGE ranking 0 -1 # ["jogador1", "jogador3", "jogador2"] (ordem crescente)
ZREVRANGE ranking 0 -1 # ["jogador2", "jogador3", "jogador1"] (ordem decrescente)
ZREM ranking "jogador1"
ZCARD ranking # 2
6.2. Consultas por intervalo de score
ZADD pontuacoes 1000 "ana"
ZADD pontuacoes 2500 "bruno"
ZADD pontuacoes 1800 "carlos"
ZADD pontuacoes 3000 "diana"
# Jogadores com score entre 1500 e 2600
ZRANGEBYSCORE pontuacoes 1500 2600 # ["carlos", "bruno"]
# Quantos jogadores têm score acima de 2000
ZCOUNT pontuacoes 2000 +inf # 2
# Ranking (posição) de um jogador específico
ZRANK pontuacoes "carlos" # 1 (baseado em score crescente)
ZREVRANK pontuacoes "carlos" # 2 (baseado em score decrescente)
6.3. Casos de uso
# Leaderboard de jogo
ZINCRBY leaderboard:jogo1 50 "player:42"
# Fila prioritária (timestamp como score)
ZADD fila_prioritaria 1705315200 "tarefa:1"
ZADD fila_prioritaria 1705315210 "tarefa:2"
ZRANGEBYSCORE fila_prioritaria -inf +inf LIMIT 0 1 # Próxima tarefa mais antiga
# Expiração baseada em timestamp
ZADD sessoes_ativas 1705315200 "sessao:abc123"
ZREMRANGEBYSCORE sessoes_ativas 0 1705315000 # Remove sessões expiradas
7. Estratégias de Modelagem: Quando Usar Cada Tipo de Dado
7.1. Mapeamento de padrões SQL para Redis
Chaves compostas: Use : para simular namespaces e chaves primárias compostas:
# SQL: SELECT * FROM pedidos WHERE usuario_id = 42
# Redis: Chave composta -> "pedidos:42:1001"
# Índices invertidos usando Sets
SADD idx:email:joao@email.com "usuario:5"
SMEMBERS idx:email:joao@email.com # ["usuario:5"]
7.2. Combinação de tipos
# Hash para dados do usuário
HSET usuario:42 nome "João" email "joao@email.com"
# Set para tags associadas
SADD usuario:42:tags "premium" "vip"
# Sorted Set para histórico de compras (timestamp como score)
ZADD usuario:42:compras 1705315200 "pedido:2001"
7.3. Limitações e boas práticas
Atomicidade: Cada comando Redis é atômico, mas para múltiplos comandos use transações:
MULTI
HSET usuario:42 saldo 1000
SADD usuario:42:permissoes "transferir"
EXEC
Persistência: Redis pode ser configurado com RDB (snapshots) ou AOF (append-only file) para persistência em disco, mas lembre-se: Redis é primariamente um cache em memória.
Boas práticas:
- Use TTL para dados temporários
- Prefira Hashes para objetos complexos em vez de strings JSON
- Use Sets para relacionamentos muitos-para-muitos
- Use Sorted Sets quando precisar de ordenação por peso
- Evite armazenar dados muito grandes (acima de 10MB por chave)
Referências
- Documentação Oficial Redis: Data Types — Guia completo sobre todos os tipos de dados suportados pelo Redis, com exemplos e explicações detalhadas.
- Redis: Introdução aos Tipos de Dados — Visão geral conceitual dos tipos de dados e quando utilizar cada um deles.
- Redis: Strings — Documentação específica sobre operações com Strings, incluindo comandos, TTL e contadores atômicos.
- Redis: Hashes — Referência completa sobre Hashes, com exemplos de modelagem de objetos e operações em lote.
- Redis: Sorted Sets — Guia detalhado sobre Sorted Sets, incluindo leaderboards, consultas por intervalo e operações de ranking.
- Redis University: Redis Data Structures — Curso gratuito e oficial sobre estruturas de dados Redis, com exercícios práticos.
- Redis Commands Reference — Referência completa de todos os comandos Redis, com sintaxe, parâmetros e exemplos.