상황
JPA는 영속성 개념을 통해 Entity <--> Table 매핑이 되는데 당연히 해당 schema (mysql/mariadb 에서는 database) 정보도 포함되어 매핑된다.
회사에서 현재 대응하고 있는 데이터베이스를 로그성으로 만드는 방식 (db_log_{yyyy}_{mm}) 을 대응하는 것은
JPA로는 불가능 하다. (영속성 개념을 이해 한다면 당연히 불가능하다는 것을 이해하게 된다..)
그래서 이번에 설계중인 제품의 전략을 다르게 해 보려고 한다.
전략1. JPA + Mybatis
- 처리가 완료되지 않은 문서 (접근이 많은 문서)에 대해서는 main database 에 두고
처리가 완료된 문서에 대해서는 log_{yyyy}_{mm} 에 둔다.
그리고 old_{yyyy}_{mm} 에 대해서는 mybatis 로 처리한다.
- 일단 가능은 할테지만 영 마음에 들지 않는다.
전략2. JPA + multi datasource
- 처리가 완료되지 않은 문서 + 최근 문서(설정 가능 ex. 6개월)에 대해서는 main database에 두고
처리가 완료된 문서 중 오래된 문서(설정 가능 ex. 6개월 이상)에 대해서는 old 데이터베이스 둔다.
- JPA 에서는 두개의 datasource 를 관리 하도록 한다.
- 보통은 최근 문서에서 검색이 이루어지며 필요할 경우에만 old 데이터베이스에서 관리되는 entity 에접근하여
검색할 수 있다.
전략3. JPA
- 그냥 하나의 database 에 둔다.
- 결재 문서의 양이 사실 많지 않은 사이트에서는 이렇게 해도 크게 문제되지 않는다.
- 하루에 결재를 해봤자 얼마나 상신하고 결재하겠어... 라는 생각으로 바라보면 가능할 것 같다.
- 하지만 우리의 상식을 뛰어넘는 재미있는 방식으로 제품을 이용하는 고객사들이 많기 때문에...
(ex. 하루 평균 6천건 상신/결재 진행 - 사실상 '결재' 하기 위함이 아닌 '증거'를 남기기 위한 목적)
- 데이터는 파티셔닝을 통해 관리한다.
이미 정의된 항목에 대한 검색은 당연히 이미 index 화 하기 때문에 큰 문제가 되지 않겠지만
새로 만드는 프로젝트에서는 커스텀 필드를 양식 설정 시 추가할 수 있기 때문에
text 로 저장되는 내용에서 like 검색이 되어야 하고 이는 분명 '검색 속도'에 큰 영향이 있을 것이다.
대량 데이터에 LIKE 검색?
보통은
SELECT `column names` FROM `table name` WHERE `column1` LIKE '%search_text%' OR `column2` LIKE '%search_text%' OR `column3` LIKE '%search_text%'
SELECT
`column names`
FROM
`table name`
WHERE
`column1` LIKE '%search_text%' OR
`column2` LIKE '%search_text%' OR
`column3` LIKE '%search_text%'
와 같은 형식으로 검색할 수 밖에 없다.
만약 100만개의 row 가 있다면 위와 같이 쿼리 할 경우 보통 1시간이 넘게 걸린다.
document 번호(ex, auto increment) 가 index 되기 때문에 이 번호로 구간을 나누어 검색하게 되면
속도는 훨씬 빨라지게 된다.
보통 커뮤니티에서 제목+내용 으로 검색하는 기능은 위와 같은 쿼리와 구간을 나누는 방식을 이용하는 것으로 보인다.
만약 rows 수가 5만개가 넘지 않는다면 이렇게만 해도 사실 큰 문제는 없을 것으로 예상 된다.
하지만 위에서 언급한 것 처럼 이상한 사이트들이 있어서.... 다른 방식을 찾아봐야 한다.
Inverted Index
Transactional SQL 에서는 LIKE 검색이 INDEX 기능을 이용할 수 없는 단점이 있기 때문에 이 문제를 극복하기 위해
단어(Term)로 인덱싱하는 inverted index(역색인) 방식이 나타났다.
기존의 데이터베이스가 하나의 구분자(primary key)가 여러 필드를 지정하고 있다면
inverted index에서는 하나의 값(term)이 해당 값이 들어간 문서번호를 지정하는 것이다.
ex) original data
document no | contents |
1 | a fun guide to cooking |
2 | decorating your home |
3 | how to raise a child |
4 | buying a new car |
5 | becoming a new home owner |
ex) inverted index
term | document no |
a | 1,3,4,5 |
becoming | 5 |
buying | 4 |
decorating | 2 |
home | 2,5 |
'becoming home' 이라고 검색하면 becoiming 과 home 으로 나눈 후에
빠르게 (5), (2,5) 라는 결과가 반환되고
5가 가장 유력한 결과물이라고 알수 있게 된다.
term position (찾은 위치)을 함께 저장하면 더 단어 검색 뿐 아니라 순서비교까지 할 수 있다.
문서양식 설정에서 커스텀하게 추가할 수 있는 항목들은 하나의 json string 형태로 text 컬럼에 저장되게 되며
이 데이터를 빠르게 검색하기 위해서는 inverted index (역색인) 원리를 적용할 필요가 있다.
#캠핑 #아빠스타드램 등 인스타그램을 즐겨하면서 #해시태그 를 많이 이용한다.
해시태그를 이용해서 빅데이터를 검색하는 방식이 궁금하여 찾아보던 중 역색인 원리를
현재 설계중인 제품에 적용해볼 필요가 있다고 생각되어 정리 해 본다.
이 원리를 잘 이용하면 xxx, xxxx 에서도 잘 활용할 수 있지 않을까
'IT' 카테고리의 다른 글
UEFI boot mode 변경 시 file system not found (0) | 2020.06.22 |
---|---|
Flyway (Spring Boot + JPA) (0) | 2019.09.10 |
JWT (토큰 기반 인증 방식) 의 이해 (0) | 2019.08.23 |
ASCII / ANSI / UNICODE / UTF-8 쉽게 이해하기 (0) | 2018.09.10 |
Java 유료화?? (1) | 2018.09.02 |