Você está certo de que apenas estruturas de dados simples estão disponíveis com o Redis e não podem ser compostas por valor (como você poderia fazer com um banco de dados orientado a documentos, como CouchDB ou MongoDB). No entanto, é possível compor estruturas de dados por referência, e esse é um padrão muito comum.
Por exemplo, os itens contidos em um conjunto podem ser as chaves para outros objetos (listas, tabelas de hash, outros conjuntos, etc...). Vamos tentar aplicar isso ao seu exemplo.
Para modelar um relacionamento entre clientes e dispositivo+porta, você pode usar conjuntos contendo IDs de clientes. Para armazenar informações sobre os clientes, uma tabela de hash por cliente é suficiente.
Aqui estão os clientes:
hmset c:1 name Smith protocol tcp snmp_dest 127.0.0.1 syslog_dest 127.0.0.2
hmset c:2 name Jackson protocol udp snmp_dest 127.0.0.1 syslog_dest 127.0.0.2
hmset c:3 name Davis protocol tcp snmp_dest 127.0.0.3 syslog_dest 127.0.0.4
As chaves desses registros são c:ID
Vamos associar dois deles a um dispositivo e porta:
sadd d:Los_Angeles:11 2 3
A chave deste conjunto é d:device:port. Os prefixos c:e d:são apenas uma convenção. Deve ser criado um conjunto por dispositivo/porta. Um determinado cliente pode pertencer a vários conjuntos (e, portanto, associado a vários dispositivos/portas).
Agora para encontrar os clientes com métodos de entrega ligados a este dispositivo/porta, basta recuperar o conteúdo do conjunto.
smembers d:Los_Angeles:11
1) "2"
2) "3"
em seguida, as informações correspondentes do cliente podem ser recuperadas canalizando vários comandos hgetall:
hgetall c:2
hgetall c:3
1) "name"
2) "Jackson"
3) "protocol"
4) "udp"
5) "snmp_dest"
6) "127.0.0.1"
7) "syslog_dest"
8) "127.0.0.2"
1) "name"
2) "Davis"
3) "protocol"
4) "tcp"
5) "snmp_dest"
6) "127.0.0.3"
7) "syslog_dest"
8) "127.0.0.4"
Não tenha medo do número de comandos. Eles são muito rápidos e a maioria dos clientes Redis tem a capacidade de canalizar as consultas para que seja necessário apenas um número mínimo de viagens de ida e volta. Usando apenas um membro e vários hgetall, o problema pode ser resolvido com apenas duas viagens de ida e volta.
Agora, é possível otimizar um pouco mais, graças ao onipresente comando SORT. Este é provavelmente o comando mais complexo do Redis e pode ser usado para salvar uma viagem de ida e volta aqui.
sort d:Los_Angeles:11 by nosort get c:*->name get c:*->protocol get c:*->snmp_dest get c:*->syslog_dest
1) "Jackson"
2) "udp"
3) "127.0.0.1"
4) "127.0.0.2"
5) "Davis"
6) "tcp"
7) "127.0.0.3"
8) "127.0.0.4"
Em um comando, ele recupera o conteúdo de um conjunto de dispositivo/porta e busca as informações correspondentes do cliente.
Este exemplo foi trivial, mas de forma mais geral, embora você possa representar estruturas de dados complexas com o Redis, ele não é imediato. Você precisa pensar cuidadosamente sobre o modelo tanto em termos de estrutura quanto de acesso a dados (ou seja, em tempo de design, mantenha seus dados E seus casos de uso).