NoSQL

내위키

말 그대로 No SQL, 즉 'SQL을 안 쓴다'는 뜻으로 해석할 수 있다. SQL을 활용할 수도 있다는 뜻으로 'Not Only SQL'을 뜻한다고 주장하기도 하지만, 사실 NoSQL 데이터베이스들이 SQL 기반의 관계형 데이터베이스와는 구조나 사용 방법이 상당히 동떨어져 있다 보니, 이런 데이터베이스를 쓰다 보면 SQL을 뭐하러 쓰지? 싶은 생각이 든다.

1 등장 배경[편집]

빅데이터 시대가 되면서 특히 NoSQL이 주목 받고 있다. 빅데이터는 데이터의 양도 엄청나지만 데이터의 형태가 정형화되어 있지 않고 워낙에 변화무쌍한 것들이 많아서 데이터 구조의 일관성을 중시하는 관계형 데이터베이스에서는 까다로운 부분이 많고 굉장히 많은 가공을 해야 한다.

게다가 이제는 글로벌 서비스의 시대다. 예전에도 인터넷 망을 통해서 전 세계 어느 웹사이트에 접속할 수 있었지만 대체로 인터넷 서비스에는 국경이 있었고 대부분의 트래픽은 인터넷 서비스를 제공하는 국가 안에서 발생했다. 글로벌 인터넷 서비스라고 해도 나라별로 따로따로 서비스를 제공했다 야후를 생각해보라. 미국 야후와 한국 야후, 일본 야후는 각각 서버를 따로 구축하고 각각 그 나라에 전용 서비스를 제공했다. 물론 데이터베이스도 각 나라의 서비스별로 따로 따로 구축해서 사용했다.

하지만 지금은 페이스북은 어떤가? 물론 접속하는지 여기 다니면 표시되는 언어나 광고는 다를 수 있다. 그러나 이것은 똑같은데 페이스북 서비스가 사용자의 접속 지역을 파악해서 그에 맞는 인터페이스나 광고를 보여줄 뿐이지 서비스 자체는 글로벌 공통이다. 내가 한국에서 페북에 포스팅을 하면 한국은 물론 아시아 여러 나라에서, 미국에서, 유럽에서, 아프리카에서 댓글이 달린다. 이제는 하나의 인터넷 서비스에 엄청난 트래픽이 쏟아진다. 만약 서비스를 제공하는 서버와 데이터베이스 서버가 페북 본사가 있는 미국에만 있다면 어떤 일이 일어날까? 아마도 글 하나 올리려면 최소 몇 초에서 몇 십초 이상 걸릴 것이고 사진이나 동영상을 올리려면? 더 이상의 자세한 설명은 생략한다. 그나마 인터넷 천국인 우리나라나 이런 정도지 우리나라보다 인터넷 사정이 나쁜 수많은 다른 나라는 거의 서비스 이용이 불가능할 것이다.

따라서 페이스북이나 구글 같은 인터넷 기업들은 세계 각지에 서버와 데이터베이스를 분산시켜서 서비스를 제공하고 있다. 이는 과거에 국가별로 따로 서버와 데이터베이스를 구축하고 국가별로 서비스를 제공 했던 것과는 다른 개념이다. 예를 들어 미국에서 저 멀리 떨어진 아프리카의 어느 나라에서 누군가가 페이스북에 글을 올렸다면 일단 그곳에서 제일 가까운 페이스북 서버의 데이터베이스에 그 글이 저장되고, 그 다음 세계 각지에 있는 서버들이 서로 변경된 내용을 주고받음으로써 데이터베이스를 일치시킨다.

이러한 시대의 관계형 데이터베이스의 한계는 점점 명확하게 드러나고 있다. 관계형 데이터베이스는 중앙집중식 시스템을 기본 전제 조건으로 한다. 즉 하나의 고성능 서버가 하나의 데이터베이스를 관장하는 것이다. 한 가지 단위의 정보는 하나의 테이블 안에 있어야 한다. 물론 하나의 서버로는 감당이 안 되다 보니 클러스터링이나 샤딩 같은 분산처리 기법들이 사용되고는 있지만 구현하기도 어려울 뿐더러 이 역시 글로벌로 콸콸콸 쏟아져들어 오는 빅데이터를 감당하기에는 역부족이다. 더 나아가 지금처럼 데이터베이스가 글로벌 여러 지역으로 분산되어 있는 상황에서는 샤딩으로는 답이 안 나온다.

2 NoSQL의 특징[편집]

NoSQL의 전략은 관계형 데이터베이스에서는 철칙처럼 되어 있는 무결성이나 일관성을 조금 양보하는 대신 분산 처리에 최적화된 데이터베이스를 구현하자는 것이다. 기존의 관계형 데이터베이스는 무결성이 보장되어야 한다. 즉 데이터에는 어떤 결함도 없어야 한다. 예를 들어 사용자를 아이디로 식별해야 하는데 사용자 정보 테이블에 같은 아이디를 가진 레코드가 두 개 있으면 안 된다. 데이터베이스 저장소가 여러 곳에 복제되어 있더라도 데이터베이스의 변화가 생길 경우 모든 복제본에 최대한 실시간으로 그 내용이 반영되어야 한다. 그래야 무결성을 보장할 수 있기 때문이다. 또한 스키마에 맞지 않는 데이터는 받지 않는다. 기존 스키마 구조와 맞지 않는 데이터가 있으면 스키마를 수정 또는 확장하든지 데이터를 스키마에 맞게 수정하든지 둘 중 하나다.

반면 NoSQL은 일단 쏟아져 들어오는 데이터는 각자 알아서 받은 다음에 그 내용들을 다른 데이터베이스에 반영하자는 것이다. 일시적으로는 무결성에 문제가 좀 생기더라도 일단 분산 처리 능력을 최대화 하는 쪽에 초점을 맞추고 있는 것이다.

또한 NoSQL은 일관성을 크게 강제하지 않기 때문에 들어오는 대로 일단 막 집어넣고 보자는 전략으로 나갈 수 있다. 애초에 스키마라는 개념을 사용하지 않으며, 따라서 데이터의 구조는 들어오는 데이터에 따라 유연하게 변할 수도 있다. 관계형 데이터베이스는 같은 테이블에 있는 레코드는 항상 같은 필드를 가지고 있지만 (값이 없으면 빈 값이나 NULL 값이라도 들어가 있어야 한다) NoSQL은 같은 컬렉션에 있어도 레코드마다 거느리고 있는 속성은 제각각일 수 있다.

데이터의 일관성은 관계형 데이터베이스가 가진 데이터의 무결성과 같은 장점을 보장하지만, 어떤 때에는 데이터의 처리를 까다롭게 만들고 경직되게 만드는 원인이기도 하다. 주소를 예로 들어 보자. 우리나라의 과거 형태 주소, 즉 지번 기반 주소를 외국의 도로명 기준 주소와 비교하면 다음과 같다.

  • 지번 주소 : 시/도, 구, 동, 번지, 세부주소
  • 외국의 도로명 주소 : 주, 시, 도로명, 건물번호, 세부주소

이게 다가 아닐 것이다. 어떤 나라는 또 다른 요소로 구성된 주소를 쓸 수도 있다. 만약 국제적인 쇼핑몰이라면 어떤 식으로 된 주소든 다 받아줘야 하는데, 나라마다 주소 체계가 제각각일 때 이를 받아주려면 테이블에 이들 모든 요소가 다 속성으로 정의되어 있는 테이블을 짜고, 각 튜플마다 필요 없는 속성은 비우는 식으로 처리해야 한다. 위의 주소 예라면,

시/도 도로명 번지/건물번호 세부주소
지번 주소 서울시 영등포구 여의도동 1-1 내위키아파트 101호
도로명 주소 Victoria Melbourne Bourke Street 1 1F

국제적으로 주소를 저장하려면 나라 이름도 저장해야 할 텐데? 넘어갑시다.

그런데 한국은 아파트를 무지 좋아하는데, 아파트 이름을 그냥 세부주소에 다 퉁쳐서 저장하는 것은 나중에 검색이나 분류를 할 때 좋지 않다. 그래서 아파트는 따로 분리하는 게 좋을 것 같다. 이렇게 각국의 특성에 맞춰서 주소 스키마를 짜려면 밑도 끝도 없다. 나름대로 최대한 고려해서 크고 아름다운 테이블을 만들었는데 나중에 가서 또 다른 나라의 가입자를 받아야 하고 주소 체계가 다르다는 사실을 알게 되면 대략 멘붕 상태에 빠지게 된다.

반면 NoSQL은 미리 스키마를 짜놓고 딱 그에 맞게 데이터를 넣는 게 아니라, 데이터를 넣다가 분명 이 범주에 들어가야 할 데이터인데 구성 요소가 다르다면 그냥 그에 맞는 새 속성(필드)을 정의해서 새로 밀어넣을 수 있다. 그렇다고 기존 데이터에 새로운 필드가 추가되지도 않는다. 즉 데이터 구조의 일관성을 강제하지 않는다.

가장 큰 문제라면 SQL처럼 뭔가 일관된 인터페이스가 없다 보니, 데이터베이스 제품별로 데이터를 넣고 빼고 가져오는 방법이 제각각이라는 것. 물론 SQL 기반 데이터베이스들도 자체 기능을 사용하기 위해서 표준에서 벗어난 구문들이 종종 추가되지만 그래도 SQL이라는 뼈대 위에 추가되는 형태인데 반해, NoSQL은 정말 제각각이다. 게다가 일관된 스키마를 강제하지도 않다 보니, 어떤 제품을 쓰다가 다른 제품으로 전환해야 할 때에는 특히나 마이그레이션 과정이 관계형 데이터베이스와는 비교도 할 수 없이 돌아버릴 수 있다. 따라서 애초에 제품을 잘 선택하는 게 정말로 중요하다. 게다가 관계형 데이터베이스야 어느 정도는 선택이 정해져 있는데 반해[1], NoSQL은 아직까지는 군웅할거 체제라서 제품 선택이 쉬운 문제가 아니다.

관계형 데이터베이스에 익숙해 있던 사람들이 가장 돌아버리는 것은 무결성 문제로, 이를테면 NoSQL은 외래 키 개념이 없다. 예를 들어 관계형 데이터베이스는 테이블 b를 정의할 때 특정 속성이 테이블 a의 키값이 되도록 정의할 수 있으며, 만약 이 속성에 a의 키값이 아닌 다른 값이 들어 있는 데이터를 테이블 b에 집어넣으려고 하면 거부한다. NoSQL은 이런 거 없다. 그냥 다 받아준다. 또한 관계형 데이터베이스는 테이블 b에서 키값으로 쓰이고 있는 테이블 a의 어떤 튜플을 삭제하려고 하면 이 역시 거부한다. 먼저 테이블 b에서 해당 튜플을 지워야 한다. NoSQL은 이런 없다. 그렇기 때문에 무결성이 중요한 데이터라면 NoSQL이 오히려 지옥이 될 수 있다.

NoSQL이 기존 관계형 데이터베이스의 한계점을 극복하기 위해서 등장한 것이긴 하지만 그렇다고 모든 문제를 해결해 주는 것도 아니고, 또한 반대로 NoSQL보다 관계형 데이터베이스가 더 나을 때도 많다. 관계형 데이터베이스는 데이터베이스 분산이 어렵고 구조가 경직되어 있지만 그게 큰 문제가 아니라면 속도와 효율성이라는 면에서 NoSQL보다 우위를 보이는 게 보통이다. 여전히 많은 서비스들은 관계형 데이터베이스를 기반으로 하고 있다. NoSQL이 가진 문제점을 모두 해결해서 제대로 쓰고 있는 기업은 구글 뿐이라는 말이 있을 정도다.[2][3] 기존 데이터베이스를 버리고 NoSQL로 갈아타는 게 능사가 아니라 과연 어느 쪽이 필요한 데이터를 표현하고 활용하는데 더욱 효율적인가를 판단해야 한다.

NoSQL은 대체로 텍스트 검색이 안 된다. 즉 SQL에서 LIKE 구문을 통해서 텍스트 안에 어디에 있든 내용을 검색하는 기능이 NoSQL에서는 처음 혹은 끝과 일치하는 텍스트만 찾을 수 있는 정도의 기능만 제공한다. 텍스트 검색 기능을 쓰고 싶다면 ElasticSearch 혹은 Algolia 같은 외부 검색 엔진을 쓰던가 해야 한다.

3 종류[편집]

구현체마다 차이들이 있지만 크게 네 가지 종류로 나눈다.

  • 키-값 기반 : HBase
  • 문서 기반 : 관계형 데이터베이스의 레코드에 해당하는 것을 여기서는 '문서'(document)라고 부르고, 이 문서의 모음을 컬렉션(collection)이라고 한다. NoSQL답게 같은 컬렉션 안에 있는 문서라고 해도 일관된 스키마 같은 건 없으며, 문서 안에 문서나 컬렉션이 들어갈 수도 있다. 다만 문서를 식별할 수 있도록 유일한 키값은 존재한다. 여기에 해당하는 데이터베이스로는 몽고DB, 카우치베이스, 구글 클라우드 파이어스토어가 있다.
  • 컬럼 기반 : 구글 BigTable
  • 그래프 기반

4 각주[편집]

  1. 금융권처럼 데이터베이스가 안 죽는 게 중요하다면 거의 오라클이고, 윈도우 서버를 쓴다면 MS의 SQL 서버가 있을 것이다. 무료 쪽은 MySQL 또는 MariaDB, 혹은 PostgreSQL 정도가 거의 대부분의 선택이다.
  2. http://eincs.com/2012/06/nosql-is-not-useful/
  3. 사실 NoSQL의 개념을 처음으로 정립한 곳이 구글이기도 하다. 상당수 NoSQL 솔루션들이 구글빅테이블 관련 논문을 기초로 하고 있다.