사이드 프로젝트에서 어떤 Database를 사용할지 고민하면서 각 차이점에 대해 알아본 내용들을 정리해보려 합니다.
잘못된 내용이 있거나 도움이 되었다면 댓글 부탁드립니다. 🙏
먼저 요약✌️
관계형 DB의 장점 = 비 관계형 DB의 단점, 비 관계형 DB의 장점 = 관계형 DB의 단점이라고 생각하면 된다.
모두 장단점이 있기 때문에 각 특성을 파악하고 상황에 맞는 DB를 선택해야 한다. 단순히 Node.js는 MongoDB가 좋다는 생각은 잘못됐다.
NoSQL은 최대한 단순하면서 많은 데이터, RDBMS는 복잡하면서 무결성이 중요한 데이터에 용이하다.
즉 금융, 결제와 같이 데이터 간 관계가 복잡하거나 무결성이 중요하다? SQL
변경에 유연해야 하거나 데이터의 양이 많거나 샤딩이 필요하다면 NoSQL
장단점, 용어 비교
SQL(관계형 DB)
장점
- 명확한 스키마. 데이터 무결성 보장
- 트랜젝션 처리, Join 가능
단점
- 스키마 변경이 어려움.
- 대용량 데이터 처리의 한계. 분산이 어려움
NoSQL(비 관계형 DB)
장점
- 스키마, 관계없음. 변경에 용이함
- 대용량 데이터 처리에 최적화되어있음. 확장도 쉬움
단점
- 데이터 무결성을 보장하기 어려움
- 트랜젝션 처리, Join 사용하기 힘듦. 집계 쿼리 사용하기 힘듬.
스키마, 관계
SQL은 엄격한 스키마에 따라서 데이터가 저장되기 때문에 무결성을 보장한다.
SQL은 먼저 테이블의 스키마를 만들어야 하고 테이블 간의 관계를 지정해야 한다.
즉 데이터가 중복되거나 데이터 잘못 들어가는 경우(스키마에 위배되는 경우)를 모두 막아준다는 것이다. 하지만 스키마 변경에 유연하지 않다는 뜻이기도 하다.
만약 필드가 누락되었을 경우 스키마를 다시 정의해야 한다.
스키마를 다시 정의하면 관련된 테이블들과의 관계를 확인해야 하고, 해당 테이블을 사용하는 프로시저, 트리거, 펑션 등을 다시 컴파일해야만 한다.(Invalid Object의 경우)
쿼리 지연이 발생하게 되고 테이블의 공간도 변경된 만큼 추가로 필요하게 되니 여러 가지를 고려해야 한다.
NoSQL은 반대로 유연하지만 무결성을 보장해주지 않는다.
스키마도 없고 관계도 없다. 스키마를 지정하지 않아도 되고 새로운 필드를 언제든지 추가할 수 있다.
처음 사용할 때 충격적이 었던 부분은 Row안에 Row를 넣을 수 있다는 점이었다.(Embedded Document)
글 컬렉션을 설계한다고 가정했을 때 글과 댓글을 하나의 컬렉션에 넣을 수 있다.
한 곳에 데이터를 모아놓게 되면 디스크에서 같은 곳에 위치하기 때문에 빠르게 접근할 수 있기 때문에 컬렉션을 설계할 때에도 왜 Document를 내장하지 않는가? 하는 관점에서 접근해야 한다.
문제는 스키마가 없기 때문에 언제든 필드를 추가/수정할 수 있지만 잘못된 데이터가 들어가더라도 어디서도 알려주지 않는다. 정합성이 떨어질 수밖에 없고 Transaction을 사용하기 힘들기 때문에 금융, 결제와 같은 곳에 사용하기는 부적합하다.
또 SQL의 Join 기능을 사용하기가 힘들다. 다른 컬렉션을 참조하여 Join처럼 사용할 수 있긴 하지만(MongoDB의 populate) 단순히 값을 참조하여 다른 컬렉션의 값을 가져올 뿐, 컬렉션 간 교집합을 가져오는 Inner Join처럼 사용하기 힘들다. Join이 필요 없도록 데이터를 구조화해야 한다.
속도
정확한 성능을 분석한 글은 찾지 못했는데, 그 이유가 관계형 DB(Mongodb)와 비 관계형 DB(Mysql)의 성능은 비교 대상이 아니라고 한다.(document-based vs relational)
단순히 MongoDB가 더 빠르다, Mysql은 느리다 라는 말은 잘못됐다.
대표적으로 Mysql은 multi-thread 방식이고 MongoDB는 single-thread, non-blocking 방식이기 때문에 관계가 복잡하지 않은 Query에 대해서는 MongoDB가 빠르다고 한다.
하지만 single-thread 특성상 하나의 Query가 전체에 영향을 줄 수 있기 때문에 조심해서 사용해야 한다.
MongoDB는 대용량 데이터 처리에 최적화되어있다.
확장(Scaling)
DB를 확장한다고 했을 때 수직적 확장과 수평적 확장으로 구분할 수 있다.
수직적 확장이란 단순히 서버의 성능을 향상하는 것이고 수평적 확장은 데이터베이스가 전체적으로 분산됨을 의미한다.
데이터가 저장되는 방식 때문에 관계형 DB는 일반적으로 수직적 확장만을 지원한다.
반면 MongoDB같은 비관계형 DB는 확장에 용이하게 아키텍처가 설계되어있다.
만약 MongoDB를 사용하려 한다면 MongoDB, mongoose 문서를 자세하게 읽어보고 시작하는걸 추천드립니다.
저처럼 영어라고 안읽다고 삽질하다가 후회하지 않길...
참조 글
'DataBase' 카테고리의 다른 글
MongoDB에서 효율적으로 페이징 처리하기(pagination) (0) | 2022.11.11 |
---|---|
[MongoDB]mongoose에서 가상 필드 조회안하기, Document를 Object로 변환하기 (0) | 2021.11.16 |