3 minute read

도큐먼트 데이터베이스는 역사를 반복하고 있는가?

1960년대와 70년대의 이러한 문제는 오늘날 개발자들이 문서 데이터베이스에서 직면하고 있는 문제와 매우 유사하다.

1970년대에 비즈니스 데이터 처리를 위한 데이터베이스는 아폴로 우주 프로그램의 재고 관리용으로 개발되어 1968년에 처음 상업적으로 출시된 IBM의 정보 관리 시스템(IMS)이었다. IMS의 설계는 계층적 모델이라는 매우 단순한 데이터 모델을 사용했다. 이 모델은 모든 데이터를 JSON 구조와 매우 유사하게 레코드 내에 중첩된 레코드 트리로 표현했다.

문서 데이터베이스와 마찬가지로 IMS는 일대다 관계에서는 잘 작동했지만, 다대다 관계와 조인을 지원하지 않았다. 개발자는 데이터를 중복(비정규화)할 것인지 아니면 한 레코드에서 다른 레코드로의 참조를 수동으로 해결할 것인지 결정해야 했다.

계층적 모델의 한계를 해결하기 위해 다양한 솔루션이 제안되었다. 여러가지 대안 중 두 가지 솔루션이 남았다.

  • 관계형 모델: SQL이 되어 전 세계를 장악
  • 네트워크 모델: 처음에는 많은 추종자를 가졌지만 결국에는 사장됨

두 모델이 해결하고자 했던 문제는 오늘날에도 여전히 관련성이 높기 때문에 오늘날의 관점에서 이 논쟁을 간략히 다시 살펴볼 가치가 있다.

도큐먼트 모델의 스키마 유연성

대부분의 도큐먼트 데이터베이스와 관계형 데이터베이스는 JSON 포맷에 데이터에 스키마를 적용하지 않는다.

스키마가 없다는 것은 도큐먼트에 임의의 키와 값을 추가할 수 있으며, 클라이언트는 도큐먼트를 읽을 때 도큐먼트에 어떤 필드가 포함될 수 있는지 보장할 수 없다는 것을 의미한다.

도큐먼트 데이터베이스를 스키마리스(스키마 없는, schema-less) 데이터베이스라고 부르기도 하지만, 데이터를 읽는 코드는 일반적으로 어떤 종류의 구조, 즉 암시적 스키마가 있지만 데이터베이스에 의해 강제되지 않는다고 가정하기 때문에 이는 오해의 소지가 있습니다.

스키마리스(schema-less) 데이터베이스의 정확한 용어는 스키마-온-리드(schema-on-read)이다.

  • schema-on-read: 데이터의 구조가 암묵적이며 데이터를 읽을 때만 해석됨

  • schema-on-write: 스키마가 명시적이며 데이터를 기록시에 스키마를 일치시킴(관계형 데이터베이스의 스키마 방식)

스키마 온 리드(schema-on-read)는 프로그래밍 언어에서 동적(런타임) 타입 검사와 유사한데, 스키마 온 쓰기는 정적(컴파일 타임) 타입 검사가 그렇다.

정적 및 동적 타입 검사를 지지자들이 상대적인 장점에 대해 큰 논쟁을 벌이는 것처럼, 데이터베이스의 스키마를 적용하는 것은 논쟁의 여지가 있는 주제이며 일반적으로 옳고 그름이 정해져 있지 않다.

특히 애플리케이션이 데이터 형식을 변경하려는 상황에서 두 접근 방식 간의 차이가 두드러진다. 예를 들어, 각 사용자의 성명을 하나의 필드에 저장하는 대신 이름과 성을 별도로 저장하고 싶다고 가정해보자. 도큐먼트 데이터베이스는 새 필드를 사용하여 새 문서를 작성하기 시작하고 애플리케이션에 이전 문서를 읽을 때를 처리하는 코드가 있습니다. 예를 들어

if (user && user.name && !user.first_name) {
  // 2013년 12월 8일이전 까지 성(first_name)이 없었음
  user.first_name = user.name.split(" ")[0];
}

반면에 “정적 타입”의 데이터베이스 스키마는 다음과 같은 라인을 따라 마이그레이션을 수행한다.

ALTER TABLE users ADD COLUMN first_name text;
UPDATE users SET first_name = split_part(name, ' ', 1); -- PostgreSQL
UPDATE users SET first_name = substring_index(name, ' ', 1); -- MySQL

스키마 변경은 느리고 다운타임이 존재한다. 대부분의 관계형 데이터베이스 시스템은 ALTER TABLE 수행시, 데이터베이스는 모든 행을 다시 작성하므로 큰 테이블에서 UPDATE 문을 실행하면 모든 데이터베이스에서 속도가 느려진다는 단점이있다.

이것이 허용되지 않는 경우, 애플리케이션은 도큐먼트 데이터베이스처럼, first_name을 기본값인 NULL로 설정하고 읽기 시점에 채울 수 있다.

스키마 온 리드(schema-on-read) 접근 방식은 컬렉션의 항목이 어떤 이유로 인해 모두 동일한 구조를 갖지 않는 경우에 유리하다.

그 이유는:

  • 객체는 다양한 유형이 있으며 각 유형의 객체를 별도의 테이블에 넣는 것은 실용적이지 않다.
  • 데이터의 구조는 사용자가 제어할 수 없고 언제든지 변경될 수 있는 외부 시스템에 의해 결정된다.

이러한 상황에서 스키마가 도움이 되기보다는 오히려 해가 될 수 있으며, 스키마 없는 문서가 훨씬 더 자연스러운 데이터 모델이 될 수 있다. 그러나 모든 레코드가 동일한 구조를 가질 것으로 예상되는 경우 스키마는 해당 구조를 문서화하고 적용하는 데 유용한 메커니즘이다.

쿼리를 위한 데이터 지역성

문서는 일반적으로 하나의 연속된 문자열로 저장되며, JSON, XML 또는 그 바이너리 변형(예: MongoDB의 BSON)으로 인코딩된다.

웹 페이지 렌더링과 같이, 애플리케이션이 전체 문서에 자주 접근해야 하는 경우이 저장 위치가 중요하다. 만약, 데이터가 여러 테이블에 분산되어 있는 경우, 모든 데이터를 검색하려면 여러 인덱스 조회가 필요하므로 디스크 검색 시간이 많이 소요된다

지역성은 문서의 많은 부분이 동시에 필요한 경우에 유리하다.데이터베이스는 일반적으로 문서의 일부만 액세스하더라도 전체 문서를 로드해야 하므로 대용량 문서에서는 낭비가 될 수 있습니다.

문서를 업데이트할 때는 일반적으로 전체 문서를 다시 작성해야 하는데, 인코딩된 문서 크기를 변경하지 않는 수정 사항만 제자리에 쉽게 배치할 수 있다

지역성을 위해 관련 데이터를 함께 그룹화하는 아이디어는 문서 모델에만 국한되지 않는다. 예를 들어,

  • Google의 Spanner 데이터베이스는 스키마에서 테이블의 행이 상위 테이블 내에 중첩 선언을 허용함으로써 관계형 데이터 모델에서 동일한 로캘리티 속성을 제공한다.

  • Oracle은 다중 테이블 인덱스 클러스터 테이블이라는 기능을 사용하여 동일한 기능을 허용합니다.

  • 빅테이블 데이터 모델의 컬럼-패밀리 개념(카산드라 및 HBase에서 사용됨)은 지역성 관리라는 유사한 목적을 가지고 있다.

도큐먼트 데이터베이스와 관계형 데이터베이스의 융합

시간이 지남에 따라 관계형 데이터베이스와 문서 데이터베이스가 점점 더 유사해지고 있다. 데이터베이스가 문서형 데이터를 처리하고 관계형 쿼리도 수행할 수 있다면 애플리케이션은 필요에 가장 적합한 기능의 조합을 사용할 수 있다. 관계형 모델과 문서 모델의 융합은 데이터베이스가 앞으로 나아가야 할 좋은 방향이다.

예를 들어,

  • MySQL을 제외 하고, 대부분의 관계형 데이터베이스 시스템은 2000년대 중반부터 XML을 지원해왔다.
  • 도큐먼트 데이터베이스는 RethinkDB는 쿼리 언어에서 관계형과 유사한 조인을 지원하며, 일부 몽고DB 드라이버는 데이터베이스 참조를 자동으로 해결한다.

데이터 중심 애플리케이션 설계, 마틴 클레프만, 위키북스, 2018