くりにっき

フルスタックキュアエンジニアです

redisのSorted Setsで同一スコアの場合の順位がどうなるか調べてみた

リアルタイムのランキング処理に超お役立ちなredisのSorted Setsですが、同一スコアがあった時の順番がどうなるのか気になったので調べてみました。

忙しい人のまとめ

同一scoreの場合はmemberのアスキーコード順になる

仮定

  • 同一スコアの場合にはrankはランダム?
  • 同一スコアの場合には先に追加されたものが上のrankになる?
  • 同一スコアの場合には後に追加されたものが上のrankになる?

検証

ローカルのredisにログイン

$ redis-cli --version
redis-cli 3.0.1

$ redis-cli

user_1 にscore 1を追加

127.0.0.1:6379> zadd "exaamle:ranking" 1 "user_1"
(integer) 1

127.0.0.1:6379> zrange "exaamle:ranking" 0 10 withscores
1) "user_1"
2) "1"

user_2 にscore 10を追加

127.0.0.1:6379> zadd "exaamle:ranking" 10 "user_2"
(integer) 1

127.0.0.1:6379> zrange "exaamle:ranking" 0 10 withscores
1) "user_1"
2) "1"
3) "user_2"
4) "10"

user_1のscoreを5に更新

127.0.0.1:6379> zadd "exaamle:ranking" 5 "user_1"
(integer) 0
127.0.0.1:6379> zrange "exaamle:ranking" 0 10 withscores
1) "user_1"
2) "5"
3) "user_2"
4) "10"

user_3にscore 5を追加

127.0.0.1:6379> zadd "exaamle:ranking" 5 "user_3"
(integer) 1
127.0.0.1:6379> zrange "exaamle:ranking" 0 10 withscores
1) "user_1"
2) "5"
3) "user_3"
4) "5"
5) "user_2"
6) "10"

新しく追加されたmenberは後に表示

user_0(アスキーコード的にuser_1よりも前)にscore 5を追加

127.0.0.1:6379> zadd "exaamle:ranking" 5 "user_0"
(integer) 1
127.0.0.1:6379> zrange "exaamle:ranking" 0 10 withscores
1) "user_0"
2) "5"
3) "user_1"
4) "5"
5) "user_3"
6) "5"
7) "user_2"
8) "10"

127.0.0.1:6379> zrank "exaamle:ranking" "user_0"
(integer) 0
127.0.0.1:6379> zrank "exaamle:ranking" "user_1"
(integer) 1
127.0.0.1:6379> zrank "exaamle:ranking" "user_3"
(integer) 2
127.0.0.1:6379> zrank "exaamle:ranking" "user_2"
(integer) 3

user_0が先にきたので同じスコアの場合はアスキーコード順みたい

検証2:memberが文字列ではなく整数値だった場合はどうなる?

score 5で整数のmemberを追加

127.0.0.1:6379> zadd "exaamle:ranking2" 5 1
(integer) 1
127.0.0.1:6379> zadd "exaamle:ranking2" 5 4
(integer) 1
127.0.0.1:6379> zadd "exaamle:ranking2" 5 0
(integer) 1
127.0.0.1:6379> zadd "exaamle:ranking2" 5 10
(integer) 1
127.0.0.1:6379> zrange "exaamle:ranking2" 0 10 withscores
1) "0"
2) "5"
3) "1"
4) "5"
5) "10"
6) "5"
7) "4"
8) "5"

127.0.0.1:6379> zrank "exaamle:ranking2" 0
(integer) 0
127.0.0.1:6379> zrank "exaamle:ranking2" 1
(integer) 1
127.0.0.1:6379> zrank "exaamle:ranking2" 10
(integer) 2
127.0.0.1:6379> zrank "exaamle:ranking2" 4
(integer) 3

memberが整数値でも文字列になってるっぽい