DSMP 프로젝트 Database 설계 중 발생한 이슈의 발생 원인부터 해결 과정까지를 정리해서 기록하겠다.
내가 프로젝트 'SPRINT2'단계에서 맡은 파트는 환자의 metadata를 프로젝트 별로 생성 관리할 수 있도록 데이터베이스 스키마를 설계하고 관련 api를 구축하는 것이었다. 문제의 발생은 데이터 베이스 스키마 설계 과정 중에 발생한 문제이다.
먼저 초기 스키마를 보면서 문제 발생 과정을 계속 설명하겠다.
위 스키마에서 보듯이 한 프로젝트 내에 여러개의 환자들의 metadata들을 embedded document 형식으로 Array를 저장하는 형식으로 설계했다.
문제 발생의 시발점은 metadata를 Array로 filed값에 저장한 것으로 부터 시작됐다. 현재 진행하는 DSMP의 프로젝트에서 프로젝트 document 마다 관리하는 metadata의 갯수는 maximum 없이 대용량 데이터가 저장 될 수 있어 mongoDB에서 제공하는 document 최대 용량 16MB를 넘어선다.
그래서 이를 해결하기 위해 stackoverflow에 document 욜량이 16MB를 넘을 때 처리하는 방법에 대해 찾아 보니, gridFS라고 데이터를 chunk 단위로 분리시켜 파일시스템으로 저장하는 형식이 있었다. 하지만 이는 image나 file과 같은 것들을 저장하는 용도 였기에 지금 직면한 문제의 해결 방법으로는 적합하지 않았다. 그래서 생각해낸 방법은 지난 학기 Database에서 배운 Normarization의 대한 개념이었다.
즉, metadata들을 project collection에서 분리 시키는 것이었다. 최종적으로 고안한 스키마는 아래와 같다.
SPRINT2.2버젼 :
위와 같이 metadata들을 project collection에서 분리 시킴
기존 SPRINT2.1버젼 스키마의 구성에서 보면 project document 내에 metadata들이 array 형식으로 들어온다. 이렇게 구성 될 시 Unbounded Array가 되기에 MongoDB의 Maximum size 16MB 의 크기를 넘게 되는 문제와 더불어 수정 삭제 혹은 조회시 Disk I/O로 인한 성능 문제가 발생하게된다.
SPRINT2.2버젼은 이를 개선 하기 위해 기존 SPRINT2.1버젼의 project document 내에 metadata array를 metadata collection으로 분리(Normarization) 시켰다. 이를 통해 좀더 Entity별로 확실한 구분이 가능해졌고 array 가 아닌 document 단위로 metadata를 관리할 수 있게 된다 (document 최대 크기를 넘는 가능성의 이슈가 없어짐). 추가적으로 추후 유저관련 collection을 추가하는 작업 등 데이터베이스의 스키마 확장성 측면에서도 더 효율적일 듯 하다.
현재 개선된 SPRINT2.2버젼 같은 경우 metadata collection에서 모든 프로젝트에 포함되는 metadata를 관리한다. 그렇기에 특정 project_id로 metadata를 조회시 disk에 저장된 metadata를 찾는 과정은 비 연속적인 section을 탐색해야 하기에 lotating delay가 길어 비효율적인 seektime이 예상된다.
이를 해결하기 위해 metadata collection에 project_id로 secondary index를 구성하여 seektime 측면에서 좀 더 좋은 효율성을 가질 수 있을 것이라 생각된다.
추가적으로 DSMP 프로젝트 특성상 수정,삭제 보다는 조회 기능의 빈도가 높아 index를 사용함으로써 얻는 이점이 index를 유지함으로서 얻는 overhead 보다 좋을 것이라 생각된다.
mongoDB 역시 oracle과 같이 B-tree를 사용하여 index를 구축한다.
MongoDB 공식문서 : https://docs.atlas.mongodb.com/schema-suggestions/avoid-unbounded-arrays/
B-tree 개념 : https://velog.io/@seanlion/btree
github issue 정리 : https://github.com/BEOKS/DicomProject/issues/78