프로젝트를 하면서 백엔드 포지션에서 작업을 진행하게 되면 여러 가지 고민에 사로잡히게 되는데 SQL과 NoSQL을 정하는 것 또한 큰 고민 중 하나에 속하는 것 같다.
MySQL 같은 MySQL 을 사용할 것인가? 아니면 MongoDB 와 같은 NoSQL을 사용할 것 인가...
필자는 아직 MongoDB 와 같은 NoSQL을 사용해 본 적이 없다. 프로젝트를 진행하면서 MySQL과 Postgresql을 사용해본 게 전부라 MongoDB 와 같은 NoSQL을 사용해본 다른 사람들에게 엄청 편하다는 이야기를 많이 들었다. 스키마에 대해 신경 쓰지 않아도 되고 1:N, M:N과 같은 관계를 지정할 필요 없다는 것까지... 듣고 나서 언젠가 사용해보아야 했다고 생각했는데 아직도 그러지 못하고 있다. 꼭 사용해보아야겠다. Node.js를 사용하게 되면 자연스레 NoSQL을 사용하게 된다는데 이 글을 쓰면서도 많은 반성을 했다.
그럼 우선 SQL과 NoSQL이 어떤 것인지 알아보고 그들만의 특징 및 장단점 그리고 마지막으로 어떨 때 SQL, NoSQL이 사용하기 유리한지 생각해보자.
SQL(관계형 DB)
SQL(Strutured Query Language)은 구조화 된 Query Language의 약자로 특정 유형의 DB와 상호작용하는 데 사용하는 Query 언어이다. SQL을 사용하면 RDBMS에서 데이터를 CRUD 할 수 있다.
이러한 RDBMS에는 주요한 특징들이 존재하는데 우선 데이터는 정해진 데이터 스키마를 따라 DB 테이블에 저장된다는 것이고 이 데이터들은 아래의 그림처럼 관계를 통해서 연결된 여러 개의 테이블에 분산된다는 것이다.
데이터는 테이블에 레코드의 형태로 저장되며 각 테이블에는 명확하게 정의된 구조가 있다. 구조는 필드의 이름과 데이터의 유형으로 정의된다. 여기서 SQL 만의 특징이 나타나는데 스키마를 준수하지 않는 레코드는 추가할 수 없다는 것이다. 추가하기 위해서는 스키마를 뜯어고치는 수밖에 없다.
그리고 SQL 기반의 DB의 중요한 것은 관계 부분이다.
데이터들을 여러 개의 테이블에 나누어서 데이터들의 중복을 피할 수 있다. 만약 사용자가 구입한 상품들을 나타내기 위해서는 User, Product, Order 등 여러 테이블을 만들어야 하지만 각각의 테이블들은 다른 테이블에 저장되어 있지 않은 데이터만을 가지고 있다. 즉, 중복된 데이터가 없다는 의미이다.
이러한 부분은 큰 장점을 가진다. 하나의 테이블에서 중복없이 하나의 데이터만을 관리하기 때문에 다른 테이블에서 부정확한 데이터를 다룰 리스크가 줄어든다.
NoSQL(비 관계형 DB)
앞서 언급한 SQL과 반대되는 접근 방식을 따르기 때문에 이처럼 이름이 지어졌다고 한다.
우선 앞서 SQL에서 언급한 특징인 스키마 부분, 관계 부분이 여기서는 존재하지 않는다. NoSQL에서는 레코드를 문서(Documents)라고 부른다고 한다.
앞서 SQL에서는 정해진 스키마를 따르지 않으면 데이터를 추가할 수 없지만 NoSQL에서는 다르다. 다른 구조의 데이터를 같은 컬렉션(SQL에서의 테이블)에 추가할 수 있다.
레코드 즉, 문서는 JSON 데이터와 비슷한 형태를 띠며 스키마에 신경 쓸 필요가 없다.
또한 RDBMS처럼 여러 테이블에 나누어 담는 것이 아니라 관련 데이터를 동일한 컬렉션에 넣는다.
따라서 앞서 말한 SQL의 예시와 비교해보면 많은 Order(주문한 상품)가 있는 경우 일반적인 모든 정보를 포함한 데이터를 Order 컬렉션에 저장한다. Product, User 정보 또한 Order에 한꺼번에 저장되는 것이다.
따라서 여러 테이블(컬렉션)에 조인할 필요가 없이 이미 필요한 모든 것을 갖춘 문서를 작성하게 된다.
실제로 NoSQL DB는 조인이라는 개념이 존재하지 않는다고 한다. 만약 조인을 하고 싶다면 직접 해당 외래 키를 검색하여 사용할 수는 있지만 일반적은 방법은 아니라고 한다.
대신 컬렉션을 통해 데이터를 복제하여 각 컬렉션 일부분에 속하는 데이터를 정확하게 산출하도록 한다.
이러한 방식은 데이터가 결국에 중복되기 때문에 SQL과는 다르게 불안정한 측면이 존재한다. 실수로 컬렉션 B에서는 데이터를 수정하지 않았는데 컬렉션 A에서만 데이터를 업데이트할 위험이 존재하기 때문이다.
그러기에 특정 데이터를 같이 사용하는 모든 컬렉션에서 똑같은 데이터 업데이트를 수행하도록 해야 한다.
이런 경우에도 커다란 장점이 존재한다. 복잡한 조인을 사용할 필요가 없다는 것... 위에서 계속 말한 것 처럼 필요한 데이터가 이미 하나의 컬렉션에 저장되어 있기 때문이다. 특히 자주 변경되지 않는 데이터 일 때에 더 큰 장점을 발휘하게 된다.
SQL과 NoSQL의 특징을 명확하게 느낄 수 있는 단어로 정리 보자면 수직적 확장과 수평적 확장이다.
DB를 어떤 방식으로 확장 시킬 수 있을까?
수직적 확장은 단순히 DB 서버의 성능을 향상하는 것을 말하고
수평적 확장은 더 많은 서버가 추가되고 DB가 전체적으로 분산됨을 의미한다. 따라서 하나의 DB에서 작동하지만 여러 host에서 작동한다.
데이터가 저장되는 방식 때문에 SQL DB는 일반적으로 수직적 확장만 지원하고, 수평적 확장은 NoSQL DB에서만 가능하다.
지금까지 이야기했던 것들을 정리하여 SQL와 NoSQL의 장/단점으로 요약해보자면
SQL의 장점은
명확하게 정의된 스키마와 데이터 무결성을 보장하며 관계는 각 데이터를 중복 없이 한 번만 저장한다.
SQL의 단점은
NoSQL 과 상대적으로 덜 유연하다. 데이터 스키마는 사전에 계획되고 알려져야 한다. 나중에 수정하기가 무척이나 번거롭고 불가능할 수도 있기 때문이다.
관계를 각자 맺고 있기 때문에 조인 문이 많은 매우 복잡한 Query가 만들어질 수 있다.
수평적 확장이 어려우며 대체로 수직적 확장만 가능하다. 어떤 시점에 다다르면 처리할 수 있는 처리량과 관련해 성장 한계에 직면하게 된다.
NoSQL의 장점은
스키마가 없기에 SQL에 비교해 훨씬 유연하다. 언제든지 저장된 데이터를 조정하고 새로운 필드를 추가할 수 있다.
데이터는 애플리케이션이 필요로 하는 형식으로 저장되며 이렇게 되면 데이터를 읽어오는 속도가 빨라진다.
수직 및 수평 확장(수직보다 수월)이 가능하므로 DB가 애플리케이션에서 발생시키는 모든 읽기/쓰기 요청을 처리할 수 있다.
NoSQL의 단점은
강점인 유연성 때문에 데이터 구조 결정을 하지 못하고 미루게 될 수 있다.
데이터 중복은 여러 컬렉션과 문서가 여러 개의 레코드가 변경된 경우 업데이트를 해야한다.
데이터가 여러 컬렉션에 중복되어 있기에 수정해야 하는 경우 모든 컬렉션에서 수행해야 한다.
그렇다면 어떤 경우에 SQL과 NoSQL을 사용하는 것이 가장 좋을까?
SQL은 관계를 맺고 데이터가 상대적으로 자주 변경되는 애플리케이션일 경우와
스키마가 변경될 여지가 없고 명확한 스키마가 사용자와 데이터에게 중요한 경우 사용하면 좋을 것이다.
NoSQL은 정확한 데이터 구조를 알 수 없거나 변경/확장될 수 있는 경우와
읽기 처리를 자주 하지만 데이터를 자주 변경하지 않는 경우, DB를 수평적으로 확장해야 하는 경우 즉, 막대한 양의 데이터를 다루어야 하는 경우이다.
물론 SQL의 단점과 NoSQL의 단점들을 생기게 하지 않기 위해서 DB가 설계가 가능한 만큼 사용할 시에 많은 계획을 세워 사용한다면 보다 효율적으로 사용할 수 있을 것이다.
'TIL' 카테고리의 다른 글
6/23[TIL] Server의 역할은? (0) | 2021.06.23 |
---|---|
6/17[TIL] 왜 Database를 사용해야 할까? (0) | 2021.06.17 |
6/9[TIL] ORM 사용의 장점과 단점은? (0) | 2021.06.09 |
6/7[TIL] SQL DB 설계에 있어 중요하게 생각하는 점은 무엇이 있을까? (0) | 2021.06.07 |
6/3[TIL] Database Indexing이란 무엇이며 왜 하는가요? (0) | 2021.06.03 |