select_intro
Redis + SQL
데이터의 새로운 발견
레디스 Key-Value 데이터를
SQL SELECT로 조회할 수 있습니다.
데이터 활용이 획기적으로 향상되었습니다.
형식: SELECT * FROM DATATYPE.KEY*
예 : SELECT * FROM STRING.KEY*
- SELECT의 컬럼은 key, value입니다. ZSet일 경우 Score 컬럼이 추가됩니다.
- Table 부분은 Datatype.key로 구성됩니다.
- Datatype은 String, List, Set, ZSet, Hash, Stream를 사용할 수 있습니다.
- Key는 key* 또는 key1 이렇게 지정합니다.
- key*는 key로 시작하는 모든 데이터(key,value)를 조회합니다.
- 기본으로 Key로 정렬(sort)되어 있습니다.
- 조건(예: string.key* or string.* where key glob 'key*')를 사용하면 인덱스를 사용해서 효율적이고 빠르게 처리합니다.
- 다양한 조건(where)로 조회할 수 있습니다. GLOB(LIKE), BETWEEN, IN, 등
- Group by, Order by, Limit 등을 사용할 수 있습니다.
- SUM(), MIN(), MAX(), LEFT(), TRIM() 등 많은 함수를 사용할 수 있습니다.
- Subquery를 사용할 수 있습니다.
- UNION, INTERSECT, EXCEPT를 사용해서 복합 쿼리를 구성할 수 있습니다.
테스트 데이터 입력: Redis 명령으로 입력
도시 이름 데이터를 입력합니다.
Example
명령> | rms (ls) 기존 데이터 삭제 |
명령> | mset mycity01 Seoul mycity02 Incheon mycity03 Chuncheon mycity04 Daejeon mycity05 Jeonju |
결과> | OK |
명령> | mset mycity06 Daegu mycity07 Gwangju mycity08 Busan mycity09 Jeju |
결과> | OK |
SQL Insert 문으로 입력
Example
명령> |
insert into string values('mycity01','Seoul'), ('mycity02','Incheon'), ('mycity03','Chuncheon'), ('mycity04','Daejeon'), ('mycity05','Jeonju'); |
결과> | 5 inserted |
명령> |
insert into string values('mycity06','Daegu'), ('mycity07','Gwangju'), ('mycity08','Busan'), ('mycity09','Jeju'); |
결과> | 4 inserted |
동영상 설명은 아래에 있습니다.
String 데이터 조회
SELECT * FROM STRING.MYCITY*
String에서 mycity로 시작하는 키와 값(value)를 조회합니다.
Example
명령> | select * from string.*; |
결과> |
0) key|value 키로 정렬되어 조회됩니다. 1) mycity01|Seoul 2) mycity02|Incheon 3) mycity03|Chuncheon 4) mycity04|Daejeon 5) mycity05|Jeonju 6) mycity06|Daegu 7) mycity07|Gwangju 8) mycity08|Busan 9) mycity09|Jeju |
명령> | select * from string.mycity*; |
결과> |
0) key|value 1) mycity01|Seoul 2) mycity02|Incheon 3) mycity03|Chuncheon 4) mycity04|Daejeon 5) mycity05|Jeonju 6) mycity06|Daegu 7) mycity07|Gwangju 8) mycity08|Busan 9) mycity09|Jeju |
명령> | select * from string.mycity05; |
결과> |
0) key|value 1) mycity05|Jeonju |
WHERE
Where 조건으로 조회할 수 있습니다.
비교: =, <, <=, >, >=, !=, <>
Example
명령> | select * from string.mycity* where value = 'Daejeon'; |
결과> |
0) key|value 1) mycity04|Daejeon |
명령> | select * from string.mycity* where value <= 'Daejeon'; |
결과> |
0) key|value 1) mycity03|Chuncheon 2) mycity04|Daejeon 3) mycity06|Daegu 4) mycity08|Busan |
명령> | select * from string.mycity* where value > 'Daejeon'; |
결과> |
0) key|value 1) mycity01|Seoul 2) mycity02|Incheon 3) mycity05|Jeonju 4) mycity07|Gwangju 5) mycity09|Jeju |
명령> | select * from string.mycity* where value != 'Daejeon'; |
결과> |
0) key|value 1) mycity01|Seoul 2) mycity02|Incheon 3) mycity03|Chuncheon 4) mycity05|Jeonju 5) mycity06|Daegu 6) mycity07|Gwangju 7) mycity08|Busan 8) mycity09|Jeju |
BETWEEN
Example
명령> | select * from string.mycity* where value BETWEEN 'Daejeon' and 'Jeju'; |
결과> |
0) key|value 1) mycity02|Incheon 2) mycity04|Daejeon 3) mycity07|Gwangju 4) mycity09|Jeju |
명령> | select * from string.mycity* where value NOT BETWEEN 'Daejeon' and 'Jeju'; |
결과> |
0) key|value 1) mycity01|Seoul 2) mycity03|Chuncheon 3) mycity05|Jeonju 4) mycity06|Daegu 5) mycity08|Busan |
IN
Example
명령> | select * from string.mycity* where key IN ('mycity03','mycity05') ; |
결과> |
0) key|value 1) mycity03|Chuncheon 2) mycity05|Jeonju |
명령> | select * from string.mycity* where key NOT IN ('mycity03','mycity05'); |
결과> |
0) key|value 1) mycity01|Seoul 2) mycity02|Incheon 3) mycity04|Daejeon 4) mycity06|Daegu 5) mycity07|Gwangju 6) mycity08|Busan 7) mycity09|Jeju |
GLOB
Glob는 *(별표), ?(물음표)를 사용하고, 대소문자를 구분합니다.
Example
명령> | select * from string.mycity* where value GLOB 'Dae*'; |
결과> |
0) key|value 1) mycity04|Daejeon 2) mycity06|Daegu |
명령> | select * from string.mycity* where value GLOB 'Dae??'; |
결과> |
0) key|value 1) mycity06|Daegu |
명령> | select * from string.mycity* where value GLOB '*ju'; |
결과> |
0) key|value 1) mycity05|Jeonju 2) mycity07|Gwangju 3) mycity09|Jeju |
명령> | select * from string.mycity* where value NOT GLOB '*ju'; |
결과> |
0) key|value 1) mycity01|Seoul 2) mycity02|Incheon 3) mycity03|Chuncheon 4) mycity04|Daejeon 5) mycity06|Daegu 6) mycity08|Busan |
LIKE
Like는 %(퍼센트), _(밑줄)을 사용하고, 대소문자를 구분하지 않습니다.
Example
명령> | select * from string.mycity* where value LIKE 'dae%'; |
결과> |
0) key|value 1) mycity04|Daejeon 2) mycity06|Daegu |
명령> | select * from string.mycity* where value LIKE '%ju'; |
결과> |
0) key|value 1) mycity05|Jeonju 2) mycity07|Gwangju 3) mycity09|Jeju |
명령> | select * from string.mycity* where value NOT LIKE '%ju'; |
결과> |
0) key|value 1) mycity01|Seoul 2) mycity02|Incheon 3) mycity03|Chuncheon 4) mycity04|Daejeon 5) mycity06|Daegu 6) mycity08|Busan |
ORDER BY
Example
명령> | select * from string.mycity* ORDER BY value; |
결과> |
0) key|value 1) mycity08|Busan 2) mycity03|Chuncheon 3) mycity06|Daegu 4) mycity04|Daejeon 5) mycity07|Gwangju 6) mycity02|Incheon 7) mycity09|Jeju 8) mycity05|Jeonju 9) mycity01|Seoul |
LIMIT
출력 행수를 제한합니다.
- LIMIT <숫자>: 숫자만큼 출력합니다.
- LIMIT <숫자1, 숫자2>: 범위를 지정할 경우 사용합니다.
숫자1은 시작 행수입니다. 0부터 시작합니다.
숫자2는 제한 행수입니다.
네 번째 행부터 네 행을 출력할 경우 3, 4를 지정합니다.
Example
명령> | select * from string.mycity* order by value LIMIT 5; |
결과> |
0) key|value 1) mycity08|Busan 2) mycity03|Chuncheon 3) mycity06|Daegu 4) mycity04|Daejeon 5) mycity07|Gwangju |
명령> | select * from string.mycity* order by value LIMIT 3,4; |
결과> |
0) key|value 1) mycity04|Daejeon 2) mycity07|Gwangju 3) mycity02|Incheon 4) mycity09|Jeju |
FUNCTIONS
COUNT(*)
Example
명령> | select COUNT(*) from string.mycity*; |
결과> |
0) COUNT(*) 1) 9 |
MIN(), MAX()
Example
명령> | select MIN(value),MAX(value) from string.mycity*; |
결과> |
0) min(value)|max(value) 1) Busan|Seoul |
LENGTH()
Example
명령> | select value name, LENGTH(value) length from string.mycity*; |
결과> |
0) name|length 1) Seoul|5 2) Incheon|7 3) Chuncheon|9 4) Daejeon|7 5) Jeonju|6 6) Daegu|5 7) Gwangju|7 8) Busan|5 9) Jeju|4 |
UPPER(), LOWER()
Example
명령> | select UPPER(value), LOWER(value) from string.mycity*; |
결과> |
0) UPPER(value)|LOWER(value) 1) SEOUL|seoul 2) INCHEON|incheon 3) CHUNCHEON|chuncheon 4) DAEJEON|daejeon 5) JEONJU|jeonju 6) DAEGU|daegu 7) GWANGJU|gwangju 8) BUSAN|busan 9) JEJU|jeju |
LEFT(), MID(), RIGHT()
Example
명령> | select LEFT(value,2), MID(value,3,3), RIGHT(value,2) from string.mycity*; |
결과> |
0) LEFT(value,2)|MID(value,3,3)|RIGHT(value,2) 1) Se|oul|ul 2) In|che|on 3) Ch|unc|on 4) Da|eje|on 5) Je|onj|ju 6) Da|egu|gu 7) Gw|ang|ju 8) Bu|san|an 9) Je|ju|ju |
기타 문자열 함수
- REPLACE(): 문자열 바꾸기 REPLACE('ABC','B','D') -> ADC
- INSTR(): 문자열이 포함된 첫 번째 순서 INSTR('ABC','B') -> 2
- TRIM(): 양쪽 공백(space), 문자, 문자열 제거
- LTRIM(): 왼쪽 공백(space), 문자, 문자열 제거
- RTRIM(): 오른쪽 공백(space), 문자, 문자열 제거
숫자 함수
- SUM(): 합계
- AVG(): 평균
- ROUND(): 반올림
- ABS(): 절대값
도시 인구 테스트 데이터 입력
Example
명령> | mset Seoul 9741383 Incheon 2925967 Chuncheon 283742 Daejeon 1525849 Jeonju 654963 |
결과> | OK |
명령> | mset Daegu 2453041 Gwangju 1496172 Busan 3416918 Jeju 489202 |
결과> | OK |
SQL Insert로 입력
Example
명령> |
insert into string values('Seoul', 9741383), ('Incheon', 2925967), ('Chuncheon', 283742), ('Daejeon', 1525849), ('Jeonju', 654963); |
결과> | 5 inserted |
명령> | insert into string values('Daegu', 2453041), ('Gwangju', 1496172), ('Busan', 3416918), ('Jeju', 489202); |
결과> | 4 inserted |
숫자(인구) 데이터 조회
조건 where key < 'a'; 는 mycity가 출력되지 않게 하려고 추가했습니다.
Example
명령> | select * from string.* where key < 'a'; |
결과> |
0) key|value 1) Busan|3416918 2) Chuncheon|283742 3) Daegu|2453041 4) Daejeon|1525849 5) Gwangju|1496172 6) Incheon|2925967 7) Jeju|489202 8) Jeonju|654963 9) Seoul|9741383 |
명령> | select * from string.* where key < 'a' and value < 1000000; |
결과> |
0) key|value 1) Chuncheon|283742 2) Jeju|489202 3) Jeonju|654963 |
명령> | select * from string.* where key < 'a' and value >= 1000000; |
결과> |
0) key|value 1) Busan|3416918 2) Daegu|2453041 3) Daejeon|1525849 4) Gwangju|1496172 5) Incheon|2925967 6) Seoul|9741383 |
SUM(), AVG()
Example
명령> | select sum(value), avg(value) from string.* where key < 'a'; |
결과> |
0) sum(value)|avg(value) 1) 22987237|2554137.44444444 |
명령> | select min(value), max(value) from string.* where key < 'a'; |
결과> |
0) min(value)|max(value) 1) 283742|9741383 |
명령> | select key city, max(value) population from string.* where key < 'a'; |
결과> |
0) city|population 1) Seoul|9741383 |
SET
테스트 데이터 입력: Redis 명령으로 입력
Example
명령> | sadd myset1 Seoul Incheon Chuncheon Daejeon Jeonju |
결과> | 5 |
명령> | sadd myset2 Daejeon Jeonju Daegu Gwangju Busan Jeju |
결과> | 6 |
SQL Insert로 입력
Example
명령> | insert into set values('myset1', 'Seoul', 'Incheon', 'Chuncheon', 'Daejeon', 'Jeonju'); |
결과> | 1 inserted |
명령> | insert into set values('myset2', 'Daejeon', 'Jeonju', 'Daegu', 'Gwangju', 'Busan', 'Jeju'); |
결과> | 1 inserted |
SET 데이터 조회
Set 데이터를 조회합니다.
Example
명령> | select * from set.myset*; |
결과> |
0) key|value 1) myset1|Seoul 2) myset1|Daejeon 3) myset1|Chuncheon 4) myset1|Incheon 5) myset1|Jeonju 6) myset2|Daegu 7) myset2|Jeonju 8) myset2|Daejeon 9) myset2|Gwangju 10) myset2|Busan 11) myset2|Jeju |
명령> | select * from set.myset1; |
결과> |
0) key|value 1) myset1|Seoul 2) myset1|Daejeon 3) myset1|Chuncheon 4) myset1|Incheon 5) myset1|Jeonju |
GROUP BY
Example
명령> | select key from set.myset*; |
결과> |
0) key 1) myset1 2) myset2 |
명령> | select key, count(*) from set.myset* group by key; |
결과> |
0) key|count(*) 1) myset1|5 2) myset2|6 |
명령> | select key, valcnt(key) from set.myset*; group by에 비해서 속도 빠름 |
결과> |
0) key|valcnt(key) 1) myset1|5 2) myset2|6 |
GROUP_CONCAT(*)
Example
명령> | select key, group_concat(value) from set.myset* group by key ; |
결과> |
0) key|group_concat(value) 1) myset1|Seoul,Daejeon,Chuncheon,Incheon,Jeonju 2) myset2|Daegu,Jeonju,Daejeon,Gwangju,Busan,Jeju |
WHERE
Example
명령> | select * from set.myset1 where value = 'Seoul' ; |
결과> |
0) key|value 1) myset1|Seoul |
명령> | select * from set.myset1 where value glob '*cheon' ; |
결과> |
0) key|value 1) myset1|Chuncheon 2) myset1|Incheon |
UNION, INTERSECT, EXCEPT
Example
명령> | select value from set.myset1 union select value from set.myset2 ; |
결과> |
0) value 1) Busan 2) Chuncheon 3) Daegu 4) Daejeon 5) Gwangju 6) Incheon 7) Jeju 8) Jeonju 9) Seoul |
명령> | select value from set.myset1 intersect select value from set.myset2 ; |
결과> |
0) value 1) Daejeon 2) Jeonju |
명령> | select value from set.myset1 except select value from set.myset2 ; |
결과> |
0) value 1) Chuncheon 2) Incheon 3) Seoul |
SUBQUERY
Example
명령> | select * from string.* where key in (select value from set.myset1); |
결과> |
0) key|value 1) Chuncheon|283742 2) Daejeon|1525849 3) Incheon|2925967 4) Jeonju|654963 5) Seoul|9741383 |
명령> | select sum(value),avg(value) from string.* where key in (select value from set.myset1); |
결과> |
0) sum(value)|avg(value) 1) 15131904|3026380.8 |
HASH
테스트 데이터 입력: Redis 명령으로 입력
Example
명령> | rm Seoul Incheon Chuncheon Daejeon Jeonju Daegu Gwangju Busan Jeju 기존 데이터 삭제 |
결과> | 9 |
명령> | hset Seoul population 9741383 han 서울 area 605.20 mayor Kim |
명령> | hset Incheon population 2925967 han 인천 area 1062.60 mayor Lee |
명령> | hset Chuncheon population 283742 han 춘천 area 1116.35 mayor Cheo |
명령> | hset Daejeon population 1525849 han 대전 area 539.35 mayor Bak |
명령> | hset Jeonju population 654963 han 전주 area 206 mayor Son |
명령> | hset Daegu population 2453041 han 대구 area 883.57 mayor Jeong |
명령> | hset Gwangju population 1496172 han 광주 area 501.24 mayor Gang |
명령> | hset Busan population 3416918 han 부산 area 769.89 mayor Jo |
명령> | hset Jeju population 489202 han 제주 area 977.8 mayor Yun |
SQL Insert 문으로 입력
Example
명령> | delete from string.* where key < 'a'; 기존 데이터 삭제 |
결과> | 9 keys deleted |
명령> |
insert into hash values('Seoul', 'population', 9741383, 'han', '서울', 'area', 605.20, 'mayor', 'Kim'), ('Incheon', 'population', 2925967, 'han', '인천', 'area', 1062.60, 'mayor', 'Lee'), ('Chuncheon', 'population', 283742, 'han', '춘천', 'area', 1116.35, 'mayor', 'Cheo'), ('Daejeon', 'population', 1525849, 'han', '대전', 'area', 539.35, 'mayor', 'Bak'), ('Jeonju', 'population', 654963, 'han', '전주', 'area', 206, 'mayor', 'Son'), ('Daegu', 'population', 2453041, 'han', '대구', 'area', 883.57, 'mayor', 'Jeong'), ('Gwangju', 'population', 1496172, 'han', '광주', 'area', 501.24, 'mayor', 'Gang'), ('Busan', 'population', 3416918, 'han', '부산', 'area', 769.89, 'mayor', 'Jo'), ('Jeju', 'population', 489202, 'han', '제주', 'area', 977.8, 'mayor', 'Yun'); |
명령> | 9 inserted |
HASH 데이터 조회
Example
명령> | select * from hash.*; |
결과> |
0) key|population|han|area|mayor 1) Busan|3416918|부산|769.89|Jo 2) Chuncheon|283742|춘천|1116.35|Cheo 3) Daegu|2453041|대구|883.57|Jeong 4) Daejeon|1525849|대전|539.35|Bak 5) Gwangju|1496172|광주|501.24|Gang 6) Incheon|2925967|인천|1062.6|Lee 7) Jeju|489202|제주|977.8|Yun 8) Jeonju|654963|전주|206|Son 9) Seoul|9741383|서울|605.2|Kim |
Order by field
Example
명령> | select * from hash.* order by han; |
결과> |
0) key|population|han|area|mayor 1) Gwangju|1496172|광주|501.24|Gang 2) Daegu|2453041|대구|883.57|Jeong 3) Daejeon|1525849|대전|539.35|Bak 4) Busan|3416918|부산|769.89|Jo 5) Seoul|9741383|서울|605.2|Kim 6) Incheon|2925967|인천|1062.6|Lee 7) Jeonju|654963|전주|206|Son 8) Jeju|489202|제주|977.8|Yun 9) Chuncheon|283742|춘천|1116.35|Cheo |
Where field
Example
명령> | select * from hash.* where population > 1000000; |
결과> |
0) key|population|han|area|mayor 1) Busan|3416918|부산|769.89|Jo 2) Daegu|2453041|대구|883.57|Jeong 3) Daejeon|1525849|대전|539.35|Bak 4) Gwangju|1496172|광주|501.24|Gang 5) Incheon|2925967|인천|1062.6|Lee 6) Seoul|9741383|서울|605.2|Kim |
계산
Example
명령> | select key,han,round(population/area,1) from hash.*; |
결과> |
0) key|han|round(population/area,1) 1) Busan|부산|4438.2 2) Chuncheon|춘천|254.2 3) Daegu|대구|2776.3 4) Daejeon|대전|2829.1 5) Gwangju|광주|2984.9 6) Incheon|인천|2753.6 7) Jeju|제주|500.3 8) Jeonju|전주|3179.0 9) Seoul|서울|16096.1 |
명령> | select key,han,round(population/area,1) density from hash.* order by density desc; |
결과> |
0) key|han|density 1) Seoul|서울|16096.1 2) Busan|부산|4438.2 3) Jeonju|전주|3179.0 4) Gwangju|광주|2984.9 5) Daejeon|대전|2829.1 6) Daegu|대구|2776.3 7) Incheon|인천|2753.6 8) Jeju|제주|500.3 9) Chuncheon|춘천|254.2 |
SUBQUERY
Example
명령> | select * from hash.* where key in (select value from set.myset1); |
결과> |
0) key|population|han|area|mayor 1) Chuncheon|283742|춘천|1116.35|Cheo 2) Daejeon|1525849|대전|539.35|Bak 3) Incheon|2925967|인천|1062.6|Lee 4) Jeonju|654963|전주|206|Son 5) Seoul|9741383|서울|605.2|Kim |
동영상 설명
Redis SQL Select Introduction 1
Redis SQL Select Introduction 2
Redis SQL Select Introduction 3
Performance 성능
Redis-benchmark 성능
Datatype | 명령 | Cmds per sec | SQL SELECT (Cmds per sec) | 비교 |
---|---|---|---|---|
STRING | GET | 115,767 | 47,851 | 41% |
LIST | LRANGE | 63,536 | 16,382 | 26% |
SET | SMEMBERS | 69,156 | 16,423 | 24% |
ZSET | ZRANGE | 17,021 | 10,001 | 59% |
HASH | HGETALL | 25,471 | 4,264 | 17% |
합계 | 290951 | 94921 | 33% |
- Redis-benchmark로 redis 원래 명령과 select를 각각 10만회 조회, 실행 시간 비교
- String은 value 1개, List 부터 Hash까지는 value 100개를 조회한 것이다.
- Redis 원래 명령에 비해 select가 평균 33% 성능이 나온다.
STRING
- GET: src/redis-benchmark -p 7000 -c 10 -n 100000 -r 1000000 get keyA___rand_int__
100000 requests completed in 8.64 seconds, 115767.55 requests per second - SELECT: src/redis-benchmark -p 7000 -c 10 -n 100000 -r 1000000 --hello --ignoreerr select "select * from string.keyA___rand_int__;"
100000 requests completed in 20.90 seconds, 47851.47 requests per second
LIST
- Test Data Input: src/redis-benchmark -p 7000 -c 1 -n 100 -r 100 insert "insert into list values ('mylist1','value___rand_int__')"
- LRANGE: src/redis-benchmark -p 7000 -c 10 -n 100000 lrange mylist1 0 -1 100000 requests completed in 15.74 seconds, 63536.44 requests per second
- SELECT: src/redis-benchmark -p 7000 -c 10 -n 100000 --hello --ignoreerr select "select * from list.mylist1;" 100000 requests completed in 6.10 seconds, 16382.70 requests per second
SET
- Test Data Input: src/redis-benchmark -p 7000 -c 1 -n 100 -r 10000 insert "insert into set values ('myset1','value___rand_int__')"
- SMEMBERS: src/redis-benchmark -p 7000 -c 10 -n 100000 smembers myset1 100000 requests completed in 1.45 seconds, 69156.30 requests per second
- SELECT: src/redis-benchmark -p 7000 -c 10 -n 100000 --hello --ignoreerr select "select * from set.myset1;" 100000 requests completed in 6.09 seconds, 16423.06 requests per second
ZSET
- Test Data Input: src/redis-benchmark -p 7000 -c 1 -n 100 -r 10000 insert "insert into zset values ('zset1',__rand_int__,'value___rand_int__')"
- ZRANGE: src/redis-benchmark -p 7000 -c 10 -n 100000 zrange zset1 0 -1 withscores 100000 requests completed in 5.88 seconds, 17021.28 requests per second
- SELECT: src/redis-benchmark -p 7000 -c 10 -n 100000 --hello --ignoreerr select "select * from zset.zset1;" 100000 requests completed in 10.00 seconds, 10001.00 requests per second
HASH
- Test Data Input: src/redis-benchmark -p 7000 -c 1 -n 100 -r 10000 insert "insert into hash values ('myhash1', 'field___rand_int__', 'value___rand_int__')"
- HGETALL: src/redis-benchmark -p 7000 -c 10 -n 100000 hgetall myhash1 100000 requests completed in 3.93 seconds, 25471.22 requests per second
- SELECT: src/redis-benchmark -p 7000 -c 10 -n 100000 --hello --ignoreerr select "select * from hash.myhash1;" 100000 requests completed in 23.45 seconds, 4264.21 requests per second
<< Commands | Select Intro | Select String >> |
---|
Email
返事がかかってなれば、メールでお知らせします。