Retour au cours

data / redis

Sets et sorted sets

Leçon 51 exercice

Explication

Ce que vous allez apprendre

  • Garantir l'unicité d'une collection d'éléments avec un set
  • Utiliser les opérations ensemblistes natives (intersection, union, différence) sans code applicatif
  • Construire un classement ordonné par score avec un sorted set (ZSET)
  • Interroger un ZSET par rang ou par plage de score selon le besoin
  • Choisir entre set et sorted set selon que l'ordre compte ou non

Dans quel contexte ?

Un site de contenu affiche les tags associés à chaque article, et propose une fonctionnalité "articles similaires" basée sur les tags en commun entre deux articles. Un jeu vidéo, lui, affiche un classement des meilleurs joueurs mis à jour en temps réel à chaque partie terminée. Ce sont deux besoins différents : le premier a besoin d'unicité et de comparaison d'ensembles, le second a besoin d'unicité ET d'un ordre par score — exactement la distinction entre set et sorted set.

D'abord, le set répond au besoin le plus simple : l'unicité

SADD tags:article:1 "redis" "database" ajoute des éléments à un ensemble où chaque valeur ne peut apparaître qu'une seule fois : ajouter deux fois le même tag n'a aucun effet la seconde fois. C'est une garantie automatique, sans code applicatif à écrire pour la vérifier.

Une fois cette unicité acquise, des opérations ensemblistes deviennent immédiatement disponibles

Comparer les tags de deux articles pour trouver ceux qu'ils ont en commun ne nécessite aucune boucle côté application : SINTER tags:article:1 tags:article:2 calcule l'intersection directement côté serveur Redis, de façon optimisée. SUNION et SDIFF complètent ce trio pour l'union et la différence.

OpérationRésultatCas d'usage
SINTERÉléments communs aux deux setsTags communs, amis en commun
SUNIONTous les éléments, sans doublonFusionner deux listes de tags
SDIFFÉléments du premier set absents du secondCe qui a été retiré, ce qui manque

Ensuite, un besoin différent apparaît dès que l'ordre compte

Un set garantit l'unicité mais n'a aucune notion d'ordre entre ses éléments. Pour un classement, il faut à la fois l'unicité (un joueur n'apparaît qu'une fois) ET un ordre (par score). Le sorted set (ZSET) combine ces deux propriétés : chaque élément est unique, mais associé à un score numérique qui détermine sa position.

Il reste à savoir comment interroger efficacement un classement

ZREVRANGE leaderboard 0 2 WITHSCORES récupère directement le top 3 avec leurs scores, sans jamais avoir à trier quoi que ce soit côté application — le tri est maintenu en permanence par Redis à chaque insertion. ZRANGEBYSCORE leaderboard 100 200 va plus loin en interrogeant une plage de scores précise, transformant le ZSET en un véritable index de plage performant.

Prérequis

Cette leçon suppose que tu es à l'aise avec les strings et leurs opérations atomiques (leçon 2) : ZINCRBY applique le même principe d'incrément atomique, mais au score d'un élément dans un classement.

Piège fréquent

Confondre ZRANK (rang croissant, 0 correspond au score le plus bas) et ZREVRANK (rang décroissant, 0 correspond au score le plus haut) est une erreur fréquente qui inverse silencieusement un classement affiché à l'utilisateur, sans qu'aucune erreur ne soit levée pour le signaler.

Bonne pratique

Utilise un sorted set avec un timestamp comme score pour indexer des événements par ordre chronologique (par exemple ZADD evenements <timestamp> <id_evenement>) : ZRANGEBYSCORE devient alors un moyen très performant de récupérer tous les événements dans une fenêtre de temps donnée, sans base de données supplémentaire.

Maintenant que tu maîtrises les collections avec et sans ordre, la prochaine leçon aborde un mécanisme transversal à toutes les structures Redis : l'expiration automatique des clés avec les TTL.

Commandes & code

Sets et sorted sets

bash
# Sets : collections non ordonnées d'éléments UNIQUES
SADD tags:article:1 "redis" "database" "nosql"
SADD tags:article:1 "redis"                   # ignoré, déjà présent
SMEMBERS tags:article:1
SISMEMBER tags:article:1 "redis"              # -> 1
SCARD tags:article:1                          # nombre d'éléments
SREM tags:article:1 "nosql"

# Opérations ensemblistes : intersection, union, différence
SADD tags:article:2 "redis" "cache" "performance"
SINTER tags:article:1 tags:article:2          # tags communs
SUNION tags:article:1 tags:article:2          # tous les tags, sans doublon
SDIFF tags:article:1 tags:article:2           # tags de l'article 1 absents de l'article 2

# Stocker le résultat d'une opération dans une nouvelle clé
SINTERSTORE tags:communs tags:article:1 tags:article:2

# Sorted sets (ZSET) : éléments uniques ordonnés par un score numérique
ZADD leaderboard 100 "alice" 250 "bob" 80 "carol"
ZINCRBY leaderboard 50 "alice"                # score d'alice passe à 150
ZSCORE leaderboard "alice"                    # -> 150
ZRANK leaderboard "alice"                     # rang croissant (0 = plus petit score)
ZREVRANK leaderboard "alice"                  # rang décroissant (0 = plus grand score)

# Classement top N (ordre décroissant, avec scores)
ZREVRANGE leaderboard 0 2 WITHSCORES

# Requêtes par plage de score (ex : joueurs entre 100 et 200 points)
ZRANGEBYSCORE leaderboard 100 200

# Suppression par rang ou par score
ZREMRANGEBYRANK leaderboard 0 0               # supprime le dernier du classement
ZREMRANGEBYSCORE leaderboard 0 50

Résumé

  • Les sets garantissent l'unicité et offrent des opérations ensemblistes natives (SINTER, SUNION, SDIFF).
  • Les sorted sets combinent unicité ET ordre par score : idéal pour classements, files à priorité, indexation temporelle (score = timestamp).
  • ZRANGEBYSCORE transforme un ZSET en index de plage performant, sans base relationnelle.

Exercices pratiques

1 disponible
1

Mission : corriger un classement de jeu affiché à l'envers

Objectif : Diagnostiquer une inversion de classement causée par une confusion ZRANK/ZREVRANK, et calculer les tags communs entre deux articles avec les bonnes opérations ensemblistes.

Contexte

Un jeu affiche en position 0 le joueur avec le score le PLUS BAS, alors que le produit veut voir le meilleur joueur en tête. Par ailleurs, l'équipe éditoriale veut une fonctionnalité "articles similaires" basée sur les tags en commun entre deux fiches. Tu dois corriger le classement et implémenter la comparaison de tags sans boucle applicative.

Résoudre l’exercice →