다양한 자료 구조
레디스에서는 Strings, Sets, Sorted Sets, Lists 등 다양한 자료 구조를 지원하고 있다.
각 자료 구조의 정의, 특징, 예시에 대해서 알아보자.
자료 구조 중에서는 Bitfields와 Geospatial indexes는 제외하였으며
명령어도 엔터프라이즈 버전 것은 제외하였다.
참고 사이트에서
명령어에 대한 상세정보를 추가로 확인할 수 있다.
Strings
정의
- 문자열 데이터를 저장 및 조회할 수 있는 기본 자료 구조
특징
- 최대 512 MB까지 저장할 수 있다.
- 단순 증감 연산에 좋다.
- String으로 변환할 수 있는 바이너리 데이터나 이미지 파일도 저장할 수 있다.
예시
"문자열 데이터"
명령어
- 데이터 저장
SET key_이름 값 [EX 만료시간] [PX 만료시간] [NX|XX]
- 값을 저장한다.
- 기존에 데이터가 있으면 덮어쓴다.
- 만료시간 설정
EX
: 초 단위 설정PX
: 밀리초 단위 설정
- 데이터 덮어쓰기 설정
NX
: 신규 key일 때만 데이터 저장XX
: 기존 key일 때만 데이터 저장
EX
,PX
,NX
,XX
옵션은 2.6.12 버전부터 사용할 수 있다.
- 데이터 조회
GET key_이름
- 값을 조회한다.
GETRANGE key_이름 시작_인덱스 종료_인덱스
- 시작 인덱스부터 종료 인덱스까지의 문자열만 조회한다.
- 인덱스는 0부터 시작한다.
STRLEN key_이름
- 문자열의 바이트 수를 리턴한다.
- 데이터 삭제
DEL key_이름
- 데이터를 삭제한다.
DEL key1 key2 key3
처럼 사용하면 여러 데이터를 한꺼번에 지울 수 있다.
- 증감 연산
INCR key_이름
- 값을 1 증가시킨다.
- 신규 key라면 값을 1로 저장한다.
DECR key_이름
- 값을 1 감소시킨다.
- 신규 key라면 값을 -1로 저장한다.
INCRBY key_이름 지정값
- 값을 지정한 값만큼 증가시킨다.
- 신규 key라면 값을 지정한 값으로 저장한다.
DECRBY key_이름 지정값
- 값을 지정한 값만큼 감소시킨다.
- 신규 key라면 값을 - 지정한 값으로 저장한다.
Lists
정의
- 정렬되어 있지 않은 데이터를 모아둔 집합 데이터
특징
- 입력된 순서로대로 저장하기 때문에 정렬되어 있지 않다.
- 내부 데이터는 서로
Linked List(링크드 리스트)
형태로 연결되어 있다. - 중복 데이터를 허용한다.
- 스택 구조나 큐 구조에 적합하다.
- Head나 Tail에서의 추가/삭제는 O(1)의 복잡도를 가진다.
- Head나 Tail이 아닌 Lists 중간에서의 추가/삭제는 보통 O(n)의 복잡도를 가진다.
- 데이터를 조회할 때는 O(n)의 복잡도를 가진다.
- 예시
[S, A, N, G, W, O, N]
명령어
- 데이터 저장
LPUSH key_이름 값
- 데이터를 리스트 왼쪽에 삽입한다.
LPUSH key_이름 값1 값2 값3
처럼 데이터를 한 번에 여러 개 저장할 수도 있다.
RPUSH key_이름 값
- 데이터를 리스트 오른쪽에 삽입한다.
RPUSH key_이름 값1 값2 값3
처럼 데이터를 한 번에 여러 개 저장할 수도 있다.
LSET key_이름 인덱스 값
- 특정 인덱스의 값을 변경한다.
LPUSHX key_이름 값
- 기존 리스트가 존재할 때 데이터를 리스트 왼쪽에 삽입한다.
LPUSH
와 달리 데이터를 1개만 저장할 수 있다.
RPUSHX key_이름 값
- 기존 리스트가 존재할 때 데이터를 리스트 오른쪽에 삽입한다.
RPUSH
와 달리 데이터를 1개만 저장할 수 있다.
- 데이터 조회
LRANGE key_이름 시작_인덱스 종료_인덱스
- 시작 인덱스부터 종료 인덱스까지의 데이터 목록을 조회한다.
- 시작 인덱스와 종료 인덱스를 필수로 지정해야 한다.
- 인덱스는 0부터 시작한다.
- 시작 인덱스에 0을, 종료 인덱스에 -1을 입력하면 전체를 조회한다.
- 실제 데이터 개수보다 범위가 넓어도 에러가 발생하지 않는다.
asc/desc
키워드를 사용하면 정렬이 가능하긴 한데 엔터프라이즈 버전에서만 지원한다.
LLEN key_이름
- 해당 리스트에 있는 데이터의 총 개수를 반환한다.
- 데이터 삭제
LREM key_이름 개수
- 개수가 양수면 왼쪽에서부터 삭제한다.
- 개수가 음수면 오른쪽에서부터 삭제한다.
- 개수가 0이면 전체를 삭제한다.
LTRIM key_이름 시작_인덱스 종료_인덱스
- 시작 인덱스부터 종료 인덱스까지를 제외한 나머지 데이터를 전부 삭제한다.
- 없는 범위를 선택하면 모든 데이터가 삭제되니 주의해야 한다.
- 데이터 조회 및 삭제
LPOP key_이름
- 리스트 왼쪽에서 데이터 1건을 삭제하면서 해당 데이터의 값을 반환한다.
RPOP key_이름
- 리스트 왼쪽에서 데이터 1건을 삭제하면서 해당 데이터의 값을 반환한다.
Sets
정의
- 정렬되어 있지 않은 데이터를 모아둔 집합 데이터
특징
- 중복 데이터를 허용하지 않는다.
- 교집합이나 합집합같은 일반적인 집합 연산에 효율적이다.
- key와 value가 1:N 관계이다.
- 그래서 집합이라는 의미로 Sets의 value는 member라고 부르기도 한다.
- 예시
{S, A, N, G, W, O}
명령어
- 데이터 저장
SADD key_이름 값
- 값을 저장한다.
SADD key_이름 값1 값2 값3
처럼 데이터를 한 번에 여러 개 저장할 수도 있다.
SMOVE
- 데이터 조회
SMEMBERS key_이름
- 모든 값을 조회한다.
SCARD key_이름
- 요소의 개수를 조회한다.
- 데이터 삭제
SREM
- 값을 삭제한다.
SREM key_이름 값1 값2 값3
처럼 데이터를 한 번에 여러 개 삭제할 수도 있다.
- 데이터 조회 및 삭제
SPOP
- 집합 연산 (Read Only)
SUNION key_이름...
- 나열한 key 이름에 해당하는 Sets들의 합집합을 조회한다.
- 내부 요소는 특별한 순서없이 정렬된다.
asc/desc
키워드를 사용하면 정렬이 가능하긴 한데 엔터프라이즈 버전에서만 지원한다.
SINTER key_이름...
- 나열한 key 이름에 해당하는 Sets들의 교집합을 조회한다.
- 내부 요소는 특별한 순서없이 정렬된다.
asc/desc
키워드를 사용하면 정렬이 가능하긴 한데 엔터프라이즈 버전에서만 지원한다.
SDIFF key_이름...
- 맨처음에 명시한 Sets를 기준으로 나열한 key 이름에 해당하는 Sets들의 차집합을 조회한다.
- 내부 요소는 특별한 순서없이 정렬된다.
asc/desc
키워드를 사용하면 정렬이 가능하긴 한데 엔터프라이즈 버전에서만 지원한다.
- 집합 연산 (Write Only)
SUNIONSTORE 신규_Sets_key_이름 key_이름...
- 나열한 key 이름에 해당하는 Sets들의 합집합을 생성해서 새로운 이름으로 저장한다.
- 내부 요소는 특별한 순서없이 정렬된다.
- 생성한 신규 집합은
SMEMBER
로 조회한다. - 신규 Sets key 이름 자리에 기존 key 이름을 명시하면 해당 key에 데이터가 저장된다.
SINTERSTORE 신규_Sets_key_이름 key_이름...
- 나열한 key 이름에 해당하는 Sets들의 교집합을 생성해서 새로운 이름으로 저장한다.
- 내부 요소는 특별한 순서없이 정렬된다.
- 생성한 신규 집합은
SMEMBER
로 조회한다. - 신규 Sets key 이름 자리에 기존 key 이름을 명시하면 해당 key에 데이터가 저장된다.
SDIFFSTORE 신규_Sets_key_이름 key_이름...
- 맨처음에 명시한 Sets를 기주으로 나열한 key 이름에 해당하는 Sets들의 차집합을 생성해서 새로운 이름으로 저장한다.
- 내부 요소는 특별한 순서없이 정렬된다.
- 생성한 신규 집합은
SMEMBER
로 조회한다. - 신규 Sets key 이름 자리에 기존 key 이름을 명시하면 해당 key에 데이터가 저장된다.
Sorted Sets
정의
- 정렬되어 있는 데이터를 모아둔 집합 데이터
특징
- 중복 데이터를 허용하지 않는다.
- 데이터를
스코어(Score)
와 함께 저장할 수 있다.- 스코어 값을 기준으로 데이터를 오름차순으로 정렬한다.
- 스코어 값이 동일하다면 사전순으로 정렬한다.
- value는 안 되지만 score는 중복이 가능하다.
- key와 value가 1:N 관계이다.
- 그래서 집합이라는 의미로 Sorted Sets의 value는
member
라고 부른다. - 데이터를 조회할 때는 O(log n)의 복잡도를 가진다.
Sorted Sets
를 줄여서ZSets
라고 부른다.
- 그래서 집합이라는 의미로 Sorted Sets의 value는
- 예시
{"LG": 1, "KT": 2, "SSG": 3, "NC": 4, "KIA": 5}
명령어
- 데이터 저장
ZADD key_이름 스코어 값
- 스코어와 값을 저장한다.
ZADD key_이름 스코어1 값1 스코어2 값2 스코어3 값3
처럼 데이터를 한 번에 여러 개 저장할 수도 있다.
- 데이터 조회
ZRANGE key_이름 시작_인덱스 종료_인덱스 [LIMIT 오프셋 개수] [WITHSCORES]
- 지정한 범위의 데이터를 조회한다.
- 인덱스는 스코어를 기준으로 오름차순으로 생성된다.
- 스코어가 같으면 사전 기준으로 인덱스가 정해진다.
- 시작 인덱스에 0을, 종료 인덱스에 -1을 입력하면 전체를 조회한다.
LIMIT
옵션을 사용하면 일정 개수만 조회할 수 있다.- 오프셋으로 지정한 인덱스부터 조회한다.
- 오프셋은 0부터 시작한다.
- 개수는 1 이상이어야 한다.
- 개수가 0일 경우 조회되지 않는다.
WITHSCORES
옵션을 사용하면 스코어도 함께 조회한다.
ZRANGEBYSCORE key_이름 시작_스코어 종료_스코어 [LIMIT 오프셋 개수] [WITHSCORES]
- 지정한 스코어의 범위에 해당하는 데이터 개수를 조회한다.
- 별도의 지정이 없으면 포함 검색을 한다.
30 100
이면30 <= score <= 100
이 된다.
- 스코어 앞에
(
를 붙이면 해당 포함하지 않는 검색을 한다.(30 100
이면30 < score <= 100
이 된다.
- 별도의 지정이 없으면 포함 검색을 한다.
- 시작 스코어에
-inf
을, 종료 스코어에+inf
를 입력하면 전체를 조회한다.-inf
와+inf
는 그냥 양끝을 지정하는 명령어라서 스코어와 혼합해서 사용해도 된다.
LIMIT
옵션을 사용하면 일정 개수만 조회할 수 있다.- 오프셋으로 지정한 인덱스부터 조회한다.
- 오프셋은 0부터 시작한다.
- 개수는 1 이상이어야 한다.
- 개수가 0일 경우 조회되지 않는다.
WITHSCORES
옵션을 사용하면 스코어도 함께 조회한다.
- 지정한 스코어의 범위에 해당하는 데이터 개수를 조회한다.
ZRANK key_이름 값
- 해당 값의 순위(= 인덱스)를 조회한다.
- 기준 : 스코어의 오름차순
ZREVRANK key_이름 값
- 해당 값의 순위(= 인덱스)를 조회한다.
- 기준 : 스코어의 내림차순
ZSCORE key_이름 값
- 해당 값의 스코어를 조회한다.
ZCARD key_이름
- 데이터의 개수를 조회한다.
ZCOUNT key_이름 시작_스코어 종료_스코어
- 지정한 스코어의 범위에 해당하는 데이터 개수를 조회한다.
ZSCAN key_이름 커서[MATCH 패턴] [COUNT 개수]
MATCH
옵션을 사용하면 패턴에 맞는 데이터만 조회할 수 있다.GLOB style patttern
을 따른다.
COUNT
옵션을 사용하면 지정된 개수만큼 조회한다.ZSCAN zset_name 0 match b*
처럼 사용하면 된다.
- 데이터 삭제
ZREM key_이름 값
- 해당하는 값을 삭제한다.
ZREM key_이름 값1 값2 값3
처럼 데이터를 한 번에 여러 개 삭제할 수도 있다.
- 집합 연산 (Read Only)
ZUNION key_개수 key_이름... [WEIGHTS 가중치...] [AGGREGATE SUM|MIN|MAX] [WITHSCORES]
- 나열한 key 이름에 해당하는 ZSets들의 합집합을 조회한다.
WITHSCORES
옵션을 사용하면 스코어도 함께 조회한다.- 6.2 버전부터 사용할 수 있다.
ZINTER key_개수 key_이름... [WEIGHTS 가중치...] [AGGREGATE SUM|MIN|MAX] [WITHSCORES]
- 나열한 key 이름에 해당하는 ZSets들의 교집합을 조회한다.
WITHSCORES
옵션을 사용하면 스코어도 함께 조회한다.- 6.2 버전부터 사용할 수 있다.
ZDIFF key_개수 key_이름... [WEIGHTS 가중치...] [AGGREGATE SUM|MIN|MAX] [WITHSCORES]
- 맨처음에 명시한 ZSets를 기준으로 나열한 key 이름에 해당하는 ZSets들의 차집합을 조회한다.
WITHSCORES
옵션을 사용하면 스코어도 함께 조회한다.- 6.2 버전부터 사용할 수 있다.
- 집합 연산 (Write Only)
ZUNIONSTORE 신규_Sets_key_이름 key_개수 key_이름... [WEIGHTS 가중치...] [AGGREGATE SUM|MIN|MAX] [WITHSCORES]
- 나열한 key 이름에 해당하는 ZSets들의 합집합을 생성해서 새로운 이름으로 저장한다.
ZINTERSTORE 신규_Sets_key_이름 key_이름... [WEIGHTS 가중치...] [AGGREGATE SUM|MIN|MAX] [WITHSCORES]
- 나열한 key 이름에 해당하는 ZSets들의 교집합을 생성해서 새로운 이름으로 저장한다.
ZDIFFSTORE 신규_Sets_key_이름 key_이름... [WEIGHTS 가중치...] [AGGREGATE SUM|MIN|MAX] [WITHSCORES]
- 맨처음에 명시한 Sets를 기준으로 나열한 key 이름에 해당하는 Sets들의 차집합을 생성해서 새로운 이름으로 저장한다.
- 6.2 버전부터 사용할 수 있다.
- 집합 연산 (공통 사항)
- 내부 요소는 스코어를 기준으로 정렬된다.
- 값이 동일한 요소가 존재한다면 집합 연산이 진행될 때 동일한 요소가 갖고 있는 스코어끼리 연산된다.
- 신규 ZSets key 이름 자리에 기존 key 이름을 명시하면 해당 key에 데이터가 저장된다.
WEIGHTS
옵션을 사용하면 집합 연산을 하기 전에 각 ZSets의 모든 요소의 스코어에 가중치를 곱한다.- 만약에 특정 ZSets의 특정 요소의 스코어가 2고, 가중치가 3이라면
해당 요소의 실제 스코어는 6이 된 상태로 집합 연산을 시작한다.
- 만약에 특정 ZSets의 특정 요소의 스코어가 2고, 가중치가 3이라면
AGGREGATE
옵션을 사용하면 집합 연산 시 발생하는 스코어의 연산 방식을 변경할 수 있다.- 생략하면 기본값은
SUM
이다. SUM
을 사용하면 모든 스코어를 더한다.MIN
을 사용하면 스코어 중에서 가장 작은 값을 사용한다.MAX
를 사용하면 스코어 중에서 가장 큰 값을 사용한다.
- 생략하면 기본값은
Hashes
정의
- 해시형 자료 구조
특징
- Field(필드)와 Value(값)로 구성된다.
- 필드는 일종의 서브 키라고 생각하면 된다.
- 값을 저장 및 조회하려면 레디스 키와 필드를 동시에 사용해야 한다.
- 대부분의 관련 명령어의 복잡도는 O(1)이다.
- HKEYS, KVALS, HGETALL만 복잡도가 O(n)이다.
- 메모리가 허용하는 한 제한 없이 값을 저장할 수 있다.
- 예시
{"Name": "Sangwon", "Age": "27", "Gender": "Male"}
명령어
- 데이터 저장
HSET key_이름 field_이름 값
- 필드와 값을 저장한다.
HMSET key_이름 필드1 값1 필드2 값2 필드3 값3
- 여러 필드에 대한 값을 한 번에 저장한다.
- 데이터 조회
HGET key_이름 field_이름
- 필드로 값을 조회한다.
HMGET key_이름 필드1 필드2 필드3
- 여러 필드에 대한 값을 한 번에 조회한다.
HKEYS key_이름
- 모든 필드 목록을 조회한다.
HVALS key_이름
- 모든 값 목록을 조회한다.
HGETALL key_이름
- 모든 필드 및 값 목록을 조회한다.
HLEN key_이름
- 필드의 개수를 조회한다.
HEXISTS key_이름 field_이름
- 필드가 존재하는 지 확인한다.
STRLEN key_이름 field_이름
- 값의 바이트 수를 조회한다.
- 데이터 삭제
HDEL key_이름 field_이름
- 필드로 value를 삭제한다.
HDEL key_이름 필드1 필드2 필드3
처럼 데이터를 한 번에 여러 개 삭제할 수도 있다.
Bitmaps
정의
- 비트 연산을 사용할 수 있는 자료 구조
특징
- 최대 2^32 Bit까지 저장할 수 있다.
- 저장할 때 저장 공간 절약이 많이 된다.
- 예시
10100111001001010100110010
명령어
- 데이터 저장
SETBIT key_이름 오프셋 값
- 오프셋에는 몇 번째 비트인지를 작성한다.
- 정수만 입력할 수 있다.
- 값은 0과 1만 사용할 수 있다.
- 오프셋은 0부터 시작한다.
- 오프셋에는 몇 번째 비트인지를 작성한다.
- 데이터 조회
GETBIT key_이름 오프셋
- 오프셋에 해당하는 위치의 비트를 조회한다.
BITCOUNT key_이름
- 값이 1인 비트의 개수를 조회한다.
HyperLogLog
정의
- 집합의 데이터 개수를 추정할 수 있는 알고리즘의 이름 겸 레디스의 자료 구조
- Sets를 개선한 자료 구조
특징
- HyperLogLog 알고리즘을 비트 패턴을 분석하여 비교적 정확한 추정 값을 계산할 수 있다.
- 오차는 약 0.81%다.
- 정확하게 계산하는 경우에 사용하면 시스템 부하가 발생한다.
- 추정 값을 계산하는 것에 최적화가 되어 있기 때문이다.
- 중복된 값을 제거할 수 있다.
- 저장 공간이 작아 카운트같은 케이스에 적합하다.
- 저장되는 모든 값이 12 kb로 고정된다.
- 저장된 데이터는 다시 확인할 수 없다.
- 데이터 보안에 적절하다.
- 값을 원소(element)라고 부른다.
- 예시
00110101 11001110 10101010
명령어
- 데이터 저장
PFADD key_이름 값
- 값을 저장한다.
PFADD key_이름 값1 값2 값3
처럼 데이터를 한 번에 여러 개 저장할 수도 있다.
- 데이터 조회
PFCOUNT key_이름
- 원소의 개수를 조회한다.
PFCOUNT key1 key2 key3
처럼 데이터를 한 번에 여러 개 조회할 수도 있다.
PFMERGE key_이름...
- 원소의 개수를 합산해서 조회한다.
- 맨처음에 명시한 key에 해당하는 HyperLogLog에 개수가 합산되어 저장된다.
- 신규 key로 저장해도 되고, 기존 key에 저장해도 된다.
- 나머지 key 목록에 해당하는 HyperLogLog도 삭제되지 않고 남아있다.
Streams
정의
- Log나 IoT 신호와 같이 지속적으로 빠르게 발생하는 데이터를 처리하기 위한 자료구조
특징
- 이벤트성 로그를 처리할 수 있다.
- Kafka나 RabbitMQ같은 일종의 메시지 서비스 기능을 사용할 수 있다.
- 스트림 키 이름, 값, 필드를 사용할 수 있는 자료 구조다.
- 데이터는 추가만 할 수 있고 수정은 할 수 없다.
- 흔히 로그 조회할 때
tail -f
를 사용하는 것처럼 신규 데이터를 실시간으로 확인할 수 있다. - 데이터를 조회할 때 id 값 기반으로 시간 범위로 조회한다.
- Streams는 하나의 테이블이라고 볼 수 있다.
XADD
명령어를 사용해보면 이해할 수 있다.- key는 테이블의 역할을 한다.
- 아이디는 PK의 역할을 한다.
- 필드는 컬럼의 역할을 한다.
- 값은 그냥 값이다.
- 개인적인 느낌이니 이런 거구나라고만 생각하자.
- 5.0 버전부터 사용할 수 있다.
- 예시
{"ID":" 1538319053569-0", {"f1": "v1", "f2": "v2"}}
출처
Data structures
[REDIS] 📚 자료구조 명령어 종류 & 활용 사례 💯 총정리
[Redis] Redis 자료구조 알아보기
Redis 기본 자료구조
[Redis] 레디스 알고 쓰자. - 정의, 저장방식, 아키텍처, 자료구조, 유효 기간
Redis의 기본 자료구조 및 사용법