웹 앱 개발에는 적절한 데이터베이스 선택이 필수적이다.
보통 Spring은 MySQL, Node.js는 MongoDB를 사용해야한다고 생각하지만, 데이터베이스는 단순히 프레임워크에 따라 결정하는 것이 아니라 프로젝트에 따라 적절하게 선택해야한다.
SQL은 '구조화 된 쿼리 언어 (Structured Query Language)' 의 약자이다. 따라서 데이터베이스 자체를 의미하는 것이 아니라, 특정 유형의 데이터베이스와 상호 작용하는데 사용하는 쿼리 언어이다.
SQL을 사용하면 관계형 데이터베이스 관리 시스템(RDBMS)에서 데이터를 저장, 수정, 삭제 및 검색할 수 있다.
각 테이블에는 명확하게 정의된 구조(structure)가 있다. 구조는 테이블에 들어갈 데이터를 정의하는 필드(field) 집합을 의미하며, 스키마(schema)라고도 한다.
데이터는 정의된 구조에 따라 테이블(table)에 레코드(record)로 저장된다.
따라서, 관계형 데이터베이스에서 스키마를 준수하지 않는 레코드는 추가할 수 없다. 예를 들어, 위 테이블에서 '유통기한' 이라는 필드를 넣고 싶다면, 스키마를 수정하기 전까지는 필드를 추가할 수 없다.
데이터베이스에서는 하나의 테이블에 필요한 모든 필드를 넣고 모든 데이터를 저장할 수 있다. 하지만 이러한 경우 데이터들이 중복해서 저장되는 상황이 발생될 수 있다. 관계형 데이터베이스는 데이터들을 여러개의 테이블에 나누어 데이터들의 중복을 피할 수 있다.
사용자가 구입한 상품들을 나타내기 위해서는 위와 같이 여러 테이블을 만들어야 하지만, 각각의 테이블들은 다른 테이블에 저장되지 않은 데이터만 가지고 있다. 즉, 이러한 구조는 하나의 테이블에서 중복없이 하나의 데이터만을 관리하기 때문에, 다른 테이블에서 부정확한 데이터를 다룰 위험이 없다.
NoSQL은 SQL과 반대되는 접근방식을 의미한다.
NoSQL은 SQL에서의 테이블을 컬렉션(collections), 레코드를 문서(documents)라고 한다. 또한, 정해진 스키마가 없어 다른 구조의 데이터를 같은 컬렉션에 추가할 수 있다.
문서는 JSON 데이터와 비슷한 형태를 가지며, 관련 있는 문서들은 동일한 컬렉션에 저장된다. 예를 들어, 관계형 데이터베이스에서의 Users, Products 또한 Orders 컬렉션에 한꺼번에 저장된다.
따라서 NoSQL 데이터베이스는 이미 필요한 모든 데이터를 갖춘 문서가 존재하므로 조인(JOIN)이라는 개념이 존재하지 않는다.
대신 컬렉션을 통해 데이터를 복제하여 각 컬렉션 일부분에 속하는 데이터를 정확하게 산출한다.
이런 방식은 데이터가 중복되기 때문에 특정 데이터를 같이 사용하는 모든 컬렉션에서 똑같은 데이터에 대한 업데이트가 수행되도록 해야 한다.
그럼에도 불구하고, 복잡하고 느린 조인을 사용할 필요가 없다는 장점이 더 크다.
SQL과 NoSQL은 데이터베이스 서버를 확장(Scaling)하는 방식이 다르다.
수직적 확장이란 데이터베이스 서버의 성능을 향상시키는 것이다. 예를 들어, 데이터베이스 서버 컴퓨터의 CPU를 업그레이드 하는 방식이다.
수평적 확장이란 더 많은 서버가 추가되고 데이터베이스가 전체적으로 분산됨을 의미한다. 따라서 하나의 데이터베이스에서 작동하지만 여러 호스트에서 작동한다.
수평적 확장에는 샤딩(Sharding)이라는 개념이 사용되는데, SQL 데이터베이스는 샤딩의 개념이 존재하지만 특정 제한이 있고 구현하기가 어렵다.
반면, NoSQL 데이터베이스는 이를 기본적으로 지원하므로 여러 서버에서 데이터베이스를 쉽게 분리할 수 있다.
따라서, SQL은 수직적 확장, NoSQL은 수직적 확장과 수평적 확장을 지원한다.
그렇다면, SQL과 NoSQL 둘 중에 무엇을 선택해야 할까? 결론은 '정답은 없다' 이다.
둘 다 훌륭한 솔루션이고 어떤 데이터를 다루느냐에 따라 선택을 고려해야 한다.
분명한 것은 데이터베이스는 다른 방식으로 설계될 수 있다는 것이다. 둘 중 어떤 데이터베이스를 사용하더라도 설계적으로 단점들을 완화시킬 수 있다.
[참고]