MySQL DB를 사용하는 경우, 특별한 규칙이 없는 256Byte가 넘는 텍스트는 도리없이 TEXT를 사용한다.
만약 해당 필드를 검색해야 한다면?
TEXT필드를 별도의 테이블로 떼어낸다.
하지만, Row가 수십만이 넘어간다면 어떻게 하더라도 TEXT필드를 검색하기란 여간 부담이 되지 않는다. 그렇다고 검색엔진과 같은 방식을 쓰기에는 배보다 배꼽이 더 크고...
최근에 모 프로젝트를 하면서 유사한 고민이 생겼다.
- 최대 Rows : 10,000,000
- 검색 조건 : 새로 저장할 값이 이미 존재하는 지 해당 필드에서 검색
- View 조건 : 관리자 화면에서 저당된 데이터를 확인할 수 있어야 한다.
다행히도 해당 필드에 대한 일부 검색이 아니고 완전일치 검색이었다. 그래도, 그대로 테이블을 구성하기엔 걱정이 되었다.
방법을 하나 생각했다.
저장해야 할 텍스트를 MD5로 해시하여 DB에 저장하고, 실제 데이터는 파일로 저장하는 것이다. MD5로 해시를 하면 길이가 32Bytes가 되어서 아무리 긴 값이라도 32Bytes의 CHAR형으로 필드를 구성할 수 있으므로 완전 일치 검색을 하기에 부담이 적다.
하지만, MD5는 완전한 중복을 제거할 수가 없어서 또다른 해시를 이용해야 한다.
생각하기 귀찮아 그냥 실 데이터 길이를 MD5값의 뒤에 붙이기로 했다. (운에 맡길 수 밖에...)
정리하면...
1) DB 2) 파일
- DB의 필드는 CHAR(36)로 구성한다.
- 저장할 값 = 실 데이터의 MD5해시(32Bytes) + 실 데이터의 길이(4Bytes)
- 파일 갯수가 많다보니 디렉터리를 분할하여 저장한다. (디렉터리 : 00 ~ ff, 총 256개)
- 디렉터리 구성 : substr("DB에 저장할 값", 0, 2)
- "DB에 저장할 값"을 파일명으로 하여 파일을 생성한다.
- 해당 파일에 실 데이터를 저장한다.
똑같지는 않지만 p2p 등에서 파일의 중복을 없애기 위해 유사한 방법을 이용하기도 한다.