개요

  • 이 문서는 [[Designing-Data-Intensive-Applications]]책의 2장을 공부하며 메모한 것입니다.
  • 이 문서는 메모일 뿐이니 자세한 내용은 교재를 참고해야 합니다.

복잡한 애플리케이션에서는 여러 API를 기반으로 만든 API 처럼 중간 단계를 더 둘 수 있지만 기본 개념은 여전히 동일하다. 각 계층은 명확한 데이터 모델을 제공해 하위 계층의 복잡성을 숨긴다. 이 추상화는 다른 그룹의 사람들이 효율적으로 함께 일할 수 있게끔 한다.

이번 장에서는 다양한 범용 데이터 모델을 살펴본다.

  • 관계형 모델(relational model)
  • 문서 모델(document model)
  • 그래프 기반 데이터 모델(graph-based data model)

세 모델 모두 현재 널리 사용되고 있다.

  • 한 모델을 다른 모델로 흉내내는 것도 가능(RDB로 그래프 데이터 모델을 흉내낸다거나…)은 하지만 결과는 썩 좋지 않을 것이다.
  • 각기 목적에 맞는 다양한 시스템을 보유해야 한다.

관계형 모델과 문서 모델

  • 관계형 데이터베이스의 근원은 1960년대 메인프레임에서 수행된 비즈니스 데이터 처리.
    • 트랜잭션 처리
    • 일괄 처리

당시 다른 데이터베이스를 사용하는 애플리케이션 개발자는 데이터베이스의 내부 데이터 표현에 대해 많이 고민해야 했지만 관계형 모델의 목표는 정리된 인터페이스 뒤로 구현 세부 사항을 숨기는 것이다.

  • NoSQL
    • 어원: 비관계형 데이터베이스 모임용 트위터 해시태그. #NoSQL
      • 현재: Not Only SQL
    • Why NoSQL ?
      • RDB보다 더 뛰어난 확장성. (대규모 데이터셋이나 매우 높은 쓰기 처리량 달성에 대해)
      • 오픈소스 선호
      • 관계형 모델에서 지원하지 않는 특성화된 질의 동작(specialized query operation)
      • 관계형 스키마의 제한에 대한 불만
      • 더 동적이고 표현력이 풍부한 데이터 모델에 대한 욕구
    • 두 가지 주요 갈래가 있음
      • 문서 DB : 문서와 문서 간 관계가 거의 없는 경우를 대상으로 한다.
      • 그래프 DB : 모든 자료가 잠재적으로 관련 있는 경우를 대상으로 한다.

객체 관계형 불일치

OOP 언어로 개발한 애플리케이션과 SQL 데이터 모델.

  • 임피던스 불일치(impedance mismatch) : OOP 코드와 DB 모델 객체(table, row, column) 사이에 어색한(awkward) 전환 계층이 필요.
    • 임피던스 불일치는 전자공학에서 빌려온 단어.
  • Hibernate 같은 객체 관계형 매핑(ORM) 프레임워크는 전환 계층의 보일러 플레이트 코드 양을 줄여준다.
    • 그러나 ORM을 쓴다 해도 OOP 모델과 DB 모델 사이의 차이를 완벽히 숨길 순 없음.
  • JSON 표현은 multi-table 스키마보다 더 나은 지역성(locality)을 갖는다.
    • JSON 모델이 애플리케이션 코드와 DB 계층 간의 임피던스 불일치를 줄인다고 생각하는 사람도 있음.
    • JSON 표현에서는 모든 관련 정보가 한 곳에 있어 쿼리 하나로 충분.
    • JSON의 문제점도 있는데, 그건 다른 챕터에서…

Many-to-One and Many-to-Many Relationships

중복된 데이터를 정규화하려면 many-to-one 관계가 필요.

  • RDB에서는 join이 쉬워서 일반적으로 쓰고 있음.
  • 다대일 관계는 문서 모델에는 적합하지 않음.
    • 문서 모델 데이터베이스에서는 join 지원이 약한 편이다.

문서 데이터베이스는 역사를 반복하고 있나?

문서 DB와 NoSQL은 DB에서 다대다 관계를 표현하는 좋은 방법이 무엇인지에 대한 논쟁을 다시 열었다.

  • 1970년대 IBM의 정보 관리 시스템(Information Management System, IMS)
    • IMS는 계층 모델(hierarchical model)을 사용.
      • 계층 모델은 JSON과 흡사했다.
      • 일대다에서는 잘 작동했지만 다대다 관계 표현이 어려웠음.
      • join도 지원하지 않음.

계층 모델의 한계 극복을 위해 제안된 해결책들

  • 관계형 모델(세상을 지배하게 됨)
  • 네트워크 모델(지금은 거의 잊혀짐)

네트워크 모델

네트워크 모델은 계층 모델을 일반화한다.

  • 네트워크 모델에서 레코드 간 연결은 외래 키보다는 프로그래밍 언어의 포인터와 더 비슷하다.
  • 레코드에 접근하는 유일한 방법은 root record에서부터 경로를 따라 내려가는 것이다.
  • 만약 레코드가 다중 부모를 갖는다면 다양한 관계를 모두 추적해야 한다는 문제가 있음.
  • 원하는 데이터에 대한 경로가 없다면 곤란해진다.
  • 접근 경로를 수작업으로 지정해주는 노력이 필요.

관계형 모델

  • 관계(테이블)는 단순히 튜플(로우)의 컬렉션이 전부.
  • 필요한 테이블을 읽으면 된다.
  • query optimizer가 있어 접근 경로를 자동으로 만든다.
  • 즉, 관게형 모델은 애플리케이션에 새로운 기능을 추가하는 작업이 쉽다.

문서 DB와의 비교

  • 문서 DB는 계층 모델과 비슷한 점이 있지만,
  • 다대일/다대다 관계 표현시 관계형 DB와 근본적으로 다르지 않다.
    • 관련 항목은 고유한 식별자로 참조하기 때문.

관계형 DB와 오늘날의 문서 DB

  • 문서 데이터 모델을 선호하는 이유
    • 스키마 유연성
    • 지역성에 기인한 더 나은 성능
    • 애플리케이션의 데이터가 문서와 비슷한 구조인 경우
      • 관계형 기법은 다루기 힘든 스키마, 불필요한 코드를 많이 발생시킨다.
  • 관계형 모델을 선호하는 이유
    • join
    • 다대다/다대일 관계를 더 잘 지원

데이터를 위한 질의 언어

선언형 언어

선언형 언어(SQL 같은)의 장점들

  • DB 엔진의 상세 구현이 숨겨져 있어 질의를 변경하지 않고도 DB 시스템의 성능을 향상시킬 수 있다.
  • SQL은 순서를 보장하지 않으므로 순서를 바꾸어도 상관없다.
  • SQL이 기능적으로 더 제한적이라는 사실은 DB가 자동으로 최적화할 수 있는 여지를 더 많이 준다는 의미.
  • 선언형 언어는 병렬 실행에 적합하다.
    • 오늘날의 CPU는 클록 속도를 높여 빨라지기보다, 코어를 더 추가해 빨라지는 방식을 선택.
    • 명령형 코드는 명령어를 순서대로 수행하도록 지정되기 때문에 병렬 처리가 어렵다.
    • 선언형 언어는 보고 싶은 결과의 패턴만 지정하기 때문에 병렬 실행으로 더 빨라질 가능성이 크다.

MapReduce Querying

  • 맵리듀스는 선언형 언어와, 완전한 명령형 질의 API의 중간 정도에 있음.
  • 맵리듀스는 함수형 프로그래밍 언어에 있는 mapreduce 함수를 기반으로 한다.

그래프형 데이터 모델

관계형 모델은 다대다 관계를 다루지만, 데이터 간 연결이 더 복잡해지면 그래프로 데이터를 모델링하는 쪽이 더 자연스러울 수 있다.

그래프의 구성 요소

  • 정점(vertex)
  • 간선(edge)

그래프 모델링의 예

  • 소셜 그래프
    • 정점: 사람
    • 간선: 사람들이 서로 알고 있음
    • 페이스북
      • 간선: 어떤 사람들이 서로 친구인가?
      • 간선: 어떤 사람이 어떤 장소에서 체크인했는가?
      • 간선: 어떤 사람이 어떤 포스트에 좋아요를 눌렀는가?
      • 간선: 어떤 사람이 어떤 포스트에 코멘트를 작성했는가?
  • 웹 그래프
    • 정점: 웹 페이지
    • 간선: 다른 페이지에 대한 HTML 링크
    • page rank로 검색 결과 순위 결정
  • 도로나 철도 네트워크
    • 정점: 교차로
    • 간선: 도로/철로 선 등
    • 자동차 네비게이션 등에서 최단 경로 검색

속성 그래프

속성 그래프의 정점

  • 고유한 식별자
  • 유출(outgoing) 간선 집합
  • 유입(incoming) 간선 집합
  • 속성 컬렉션(키-값 쌍)

속성 그래프의 간선

  • 고유한 식별자
  • 꼬리 정점: 간선이 시작하는 정점
  • 머리 정점: 간선이 끝나는 정점
  • 두 정점 간 관계 유형을 설명하는 레이블
  • 속성 컬렉션(키-값 쌍)

이대로 RDB에 저장하면, 속성 컬렉션은 json 타입을 쓰면 된다.

CREATE TABLE vertices (
    vertex_id integer PRIMARY KEY,
    properties json
);

CREATE TABLE edges (
    edge_id integer PRIMARY KEY,
    tail_vertex integer REFERENCES vertices (vertex_id),
    head_vertex integer REFERENCES vertices (vertex_id),
    label text,
    properties json
);

CREATE INDEX edges_tails ON edges (tail_vertex);
CREATE INDEX edges_heads ON edges (head_vertex);

속성 그래프의 특징은 다음과 같다.

  • 정점은 다른 정점과 간선으로 연결된다.
  • 특정 유형과의 관계를 제한하는 스키마가 없다.
  • 정점이 주어지면, 유입/유출 간선을 효율적으로 찾을 수 있다.
  • 정점을 따라 그래프를 순회할 수 있다.
  • 다른 유형의 관계에 서로 다른 레이블을 사용하면 단일 그래프에 다른 유형의 정보를 저장하면서도 데이터 모델을 깔끔하게 유지할 수 있다.

Cypher 질의 언어

선언형 질의 언어

생략

SQL의 그래프 질의

그래프 데이터를 관계형 구조로 넣어도 SQL을 사용해 질의할 수 있을까?

  • SQL:1999 이후, 가변 순회 경로에 대한 질의 개념은 재귀 공통 테이블 식(recursive common table expression)(WITH RECURSIVE 문)을 사용해 표현할 수 있다.
  • Cypher로는 쉬운데 SQL로는 많이 어려움. 게다가 길다.

트리플 저장소(Triple-Stores)와 스파클(SPARQL)

속성 그래프 모델과 비슷하다.

  • 비슷한 개념을 다른 용어로 표현한 느낌.
  • 트리플 저장소는 모든 정보를 주어(subject), 서술어(predicate), 목적어(object)로 저장한다.
    • 주어는 그래프의 정점과 같다.
    • 목적어는 두 가지 중 하나다.
      • 그래프의 다른 정점
    • 예 : John, likes, bananas
    • 예 : John, age, 30
    • 예 : John, marriedTo, Loui

시맨틱 웹(semantic web)

  • 웹 사이트는 사람이 읽을 수 있도록 정보를 보여주고 있다.
  • 컴퓨터도 판독 가능하도록 정보를 보여주면 어떨까?

생략

스파클(SPARQL) 질의 언어

생략

데이터로그(Datalog)

생략

Links

  • [[Designing-Data-Intensive-Applications]]