Listas do Redis (Parte 2)
Esta lição aborda operações avançadas de lista, incluindo consulta, modificação e inserção de elementos.
LINDEX: Obter Elemento por Índice
LINDEX recupera um elemento pelo seu índice sem removê-lo.
Uso Básico
LPUSH mylist "um" "dois" "três" "quatro" "cinco"
# Obter o primeiro elemento (índice 0)
LINDEX mylist 0
"cinco"
# Obter o segundo elemento
LINDEX mylist 1
"quatro"
# Obter o último elemento
LINDEX mylist -1
"um"
# Obter o penúltimo elemento
LINDEX mylist -2
"dois"
Índice Fora do Intervalo
# Retorna nil quando o índice está fora do intervalo
LINDEX mylist 10
(nil)
LINDEX mylist -10
(nil)
LSET: Definir Elemento por Índice
LSET modifica o elemento em um índice especificado.
Uso Básico
LRANGE mylist 0 -1
1) "cinco"
2) "quatro"
3) "três"
4) "dois"
5) "um"
# Modificar o primeiro elemento
LSET mylist 0 "PRIMEIRO"
OK
# Modificar o último elemento
LSET mylist -1 "ÚLTIMO"
OK
LRANGE mylist 0 -1
1) "PRIMEIRO"
2) "quatro"
3) "três"
4) "dois"
5) "ÚLTIMO"
Índice Fora do Intervalo
LSET mylist 10 "valor"
(error) ERR index out of range
LINSERT: Inserir Antes ou Depois de um Elemento de Referência
LINSERT insere um novo elemento antes ou depois de um elemento de referência especificado.
LINSERT BEFORE: Inserir Antes
LRANGE mylist 0 -1
1) "PRIMEIRO"
2) "quatro"
3) "três"
4) "dois"
5) "ÚLTIMO"
# Inserir "ANTES_TRÊS" antes de "três"
LINSERT mylist BEFORE "três" "ANTES_TRÊS"
(integer) 6 # Retorna o tamanho da lista
LRANGE mylist 0 -1
1) "PRIMEIRO"
2) "quatro"
3) "ANTES_TRÊS"
4) "três"
5) "dois"
6) "ÚLTIMO"
LINSERT AFTER: Inserir Depois
# Inserir "DEPOIS_TRÊS" depois de "três"
LINSERT mylist AFTER "três" "DEPOIS_TRÊS"
(integer) 7
LRANGE mylist 0 -1
1) "PRIMEIRO"
2) "quatro"
3) "ANTES_TRÊS"
4) "três"
5) "DEPOIS_TRÊS"
6) "dois"
7) "ÚLTIMO"
Elemento de Referência Não Encontrado
# Elemento de referência especificado não existe
LINSERT mylist BEFORE "naoexiste" "valor"
(integer) -1 # Retorna -1 quando o pivô não é encontrado
LREM: Remover Elementos por Valor
LREM remove elementos da lista que correspondem a um valor especificado.
Uso Básico
LPUSH mylist "a" "b" "a" "c" "a" "d"
LRANGE mylist 0 -1
1) "d"
2) "a"
3) "c"
4) "a"
5) "b"
6) "a"
# Remover 2 ocorrências de "a" a partir da cabeça
LREM mylist 2 "a"
(integer) 2 # Deletou 2
LRANGE mylist 0 -1
1) "d"
2) "c"
3) "b"
4) "a"
Referência de Parâmetros
| Parâmetro | Descrição |
|---|---|
| count > 0 | Remover count ocorrências a partir da cabeça |
| count < 0 | Remover abs(count) ocorrências a partir da cauda |
| count = 0 | Remover todos os elementos correspondentes |
Remover da Cauda
LPUSH mylist "a" "b" "a" "c" "a"
# Remover 1 ocorrência de "a" a partir da cauda
LREM mylist -1 "a"
(integer) 1
Remover Todos os Elementos Correspondentes
LPUSH mylist "a" "b" "a" "c" "a"
# Remover todos os "a"
LREM mylist 0 "a"
(integer) 3
LRANGE mylist 0 -1
1) "c"
2) "b"
RPOPLPUSH: Mover Elementos
RPOPLPUSH remove o elemento da cauda de uma lista e o insere na cabeça de outra lista.
Uso Básico
# Lista de origem
LPUSH source "um" "dois" "três"
# Lista de destino
LPUSH destination "a" "b"
# Mover cauda da origem para cabeça do destino
RPOPLPUSH source destination
"um" # Retorna o elemento movido
LRANGE source 0 -1
1) "três"
2) "dois"
LRANGE destination 0 -1
1) "um"
2) "a"
3) "b"
Caso de Uso: Fila Circular
# Mover uma tarefa da cauda de volta para a cabeça para processamento round-robin
RPOPLPUSH queue:task queue:task
Caso de Uso: Fila de Backup
# Mover tarefa para fila de backup durante o processamento
RPOPLPUSH queue:task queue:backup
# Se o processamento falhar, a tarefa pode ser recuperada da fila de backup
BRPOPLPUSH: Movimento Bloqueante
BRPOPLPUSH é a versão bloqueante de RPOPLPUSH.
# Se a lista de origem estiver vazia, aguardar bloqueante por até 10 segundos
BRPOPLPUSH source destination 10
LMOVE: Mover Elementos (Redis 6.2+)
LMOVE é uma versão generalizada de RPOPLPUSH que permite especificar ambas as posições de origem e destino.
# Remover da direita da origem, inserir à esquerda do destino
LMOVE source destination RIGHT LEFT
# Remover da esquerda da origem, inserir à direita do destino
LMOVE source destination LEFT RIGHT
Aplicações Avançadas de Lista
Caso de Uso 1: Paginação
# Lista de artigos
LPUSH articles "article:1" "article:2" ... "article:100"
# Página 1 (10 itens por página)
LRANGE articles 0 9
# Página 2
LRANGE articles 10 19
# Página 3
LRANGE articles 20 29
Caso de Uso 2: Contatos Recentes
# Adicionar um contato à lista recente
LPUSH contacts:user:1 "user:2"
# Se já existir, remover primeiro e depois adicionar (mover para o início)
LREM contacts:user:1 0 "user:2"
LPUSH contacts:user:1 "user:2"
# Obter 10 contatos recentes
LRANGE contacts:user:1 0 9
Caso de Uso 3: Escalonamento Round-Robin
# Lista de tarefas
LPUSH tasks "task1" "task2" "task3"
# Round-robin: remover tarefa, processá-la, depois colocá-la de volta na cauda
RPOPLPUSH tasks tasks
"task1" # Processar task1
# Próxima consulta obterá task2
Caso de Uso 4: Log Limitado
# Adicionar uma entrada de log
LPUSH log:app "mensagem de log"
# Manter as 1000 entradas de log mais recentes
LTRIM log:app 0 999
# Visualizar logs recentes
LRANGE log:app 0 99
Otimização de Desempenho de Lista
1. Evitar Operações no Meio
# ❌ Desempenho ruim: inserir ou deletar no meio
LINSERT mylist BEFORE "meio" "novo"
LREM mylist 1 "meio"
# ✅ Bom desempenho: operar apenas na cabeça e cauda
LPUSH mylist "novo"
LPOP mylist
2. Evitar Listas Grandes
# ❌ Lista muito grande
LLEN mylist
(integer) 1000000
# ✅ Usar LTRIM para limitar o tamanho
LTRIM mylist 0 9999
3. Buscar em Lotes com LRANGE
# ❌ Buscar um intervalo enorme de uma vez
LRANGE mylist 0 -1
# ✅ Buscar em lotes
LRANGE mylist 0 99
LRANGE mylist 100 199
4. Escolher a Estrutura de Dados Correta
| Requisito | Estrutura de Dados Recomendada |
|---|---|
| Fila/Pilha | List |
| Últimos N itens | List + LTRIM |
| Paginação | List + LRANGE |
| Lista deduplicada | Set ou Sorted Set |
| Ordenação ponderada | Sorted Set |
Limitações da Lista
1. Busca Lenta de Elementos
# Encontrar um valor específico requer percorrer a lista inteira
LINDEX mylist 500000 # Operação O(N), muito lenta
2. Operações Lentas no Meio
# Inserir ou deletar no meio requer deslocar elementos
LINSERT mylist BEFORE "meio" "novo" # O(N)
3. Não Pode Encontrar Índice por Valor
Redis não fornece um comando para encontrar o índice de um valor pelo seu conteúdo. Isso deve ser implementado no nível da aplicação.
❓ Perguntas Frequentes
LINDEX mylist 0 é equivalente a LRANGE mylist 0 0.📖 Resumo
- LINDEX obtém elemento por índice, LSET define elemento por índice
- LINSERT insere antes ou depois de um pivô (desempenho O(N))
- LREM remove elementos por valor, com controle sobre contagem e direção
- RPOPLPUSH move elementos, usado para filas circulares e filas de backup
- BRPOPLPUSH movimento bloqueante, usado para filas de mensagens confiáveis
- Aplicações avançadas de lista: paginação, contatos recentes, escalonamento round-robin
- Otimização de desempenho: evite operações no meio, limite o tamanho da lista, busque em lotes
📝 Atividades
- Operações de índice: Crie uma lista, use LINDEX para obter elementos em diferentes posições, use LSET para modificar elementos
- Inserir e deletar: Use LINSERT para inserir no meio, use LREM para remover elementos por valor
- Movimento de elementos: Use RPOPLPUSH para implementar uma fila circular para round-robin de tarefas
- Paginação: Crie uma lista com 20 elementos e implemente paginação com 5 itens por página
Próxima Lição
Na próxima lição, nós aprenderemos sobre Conjuntos do Redis (Parte 1), abordando operações básicas de conjunto.



