본문 바로가기

database

데이터 중심 애플리케이션 설계 2장 다시 읽기(RDB vs NoSQL)

데이터 중심 애플리케이션 설계(Designing Data-Intensive Applications) 2장 데이터 모델과 질의 언어를 읽으며 생각할만한 내용에 대해서 자유롭게 적어보고자 한다. 예전에 한 번 읽었던 내용이지만 최근 RDB와 NoSQL에 대해서 생각해보며 관점이 달라진 것이 있는지 스스로 돌아보고 싶었다.

현재 가지고 있는 생각은 이렇다. 데이터베이스란 근본적으로 데이터를 저장(write)하고 조회(read)하는, 어딘가에 데이터를 쓰고 읽는 행위의 공간이다. 수정(modify)을 하기도 하는데, 수정을 하기 위해서는 읽은 뒤에 쓰는 행위가 필요하다. 결국 읽기와 쓰기의 문제다.

이 때 데이터베이스 제품이 다양한 이유가 데이터를 어떻게 저장할 것인가의 문제에서 파생된다고 본다. 데이터를 어떻게 저장해야, 그리고 어떻게 읽어야 특정 application에 적합할지를 데이터베이스 제품이 어느정도 강제하고 있는 것이다. 내가 다루는 데이터가 어떻게 쓰이고 읽혀야 효율적일지를 판단할 수 있다면, 이에 맞는 데이터베이스 선택도 가능할 것이다.

개인적으로는 그래도 제품을 '활용'하고 있다고 볼만한 것은 Oracle이나 MySQL 같은 RDB 인 듯 싶다. Redis나 MongoDB 같은 제품을 토이 프로젝트 등에서 사용은 해보았지만, 제대로 안다고는 생각치 않는다. 항상 이론과 실제 사이의 간극은 존재하기 때문이다. 현실 세계에서 일어나는 문제(problem)를 해결(solving)하는 과정에서는 다양한 변인 요소(fators)들이 존재하고, 그럴듯한 이론과는 다소 다른 양상이 펼쳐지기 마련이다. 이론을 안다는 것과 이를 활용하여 현실 세계의 문제를 해결한다는 것은 다른 문제다.

이론적으로 document-based DB를 사용하는 것이 더 올바르라고 추측될 수 있는 상황에서도, 사실은 RDB를 사용하여도 무방한 상황이 그렇다. 데이터가 지속적으로 변경, 추가될 것 같은 상황에서 schema-less하게 관리하는 것이 더 용이해보이지만, 실제로 운영해보면 그렇게 자주 변경이 일어나지가 않는다. 기존에 RDB를 사용하고 있는 조직이라면 MongoDB 등의 제품을 새로 도입하는 것으로 인해 팀원들의 학습이 필요하기도 하다. 당장 중요한 서비스 개발건이 있는데 학습으로 인해 개발 주기가 늦춰진다면 그것도 문제다. (개인적으로는 학습이 장기적으론 조직에도 투자라고 생각하지만 단기 성과가 중요한 상황이라면 그렇다)

결정적으로는 다른 데이터베이스 제품을 활용해서 현실의 문제를 해결해야만 할 경험이 없는 것이 문제라고 생각이 되긴 하는데, 그럼에도 계속 공부하는 이유가 결국에는 기존 문제 해결 방식의 임계점이 분명히 도달할 것이라고 생각되어서다. 사설이 길어졌는데 아무튼 2장으로 들어가보자.

데이터 모델과 질의 언어

"데이터 모델은 아마도 소프트웨어 개발에서 제일 중요한 부분일 것이다. 데이터 모델은 소프트웨어가 어떻게 작성됐는지 뿐만 아니라 해결하려는 문제를 어떻게 생각해야 하는지에 대해서도 지대한 영향을 미치기 때문이다."

해결하려는 문제를 어떻게 생각해야 하는지에 영향을 미친다. 책에서는 프로필을 예시로 사용하는데, 여기서 주소 관련 내용이 나온다. 실제 일하면서도 주소 관련된 처리에 대해서도 고민을 하게 되는 지점이 있는데, 주소 체계는 '표준'이다. 특정 고객이 특정 주소를 갖는다고 할 때, 만약에 초기에 아무런 고민 없이 만들었다면, 주소를 저장한 나의 데이터베이스에는 뒤죽박죽인 주소가 저장되어 있을 것이다. 그렇다면 주소의 '표준'에 대해서 생각해보고, '주소를 공통된 형식으로 저장하려면 어떻게 해야할까?'라는 문제가 있다면, 이를 해결하는 방향이 달라진다.

"데이터를 관계형 테이블에 저장하려면 애플리케이션 코드와 데이터 베이스 모델 객체 사이에 거추장스러운 전환 계층이 필요하다. 이런 모델 사이의 분리를 종종 impedeance mismatch라고 부른다."

json 구조의 데이터를 저장할 때, json 데이터 모델을 지원하는 제품에 저장하면 RDB에서의 다중 join 없이 locality를 가진 질의 하나로 데이터를 불러올 수 있다. 그렇지만 만약 위에서 말한 주소 데이터의 중첩 구조가 깊고, 해당 데이터만을 수정해야 하는 문제가 있다면 특정 고객의 root 부터 탐색하여 주소가 있는 계층까지 내려간 다음에 해당 데이터만을 수정해야 한다. 특정 고객만의 정보를 바꾸는 것이 아니라, 주소 체계가 변경되어 일부 특정되지 않는 고객의 주소 정보를 바꿔야 한다면 비용은 훨씬 커진다.(최악의 경우에 모든 고객의 주소 정보를 탐색해서 해당 주소에 대한 정보를 바꿔줘야 한다.)

RDB를 활용했다면 고객은 주소 정보에 대한 참조값을 가지고 있을 것이다. 그리고 해당 주소의 참조값을 key로 주소 관련 정보가 저장되어 있을 것이다. 주소 체계가 변경되어 주소를 변경해야 할 때, 새로운 주소를 만들어 고객의 참조값을 변경해주거나, 변경되 주소 key의 정보만 변경해주면 해결할 수 있다. 구조화된 저장 방식 덕분에(저장 시 write cost에 대한 손해를 감수했기 때문에) read cost를 줄일 수 있게된 것이다.

"문서 데이터베이스처럼 IMS도 일대다 관계에서는 잘 동작한다. 하지만 다대다 관계 표현은 어려웠고 조인은 지원하지 않았다. 개발자는 (비정규화된) 데이터를 중복할지 한 레코드와 또 다른 레코드의 참조를 수동으로 해결할지 결정해야 했다. 1960년대와 70년대의 이 문제는 오늘날 문서 데이터베이스를 사용해서 작업 중인 개발자가 풀어야 할 문제와 매우 비슷하다."

위에서 말한 주소 정보 변경에 대한 문제는 실제로 일대다의 문제로 보이지만, 그래서 문서 기반 데이터베이스에서도 약한 수준의 join을 지원하여 해결할 수는 있지만 메모리, cpu 등의 자원을 다 사용해야 하고 애플리케이션 레벨에서 추가 처리 등이 필요하다.

"관계형 데이터베이스와 오늘날의 문서 데이터베이스 / 문서 데이터 모델을 선호하는 주요 이유는 스키마 유연성, 지역성에 기인한 더 나은 성능 때문이고 일부 애플리케이션의 경우 애플리케이션에서 사용하는 데이터 구조와 더 가깝기 때문이다. 관계형 모델은 조인, 다대일, 다대다 관계를 더 잘 지원함으로써 문서 데이터 모델에 대항한다."

자료 구조의 차이도 있다. RDB는 B+Tree 알고리즘을 사용하여 데이터를 저장(write)한다. write cost를 높이고 read cost를 상대적으로 낮추기 위함이다. range scan에 대한 요구사항이 있을 시 성능적으로 log함수 수준에서 조회가 가능하다.

차이점을 실제 데이터베이스 제품을 사용해보면서 보고자 한다. 이는 다음 글에서 다룬다.