데이터 모델 상세

‘빅데이터 세상으로 떠나는 간결한 안내서 NoSQL’를 읽고 정리하고자함


요점 정리

  • 집합 지향 데이터베이스에서는 집합 내 관계보다는 집합 간 관계를 처리하는 것이 더 어려움
  • 그래프 데이터베이스는 데이터를 노드와 간선의 그래프 구조로 만들며, 복잡한 관계를 가지는 데이터에 최적
  • 무스키마 데이터베이스는 레코드에 필드를 자유롭게 추가할 수 있지만, 보통 데이터 사용자가 기대하는 암묵적인 스키마가 있음
  • 집합 지향 데이터베이스는 주요 집합과 구조가 다른 데이터 제공을 위해 구체화된 뷰를 사용함
  • 구체화된 뷰는 보통 맵-리듀스 계산을 통해 수행

1. 관계

  • 집합은 일반적으로 함께 접근하는 데이터를 한 덩어리로 모아놓기 때문에 유용
  • 하지만, 관련 데이터를 다르게 접근하는 경우가 많은데, 관계는 사용자는 알 수 있지만 데이터베이스는 이 관계를 모르고, 이 관계, 연결을 알면 더 유용한 경우가 많음
  • 그래서 키-값 저장소 까지도 관계를 데이터베이스에 보이도록하는 방법을 제공
    • 문서 저장소는 집합의 내용을 가지고 인덱스를 만들고 조회할 수 있음
    • 카-값 저장소인 리악은 부분검색, 링크 순회를 지원해 메타데이터에 링크 정보를 생성할 수 있음
  • 집합 간 관계에서 중요한 측면은 ‘업데이트를 처리하는 방식’
    • 집합 지향 데이터베이스는 집합을 데이터 접근 단위로 취급하고, 원자성은 당일 집합의 내용안에서만 지원
  • 집합을 한번에 여러개 업데이트하면, 도중 실패한 경우 직접 처리해야함
    • 관계형 데이터베이는 단일 트랙잭션에서 여러 레코드를 수정할 수 있으며, 많은 행을 변경할 떄도 ACID 보장함
  • 집합 지향 데이터베이스에서는 여러 집합에 결쳐 데이터 조작하는 경우에는 처리가 불편함
    • 그래서, 데이터간의 관계가 많을 시에는 NoSQL보다는 RDB가 더 나은 선택일 수 도 있음
    • 물론, RDB도 관계를 처리하려면 JOIN해야하며, 성능 측면에서 곤란한 상황이 발생할 수 도 있음

2. 그래프 데이터베이스

  • 대다수는 NoSQL은 클러서터에서 실행해야 할 필요성이 생겼으며, 연결이 간단하고 레코드 크기가 큰 집합 지향 데이터 모델을 주로 활용
  • 그래프 데이터베이스는 상호 연결이 복잡하고 레코드 크기가 작은 반대의 모델을 가짐

  • 간선으로 연결된 노드가 전부인 데이터 모델를 사용함
    • FlockDB : 단순 노드와 간선 이외에 다른 속성은 지원하지 않음
    • Neo4j : 스키마가 없는 방식으로 노드나 간선의 속성을 자바 객체를 추가할 수 있음
    • Infinite Graph : 내장 타입의 서브클래스로 된 사용자의 자바 객체를 노드와 간선에 저장
  • 그래프 데이터베이스에 노드와 간선으로 그래프를 구성하고 나면, 그래프 구조를 고려해 설계한 쿼리 연산으로 네트워크를 검색할 수 있음
    • RDB도 외래키를 이용해 관계를 만들 수 있지만, 조인은 비용이 많이 들 수 있고, 연결이 많은 데이터 모델에서는 성능이 낮아짐
  • 그래프 데이터베이스에서 관계를 따라가는 연산은 비용이 적고, 관계 사이를 돌아다닌 작업의 대부분은 쿼리시점에서 입력 시점으로 옮겼기 떄문
  • 쿼리 성능이 입력 성능보다 중요한 상황이라면 당연히 이렇게 설계하는 것이 이득
  • 그래프 데이터베이스는 클러스터에서보다는 ‘단일 서버’에서 실행되는 경우가 많음
    • 데이터 일관성을 유지하는데 여러 노드와 간선을 포괄하는 ACID 트랜잭션도 필요
    • 관계형 모델을 사용하지 않는다는 점에서 NoSQL이 주목받는 시기에 함께 관심이 높아짐

3. 스키마 없는 데이터베이스

  • 모든 형태의 NoSQL 데이터베이스는 스키마가 없다는 공통점이 있음
    • 키-값 저장소에는 키에 대응되는 값에 어떤 데이터든 저장 할 수 있음
    • 문서에는 저장하는 문서 구조에 어떤 제약이 없으므로 사실상 똑같은 처리 작업을 할 수 있음
    • 칼럼패밀리는 칼럼 안에 어떤 데이터든 저장할 수 있음
    • 그래프 데이터베이스도 자유롭게 간선을 추가할 수 있고 노드와 간선에 원하는 속성을 추가할 수 있음

장점

  • 스키마에 구속되지 않으면 필요한 것을 쉽게 저장할 수 있음
  • 변경을 처리하는 것도 쉽지만, ‘균일하지 않은 데이터’를 처리하는 것이 쉬어짐
    • 각 레코드가 서로 다른 집합의 필드를 가지는 데이터

문제

  • 데이터에 접근하는 상황에서는 어떤 형태든 암묵적인 스키마에 의존해야함

암묵적 스키마의 문제

  1. 어떤 데이터가 있는지 확인하려면 애플리케이션 코드를 확인해야함
  2. 데이터베이스는 스키마에 대해 아무것도 몰라, 스키마 정보를 활용해 효율적인 데이터를 저장하거나 꺼낼 수 없음
  3. 여러 애플리케이션이 데이터를 비일관적으로 조작하지 않는지 확인하기 위한 ‘유효성 검사’가 필요함
  • 이런 문제로 관계형 데이터베이스가 고정된 스키마를 가졌던 것

  • 무스키마 데이터베이스를 사용하면, 스키마가 애플리케이션 코드로 이동함

    • 여러 팀이 개발하는 많은 애플리케이션이 한 데이터베이스에 접근하는 경우라면 문제가 생김

완화방법

  1. 모든 데이터베이스 상호작용을 단일 애플리케이션에 캡슐화하고 다른 애플리케이션은 웹 서비스로 통합하는것
  2. 각 애플리케이션에서 접근하는 집합 구조 영역에 대해 명확하게 기술하는 것
    • 문서 데이터베이스라면, 다른 섹션이 될 것이고, 칼럼 패밀리라면 다른 칼럼이 될 수 있음
  • 데이터가 균일하지 않는다면 무스키마 데이터베이스를 고려할 좋은 이유

4. 구체화된 뷰

  • 주문에 접근하고 싶으면 주문 관련 데이터를 모두 한 집합에 포함시켜 한번에 저장하거나 읽어오면 편함
  • 근데, 특정 상품이 지난 2주간 얼마나 팔렸는지 알고 싶어한다면..?
  • 데이터베이스의 주문 데이터를 다 읽어야할 수 도 있음 ..

  • 이런 경우에는 관계형 데이터베이스로 데이터 접근하기 쉬움
  • 그 뿐아니라, 관계형 데이터베이스에서는 ‘뷰’를 통해 데이터를 저장되어 있는 것과 다른 형태로 쉽게 볼 수 있음
    • 뷰는 관계형 데이블 같지만, 기본 테이블에 대한 계산으로 정의됌
    • 뷰에 접근할 때 데이터베이스는 뷰에 보일 데이터를 계산해, 캡슐화의 편리한 형태라고 볼 수 있음
  • 뷰를 사용하면 데이터가 유도된 데이터인지, 원본 데이터 인지 클라이언트에게 숨길 수 있음
  • 뷰를 계산하는 비용이 많이 들 수 있기 때문에, 계산 결과를 미리 만들어 디스크에 캐시해 놓은 ‘구체화 뷰(materialized view)’가 고안됌

  • NoSQL에는 뷰는 없지만, 쿼리 결과를 미리 계산해 캐시해 놓을 수 있음 = 구체화된 뷰
  1. 기본 데이터가 바뀔 때 구체화 뷰도 함께 바꾸는 방법
    • 쓰기보다는 읽기가 훨씬 많고, 구체호 뷰가 최신 데이터를 갖도록하고 싶은 경우에 좋음
  2. 업데이트할 때마다 이런 오버헤드를 감수하고 싶지 않다면, 배치 작업으로 구체화 뷰 업데이트
  • 데이터를 읽어 뷰를 계산하고 결과를 테이터베이스에 저장하는 방식으로 데이터베이스 밖에서 구체화뷰를 만들 수 있음
  • 서로 다른 칼럼 패밀리를 이용해 구체화 뷰를 만드는 것은 칼럼 패밀리 데이터베이스에서 흔한 방법

5. 데이터 접근을 위한 모델

  • 데이터 집합 모델을 만들 떄는 ‘이 집합과 관계된 데이터에 어떤 부수효과가 무엇인지 뿐 아니라 데이터를 어떻게 읽을 것인지’도 고려해야함

e.g) 고객의 모든 정보를 키-값 저장소에 저장하는 모델

키-값

  • 키값으로 고객 정보를 받아 처리
  • 고객과 주문의 집합을 분리해, 고객집합에 주문집합에 대한 참조 데이터를 추가

문서

  • 문서 내부를 조회할 수 있으므로 문서 내 속성으로 쿼리할 수 있음

칼럼 패밀리

  • 칼럼순서를 조정해 자주 사용하는 칼럼을 먼저 읽도록 할 수 있음
  • 칼럼 패밀리를 사용해 데이터 모델을 만들때는 쓰기 편의성보다는 ‘쿼리 요건’에 맞춰야함
  • 일반적인 규칙은 쿼리를 쉽게 하고 쓰기 시 데이터를 역정규화하는 것