Tout d'abord, examinons un scénario : un site Web doit compter les utilisateurs qui se sont connectés de manière continue au cours d'une semaine et les utilisateurs qui se sont connectés au cours d'un mois.
S'il est implémenté à l'aide d'une base de données traditionnelle telle que Mysql, il sera difficile à réaliser. Mais si vous utilisez Redis pour le faire, c'est très simple. Le type de collection et le type Bitmap de Redis peuvent être facilement obtenus. Aujourd'hui, nous parlerons principalement de la façon d'utiliser les Bitmaps pour implémenter la fonction de comptage des utilisateurs actifs.
Bitmaps
Dans un système informatique, la plus petite unité d'information est un octet, 1 octet équivaut à 8 bits, chaque bit Il ne peut être 0 ou 1 (l'ordinateur ne connaît que ces deux nombres). Les bitmaps permettent la manipulation directe des bits.
Les Bigmaps peuvent être considérées comme un tableau. Chaque bit du tableau ne peut être que 0 ou 1. L'indice du tableau est ici considéré comme un décalage.
Introduisons plusieurs commandes liées aux Bitmaps :
setbit
setbit key offset value : Définissez la valeur du bit correspondant
Par exemple, si les utilisateurs 3, 8, 23 et 32 ont visité le site Web aujourd'hui, alors
setbit user:view:2020-5-17 3 1 setbit user:view:2020-5-17 8 1 setbit user:view:2020-5-17 23 1 setbit user:view:2020-5-17 32 1
Conseils de développement : De nombreux ID d'application ne commencent pas à 1, mais beaucoup commencent à partir d'un nombre spécifié, tel que 1001, 10001. Pour ceux-ci, nous pouvons soustraire la valeur initiale lors du réglage pour éviter de perdre de l'espace
getbit
getbit key offset obtient la valeur du bit spécifié
Si je veux savoir si l'utilisateur n°8 et l'utilisateur n°45 se sont connectés aujourd'hui, alors
127.0.0.1:6379> getbit user:view:2020-5-17 8 (integer) 1 127.0.0.1:6379> getbit user:view:2020-5-17 45 (integer) 0
peut voir cet utilisateur n°8 s'est connecté aujourd'hui, mais l'utilisateur n° 45 ne s'est pas connecté aujourd'hui.
bitcount
bitcount key [start] [end] Obtenez le nombre dans la plage spécifiée de 1
Je veux savoir combien d'utilisateurs se sont connectés aujourd'hui, alors
127.0.0.1:6379> bitcount user:view:2020-5-17 (integer) 4
Opérations entre Bitmaps
bitop op clé destkey [clé ...]
La commande bitop peut effectuer une intersection (et), une union (ou), non (non), exclusive ou (xor) sur plusieurs bitmaps, et les résultats de l'opération Stocké dans destkey.
Si vous souhaitez connaître le nombre d'utilisateurs qui se sont connectés pendant trois jours consécutifs, c'est-à-dire le nombre d'utilisateurs qui se sont connectés les 17, 18 et 19 mai.
Le statut de connexion au cours des trois derniers jours est le suivant :
Les 17, 3, 8, 23 et 32 mai se sont connectés
Utilisateurs n°3, 23, 43 et 54 connectés le 18 mai
Utilisateurs n°3, 5, 23, 32, 56 et 78 connecté le 19 mai
127.0.0.1:6379> bitop and three:and user:view:2020-5-17 user:view:2020-5-18 user:view:2020-5-19 127.0.0.1:6379> bitcount three:and (integer) 2
Si vous voulez savoir combien d'utilisateurs se sont connectés au cours des trois derniers jours.
127.0.0.1:6379> bitop or three:or user:view:2020-5-17 user:view:2020-5-18 user:view:2020-5-19 (integer) 10 127.0.0.1:6379> bitcount three:or (integer) 9
Comme vous pouvez le constater, 9 utilisateurs au total se sont connectés au cours des trois derniers jours.
Combat pratique
Après avoir parlé des connaissances ci-dessus, nous pouvons compléter l'exigence souhaitée : nous devons compter le nombre de connexions consécutives dans les utilisateurs d'une semaine et les utilisateurs qui se sont connectés dans un délai d'un mois.
Simulez d'abord la situation de connexion de l'utilisateur dans les 30 jours. Le pseudo-code est le suivant :
for ($i = 0; $i < 20000; $i++) { $userId = mt_rand(1, 10000); $date = time() - 86400 * mt_rand(0, 30); $key = 'userlogin_'.date('Ymd', $date); $redis->setBit($key, $userId, 1); }
Obtenez les utilisateurs qui se sont connectés dans la semaine. Bien sûr, nous ne les récupérerons pas tous. à la fois, mais on veut les récupérer tous d'un coup comme un certain nombre, le pseudo code est le suivant :
for ($i = 1; $i <= 7; $i ++) { $key = "userlogin_".date('Ymd', time() - (86400*$i)); if ($i == 1) { $redis->bitOp('and', 'week_logined', $key); } else { $redis->bitOp('and', 'week_logined', 'week_logined', $key); } } // 获取前50个用户 $userIds = []; for ($i=1; $i<=10000; $i++) { $ret = $redis->getBit('week_logined', $i); $ret && $userIds[] = $i; if (count($userIds) >=50) break; }
Il y a un point à noter, et c'est aussi une erreur-. point sujet. Pendant le bitop, la première fois, car week_logined n'existe pas encore, donc l'opération est effectuée. Il n'y a qu'une seule clé. Au deuxième démarrage, il y a 2 touches pour effectuer l'opération.
Pour obtenir les utilisateurs connectés dans un délai d'un mois, l'idée est fondamentalement la même que ci-dessus, sauf que le et est remplacé par ou
for ($i = 1; $i <= 3; $i ++) { $key = "userlogin_".date('Ymd', time() - (86400*$i)); $redis->bitOp('or', 'month_loginOnce', 'month_loginOnce', $key); } // 获取一个月内登陆过的用户 $userIds = []; for ($i=1; $i<=10000; $i++) { $ret = $redis->getBit('month_loginOnce', $i); $ret && $userIds[] = $i; }
Vous pouvez voir qu'il y a encore quelques différences entre le ou et le de. ou bien, il n'est pas nécessaire de juger du premier coup. La raison est que tout le monde comprenne.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!