Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Contents

Hash

Redis Hash를 이용해서 하나의 key에 대한 값으로 여러 개의 sub key & value를 저장 할 수 있다. RDBMS의 테이블과 매우 비슷하다. 개인정보를 저장해야 한다고 하면 아래와 같은 Hash 테이블을 만들 수 있을 것이다.
User_ID Email Name Age Address
yundream yundream@gmail.com Yun.Dream 42 Seoul
foo foo@gmail.com Lee.foo 34 Pusan
bar bar@gmail.com Kim.bar 26 Seoul
Redis Hash에서 User_ID가 key가 되고 email, name, age, address는 sub key가 된다.

hmset을 이용해서 Hash 데이터를 저장 할 수 있다. 위 테이블에 있는 데이터를 저장해보자.
172.17.0.2:6379> hmset yundream email "yundream@gmail.com" name "Yun.Dream" age 42  address "Seoul"
OK
172.17.0.2:6379> hmset foo email "foo@gmail.com" name "Lee.foo" age 34 address "Pusan"
OK
172.17.0.2:6379> hmset bar email "bar@gmail.com" name "Kim.bar" age 26 address "Seoul"
OK

Hash는 많은 변에서 Redis의 가장 일반적인 사용모습을 보여준다. 일단 명령셋이 String과 비슷해서, SET, GET, DEL 3개의 명령을 제공한다. 가장 일반적이면서도 가장 널리 사용되기도 하는데, RDBMS의 테이블과 유사한 데이터를 저장 할 수 있어서 응용범위가 넓기 때문이다. Hash 자료를 위해서 제공하는 명령은 아래와 같다.

  • HSET : Hash에 key와 value를 저장한다. 이미 key가 존재할 경우 특정 subkey만 추가하거나 업데이트 할 수 있다.
  • HMSET : 여러 개의 subkey를 한번에 설정한다.
  • HGET : Key로 Hash 값을 가져온다. subkey를 설정해야 한다.
  • HMGET : 여러 개의 subkey를 가져올 수 있다.
  • HGETALL : Key로 Hash의 모든 subkey의 값을 가져온다.
  • HDEL : Hash 특정 subkey를 삭제한다. Hash key를 지우고 싶다면 DEL 명령을 사용해야 한다.
  • HEXISTS : Key가 존재하는지 확인한다.
  • HINCRBY : Subkey의 값을 증감한다.
  • HKEYS : Subkey 목록을 출력한다.
  • HLEN : Subkey의 갯수를 출력한다.

> HGET yundream email
"yundream@gmail.com"

> HGETALL yundream
1) "email"
2) "yundream@gmail.com"
3) "name"
4) "Yun.Dream"
5) "age"
6) "42"
7) "address"
8) "Seoul"

> HDEL yundream email
(integer) 1

> HGET yundream email
(nil)

> HGETALL yundream
1) "name"
2) "Yun.Dream"
3) "age"
4) "42"
5) "address"
6) "Seoul"

> HSET yundream age 44
> HGET yundream age
"44"
> DEL yundream

string vs hash

Hash로 저장 할 수 있는 데이터는 String으로도 저장 할 수 있다. 유저 이메일과 유저 포인트(point)를 저장해야 한다고 가정해보자. Hash로는 아래와 같이 저장 할 수 있을 것이다.
> user:1000  email "yundream@gmail.com" point 325
string으로도 아래와 같이 저장 할 수 있다.
> user:1000:email "yundream@gmail.com"
> user:1000:point 325
어떤 자료구조를 선택해야 하느냐가 약간 고민이 될 수 있을 것 같다.

해시는 매우 작은 공간에 인코딩 되므로 가능한 해시를 사용해서 데이터를 표현하는게 좋다. 예를 들어 이름, 이메일, 세션 등을 이용하는 웹 응용 서비스를 만들어야 한다면, 필수 필드를 모두 포함한 단일 해시를 사용하는게 낫다. Redis의 string을 이용 할 경우 같은 데이터를 저장하기 위해서 더 많은 공간을 써야 한다. 해시로 데이터 구조를 만들면 의미론적으로도 깔끔하고 쓰기, 검색 속도 모두 빠르게 할 수 있다.

예를 들어 아래와 같은 데이터를 저장해야 한다고 가정해보자.
Field 타입 설명
UserID string O 유저아이디
Email string X 이메일
Session string X 세션
Gender string X 성별
Time string X 로그인 시간
String 타입으로는 아래와 같이 입력해야 할 것이다.
> SET user:1132:email    yundream@gmail.com
> SET user:1132:session  xxxxx 
> SET user:1132:gender   man
> SET time:1132:time     1561197174

Hash 타입으로는 아래와 같이 입력할 수 있다.
> HMSET user:1132  email "yundream@gmail.com" session "xxxxx" gender "man" time "1561197174"

응용

쇼핑카트

쇼핑카트 애플리케이션을 개발하기로 했다. 나는 아래와 같이 쇼핑 아이템 정보를 위한 테이블을 설계했다.

 쇼핑카트

redis에는 아래와 같이 입력 할 수 있을 것이다. 상품명을 필드로 했다.
> HSET cart:user0001 1000024 2
> HSET cart:user0001 3192192 1
> HSET cart:user0004 218909 1
> HSET cart:user0005 1311217 2
HGETALL로 유저 카트에 있는 모든 아이템을 읽을 수 있다.
> HGETALL cart:user0001
1) "1000024"
2) "2"
3) "3192192"
4) "1"
카트의 주요 기능들을 hash로 구현 할 수 있는지 검토해보자.
  1. 하나의 카트에 두개 이상의 아이템 입력 : HSET을 이용 아이템 ID를 필드이름으로 구현 할 수 있다.
  2. 특정 아이템 삭제 : HDEL 로 삭제 할 수 있다.
  3. 특정 아이템의 값을 업데이트 : HSET으로 업데이트 하면 된다.
  4. 아이템 가져오기 : HGETALL로 모든 아이템을 가져온다. 특정 하나의 아이템만 가져오는 기능은 굳이 구현할 필요가 없을 것이다.
아이템을 추가 구매할 경우 HINCRBY등을 사용할 수 있겠으나, (쇼핑카트 구현의 경우에는)그다지 좋은 생각은 아니다. 이런 연산은 그냥 애플리케이션에 맡기는게 낫다.

참고

  Redis Data structure - SET 목차