Conjuntos Ordenados do Redis (Parte 1)

Um sorted set (conjunto ordenado) é um conjunto com pontuações, onde os elementos são ordenados pela pontuação. Esta lição aborda operações básicas de conjuntos ordenados.

O que é um Sorted Set?

Características do sorted set:

leaderboard
├─ "player1" → pontuação: 100
├─ "player2" → pontuação: 200
├─ "player3" → pontuação: 300
└─ "player4" → pontuação: 400
💡 Implementação interna: Conjuntos ordenados usam uma skip list + tabela hash. A skip list suporta ordenação eficiente e consultas por intervalo, enquanto a tabela hash permite buscas rápidas de pontuação.

ZADD: Adicionar Elementos

Uso Básico

REDIS
# Adicionar um único elemento
ZADD leaderboard 100 "player1"
(integer) 1  # Retorna número de elementos recém-adicionados

# Adicionar múltiplos elementos
ZADD leaderboard 200 "player2" 300 "player3" 400 "player4"
(integer) 3

Parâmetros do ZADD

REDIS
# NX: Apenas adicionar novos elementos, não atualizar existentes
ZADD leaderboard NX 150 "player1"
(integer) 0  # player1 já existe, não atualizado

# XX: Apenas atualizar elementos existentes, não adicionar novos
ZADD leaderboard XX 500 "player5"
(integer) 0  # player5 não existe, não adicionado

# CH: Retornar o número de elementos alterados (incluindo atualizações)
ZADD leaderboard CH 120 "player1"
(integer) 1  # Atualizou a pontuação de player1

# INCR: Incrementar pontuação (equivalente a ZINCRBY)
ZADD leaderboard INCR 50 "player1"
"170"  # Retorna nova pontuação

Atualizando a Pontuação de um Elemento Existente

REDIS
# Se o elemento já existir, atualiza sua pontuação
ZADD leaderboard 250 "player1"

# Visualizar nova pontuação
ZSCORE leaderboard "player1"
"250"

ZSCORE: Obter Pontuação do Elemento

REDIS
ZADD leaderboard 100 "player1" 200 "player2"

# Obter pontuação
ZSCORE leaderboard "player1"
"100"

# Elemento não existe
ZSCORE leaderboard "naoexiste"
(nil)

ZRANK e ZREVRANK: Obter Posição

ZRANK: Posição do Menor para o Maior

REDIS
ZADD leaderboard 100 "player1" 200 "player2" 300 "player3"

# Posição começa em 0
ZRANK leaderboard "player1"
(integer) 0  # 1º lugar (menor pontuação)

ZRANK leaderboard "player2"
(integer) 1  # 2º lugar

ZRANK leaderboard "player3"
(integer) 2  # 3º lugar

ZREVRANK: Posição do Maior para o Menor

REDIS
# Posição do maior para o menor (maior pontuação é posição 0)
ZREVRANK leaderboard "player3"
(integer) 0  # 1º lugar (maior pontuação)

ZREVRANK leaderboard "player2"
(integer) 1  # 2º lugar

ZREVRANK leaderboard "player1"
(integer) 2  # 3º lugar
💡 Regras de posição:

  • ZRANK: menor para maior pontuação, menor pontuação tem posição 0
  • ZREVRANK: maior para menor pontuação, maior pontuação tem posição 0
  • Posição começa em 0, 1º lugar tem posição 0

ZRANGE e ZREVRANGE: Obter Elementos por Intervalo de Posição

ZRANGE: Obter por Intervalo de Posição (Menor para Maior)

REDIS
ZADD leaderboard 100 "player1" 200 "player2" 300 "player3" 400 "player4"

# Obter todos os elementos
ZRANGE leaderboard 0 -1
1) "player1"
2) "player2"
3) "player3"
4) "player4"

# Obter primeiros 2 elementos
ZRANGE leaderboard 0 1
1) "player1"
2) "player2"

# Obter últimos 2 elementos
ZRANGE leaderboard -2 -1
1) "player3"
2) "player4"

# Obter elementos com pontuações
ZRANGE leaderboard 0 -1 WITHSCORES
1) "player1"
2) "100"
3) "player2"
4) "200"
5) "player3"
6) "300"
7) "player4"
8) "400"

ZREVRANGE: Obter por Intervalo de Posição (Maior para Menor)

REDIS
# Obter todos os elementos do maior para o menor
ZREVRANGE leaderboard 0 -1 WITHSCORES
1) "player4"
2) "400"
3) "player3"
4) "300"
5) "player2"
6) "200"
7) "player1"
8) "100"

# Obter top 3 (maiores pontuações)
ZREVRANGE leaderboard 0 2 WITHSCORES
1) "player4"
2) "400"
3) "player3"
4) "300"
5) "player2"
6) "200"

ZCARD: Obter Contagem de Elementos

REDIS
ZADD leaderboard 100 "player1" 200 "player2" 300 "player3"

ZCARD leaderboard
(integer) 3

ZCOUNT: Contar Elementos Dentro de um Intervalo de Pontuação

REDIS
ZADD leaderboard 100 "player1" 150 "player2" 200 "player3" 250 "player4" 300 "player5"

# Contar elementos com pontuações entre 150 e 250
ZCOUNT leaderboard 150 250
(integer) 3  # player2, player3, player4

# Usar -inf e +inf para infinito negativo/positivo
ZCOUNT leaderboard -inf +inf
(integer) 5  # Todos os elementos

ZREM: Remover Elementos

REDIS
ZADD leaderboard 100 "player1" 200 "player2" 300 "player3"

# Remover um único elemento
ZREM leaderboard "player1"
(integer) 1

# Remover múltiplos elementos
ZREM leaderboard "player2" "player3"
(integer) 2

# Remover um elemento inexistente
ZREM leaderboard "naoexiste"
(integer) 0

ZINCRBY: Incrementar Pontuação

REDIS
ZADD leaderboard 100 "player1"

# Aumentar pontuação em 50
ZINCRBY leaderboard 50 "player1"
"150"  # Retorna nova pontuação

# Diminuir pontuação (passar um número negativo)
ZINCRBY leaderboard -20 "player1"
"130"

Casos de Uso de Sorted Set

Caso de Uso 1: Ranking de Jogos

REDIS
# Atualizar pontuações dos jogadores
ZADD game:leaderboard 1500 "player:123"
ZADD game:leaderboard 2300 "player:456"
ZADD game:leaderboard 1800 "player:789"

# Obter top 10
ZREVRANGE game:leaderboard 0 9 WITHSCORES

# Obter posição do jogador
ZREVRANK game:leaderboard "player:123"

# Aumentar pontuação do jogador
ZINCRBY game:leaderboard 100 "player:123"

Caso de Uso 2: Pesquisas em Alta

REDIS
# Atualizar pontuações de tendência
ZADD hot:search 10000 "Tutorial Redis"
ZADD hot:search 8000 "Python básico"
ZADD hot:search 15000 "JavaScript"

# Obter top 10 tendências
ZREVRANGE hot:search 0 9 WITHSCORES

# Aumentar pontuação de tendência
ZINCRBY hot:search 100 "Tutorial Redis"

Caso de Uso 3: Fila Atrasada

REDIS
# Adicionar tarefas atrasadas (pontuação é o timestamp de execução)
ZADD delay:queue 1719129600 "task:1"  # 2024-06-23 10:00:00
ZADD delay:queue 1719133200 "task:2"  # 2024-06-23 11:00:00

# Obter tarefas antes do tempo atual (tarefas a executar)
ZRANGEBYSCORE delay:queue -inf 1719129600

Caso de Uso 4: Tags Ponderadas

REDIS
# Tags de interesse do usuário (pontuação é o nível de interesse)
ZADD user:1:interests 100 "redis"
ZADD user:1:interests 80 "database"
ZADD user:1:interests 60 "cache"

# Obter tags de maior interesse do usuário
ZREVRANGE user:1:interests 0 4 WITHSCORES

Caso de Uso 5: Rankings de Exame

REDIS
# Pontuações dos alunos
ZADD exam:math 95 "student:1"
ZADD exam:math 88 "student:2"
ZADD exam:math 92 "student:3"

# Obter ranking de pontuações
ZREVRANGE exam:math 0 -1 WITHSCORES

# Obter posição do aluno
ZREVRANK exam:math "student:1"

Otimização de Codificação de Sorted Set

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

Codificação Condição Descrição
ziplist Elementos <= 128, tamanho do elemento <= 64 bytes Lista comprimida, economiza memória
skiplist Elementos > 128 ou tamanho do elemento > 64 bytes Skip list + tabela hash, melhor desempenho

Verificando Tipo de Codificação

REDIS
ZADD pequeno:zset 1 "a" 2 "b" 3 "c"
OBJECT ENCODING pequeno:zset
"ziplist"

# Após adicionar muitos elementos
OBJECT ENCODING grande:zset
"skiplist"

❓ Perguntas Frequentes

P Qual é a diferença entre um sorted set e um set?
R Cada elemento em um sorted set tem uma pontuação e é ordenado por ela. Sets são não ordenados. Sorted sets são ideais para rankings e cenários de classificação.
P As pontuações podem ser decimais?
R Sim. As pontuações são números de ponto flutuante de precisão dupla, suportando decimais.
P ZRANK retorna posições começando de 0 ou 1?
R De 0. O 1º lugar tem posição 0, o 2º lugar tem posição 1.
P Como obtenho o elemento com a maior pontuação?
R Use ZREVRANGE key 0 0 ou ZRANGE key -1 -1.
P Os elementos podem ser duplicados?
R Não. Os elementos são únicos, mas as pontuações podem ser duplicadas.

📖 Resumo

📝 Atividades

  1. Ranking: Use um sorted set para implementar um ranking de jogos — atualize pontuações, visualize posições, obtenha top 10
  2. Lista de tendências: Implemente uma lista de tendências de pesquisa — atualize pontuações de tendência, visualize tendências, aumente tendência
  3. Ranking de exame: Armazene pontuações de alunos em um sorted set, visualize rankings e pontuações
  4. Fila atrasada: Use um sorted set para implementar uma fila de tarefas atrasadas — adicione tarefas, obtenha tarefas pendentes

Próxima Lição

Na próxima lição, nós aprenderemos sobre Conjuntos Ordenados do Redis (Parte 2), abordando operações avançadas de conjuntos ordenados.

100%