BACKEND

Redis ZSET, 제대로 이해하기

gngsn 2023. 12. 27. 00:06

본 포스팅은 Redis의 정렬된 집합 자료 구조형인 ZSET 명령어에 대해 알아봅니다.

 

 

ZSETs

Sorted Set, 정렬된 집합

 

ZSET는 score에 대한 member의 매핑 값을 저장할 수 있습니다.
HASHes의 키 및 값과 유사하다고 볼 수 있습니다.


이러한 매핑 값을 통해 숫자 값의 score를 조작할 수도, 또한 score 정렬 순서에 따라 가져올 수도, score 값 뿐만 아니라 member와 score를 한 번에 검색해 가져올 수 있습니다.

score은 실제로 'IEEE 754 floating-point doubles'에 따라 Redis 내부에 저장됩니다.

 

 

이 절에서는 ZSET에서 작동하는 명령어에 대해 알아보겠습니다.

 

 

 

Sorted Set

 

Command FORMAT Example use and description
ZADD ZADD key-name score member ... ZSET에 입력받은 점수들을 각 member에 추가
ZSCORE ZSCORE key-name member Returns the score of the member in the ZSET
ZREM ZREM key-name member ... ZSET에서 입력받은 score 제거. 제거된 members들의 개수 리턴
ZCARD ZCARD key-name Returns the number of members in the ZSET
ZCOUNT ZCOUNT key-name min max Returns the number of members with scores between the provided minimum and maximum
ZINCRBY ZINCRBY key-name increment member—Increments the member in the ZSET
ZRANK ZRANK key member [WITHSCORE] Returns the position of the given member in the ZSET
ZRANGE ZRANGE key-name start stop [WITHSCORES] Returns the members and optionally the scores for the members with ranks between start and stop



ZRANGE 는 2편에서 소개하도록 하겠습니다.

 

 


 

📌 ZADD

🏷️ @write, @fast

 

🔗 Link: redis.io - ZADD 

⏱️ Time complexity: O(log(N))

N: the number of elements in the sorted set

 

 

ZADD key-name score member [score member ...]

 

 

ZSET에 입력받은 점수들을 각 member에 추가합니다.

 

✔️ Example.

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 1 "uno"
(integer) 1
redis> ZADD myzset 2 "two" 3 "three"
(integer) 2
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "uno"
4) "1"
5) "two"
6) "2"
7) "three"
8) "3"

 

 

✔️ Options

ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member ...

 

  • XX: 이미 존재하는 요소에 한해 업데이트하며 추가하지 않음
  • NX: 이미 존재하는 요소는 업데이트하지 않고 오직 새로 추가
  • LT: 이미 존재하는 요소보다 Score이 작은 경우에만 업데이트 This flag doesn't prevent adding new elements.
  • GT: Only update existing elements if the new score is greater than the current score. This flag doesn't prevent adding new elements.
  • CH: Change의 약자. 새로 추가된 요소의 수뿐만 아니라, 변경된 요소의 수와의 합을 반환. (일반적으로는 새로 추가된 요소들의 수만을 반환)
  • INCR: ZINCRBY 처럼 동작. 오직 하나의 score-element 쌍을 지정할 수 있음

Note: The GT, LT and NX options are mutually exclusive.




 

📌 ZSCORE

🏷️ @read, @fast

 

🔗 Link: redis.io - ZSCORE

⏱️ Time complexity: O(1)

 

ZSCORE key-name member

 

 

ZSET에 존재하는 score값을 key나 member으로 조회합니다.

반환 값은 string 혹은 숫자(double) 이 될 수 있습니다.
혹은, key나 member가 존재하지 않다면 nil을 반환합니다.

 

 

✔️ Example.

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZSCORE myzset "one"
"1"



 


 

 

📌 ZREM

🏷️ @write, @fast

 

🔗 Link: redis.io - ZREM

⏱️ Time complexity: O(M*log(N))

N: the number of elements in the sorted set
M: the number of elements to be removed

 

ZREM key-name member [member ...]

 

 

ZSET 내의 특정 member들을 제거하고, 제거된 members들의 개수 반환합니다.
존재하지 않는 member들은 무시합니다.
단, key가 존재하지만 Sorted Set는 없을 때 오류를 반환합니다.

 

 

✔️ Example.

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZREM myzset "two"
(integer) 1
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "three"
4) "3"




 

📌 ZCARD

🏷️  @read, @fast

 

🔗  redis.io - ZCARD

⏱️ Time complexity: O(1)

 

ZCARD key

 

각 key에 대한 Sorted Set의 Cardinality(요소들의 갯수)를 반환합니다.

 

 

✔️ Example.

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZCARD myzset
(integer) 2




 

📌 ZCOUNT

🏷️ @read, @fast

 

🔗 Link: redis.io - ZCOUNT

⏱️ Time complexity: O(log(N))

N: the number of elements in the sorted set

 

ZCARD key

 

 

key에 해당하는 sorted set 내에, min과 max 사이 score의 개수를 반환합니다.
min 및 max 인수는 ZRANGEBYSCORE 과 동일한 의미를 갖습니다.

 

Note: 내부적으로 ZRANK(ZRANK 참조)를 사용하기 때문에 복잡도는 O(log(N))입니다.

범위 내 요소의 크기에 비례하는 작업을 수행할 필요가 없습니다.

 

 

✔️ Example.

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZCOUNT myzset -inf +inf
(integer) 3
redis> ZCOUNT myzset (1 3
(integer) 2



 

📌 ZINCRBY

🏷️  @write, @fast

 

🔗 redis.io - ZINCRBY

⏱️ Time complexity: O(log(N))

N: the number of elements in the sorted set

 

ZINCRBY key increment member

 

 

key에 저장된 sorted set의 member의 score를 증가시킵니다.
정렬된 집합에 구성원이 존재하지 않으면, 마치 이전 점수가 0.0이었던 것처럼 가정하고 증가합니다.


key가 존재하지 않으면 지정된 member을 단독 member으로 하는 새로운 정렬된 집합이 만들어집니다.

key가 존재하지만 sorted set을 보유하지 않으면 오류가 반환됩니다.

 

score 값은 숫자 값의 문자열 표현이어야 하며, 배정밀도(double precision) 부동 소수점 숫자 형식을 사용합니다.
score를 감소시키고 싶다면 음수의 값을 입력하면 됩니다.

 

 

✔️ Example.

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZINCRBY myzset 2 "one"
"3"
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "two"
2) "2"
3) "one"
4) "3"



 


 

📌 ZRANK / ZREVRANK

🏷️ @read, @fast

 

🔗 ZRANK ZREVRANK

⏱️ Time complexity: O(log(N))

N: the number of elements in the sorted set

 

ZRANK key member [WITHSCORE]
ZREVRANK key member [WITHSCORE]

 

 

ZSET에서 지정된 member의 순위rank를 반환합니다.

 

ZRANK key에 저장된 sorted set의 member의 순위를 오름차순으로 반환합니다.
순위 (rank 혹은 index)는 0을 기준으로 하며, 점수가 가장 낮은 구성원의 순위가 0 입니다.

ZREVRANK를 사용하면 내림차순으로 원소의 순위를 얻습니다.


key에 저장된 정렬된 집합의 member 순위를 높은 점수에서 낮은 점수로 반환합니다.

두 명령어 모두, 옵션 WITHSCORE 을 추가하면 rank 뿐만 아니라 score 값도 함께 얻을 수 있습니다.

 

 

✔️ Example.

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZRANK myzset "three"
(integer) 2
redis> ZRANK myzset "four"
(nil)
redis> ZRANK myzset "three" WITHSCORE
1) (integer) 2
2) "3"
redis> ZREVRANK myzset "one"
(integer) 2
redis> ZRANK myzset "four" WITHSCORE
(nil)

 

 

 


 

 

📌 ZRANGE

🏷️ @read, @slow

 

🔗 Link: redis.io - ZRANGE 

⏱️ Time complexity: O(log(N)+M)

N: the number of elements in the sorted set
M: the number of elements returned

 

ZRANGE key start stop [BYSCORE | BYLEX] [REV] [LIMIT offset count] [WITHSCORES]

 

 

<key>에 저장된 정렬된 집합의 요소 범위를 지정한 값으로 반환합니다.

ZRANGE는 index(rank), score 또는 사전적 정렬과 같은 다양한 유형의 range 쿼리를 수행할 수 있습니다.

Redis 6.2.0부터, 아래의 명령어들로 조건에 맞는 range 쿼리를 사용할 수 있습니다.

 

 

ZREVRANGE → ZRANGE + REV

ZRANGEBYSCORE → ZRANGE + WITHSCORE

ZREVRANGEBYSCORE → ZRANGE + REV + WITHSCORE

ZRANGEBYLEX → ZRANGE + BYLEX

ZREVRANGEBYLEX → ZRANGE + REV + BYLEX

 

공식문서를 참고하면, 좌측 명령어는 Deprecated 되고, 우측 명령어를 사용하는 것을 권장합니다.

ZSET에 입력받은 점수들을 각 member에 추가합니다.

 

 

✔️ Example.

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 1 "uno"
(integer) 1
redis> ZADD myzset 2 "two" 3 "three"
(integer) 2
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "uno"
4) "1"
5) "two"
6) "2"
7) "three"
8) "3"

 

 

 

✔️ Options

ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member ...

 

  • XX: 이미 존재하는 요소에 한해 업데이트하며 추가하지 않음
  • NX: 이미 존재하는 요소는 업데이트하지 않고 오직 새로 추가
  • LT: 이미 존재하는 요소보다 Score이 작은 경우에만 업데이트 This flag doesn't prevent adding new elements.
  • GT: Only update existing elements if the new score is greater than the current score. This flag doesn't prevent adding new elements.
  • CH: Change의 약자. 새로 추가된 요소의 수뿐만 아니라, 변경된 요소의 수와의 합을 반환. (일반적으로는 새로 추가된 요소들의 수만을 반환)
  • INCR: ZINCRBY 처럼 동작. 오직 하나의 score-element 쌍을 지정할 수 있음

Note: The GT, LT and NX options are mutually exclusive.