Skip to content
피스타치오는 맛있어
Instagram

2장. 데이터 모델과 질의 언어

, 아키택처, 프로그래밍, 분산시스템, 시스템디자인3 min read

관계형 모델과 문서 모델

데이터 모델의 대표적인 사례가 관계형 모델입니다. 역사적으로 데이터를 하나의 커다란 트리로 표현하려고 노력했지만, 이 트리 구조는 many-to-many 관계를 표현하기 힘들었습니다. 이 문제를 해결하기 위해 나온 것이 관계형 모델입니다.

NoSQL의 탄생

그러나 사람들은 관계형 모델에 적합하지 않은 애플리케이션이 있다는 것을 발견했습니다. NoSQL(Not only SQL)은 그런 애플리케이션과 연관된 개발자들이 관계형 모델이 싫다며 만든 해쉬테그이지, 특정 기술을 지칭하는 것은 아닙니다.

이 개발자들은 어떤 것이 불만이어서 NoSQL을 탄생시켰을까요?

  • 대규모 데이터셋이나 매우 높은 쓰기 처리를 할 수 있는 확장성이 필요하다.
  • 관계형 모델들은 대부분 유료라서 짜증난다.
  • 관계형 모델에서 지원하지 않는 특수 Query 들을 NoSQL에서 해볼 수 있지 않을까?
  • 관계형 스키마는 데이터 모델이 동적이고 표현력이 풍부해지기에는 너무 제한적이다.

객체 관계형 불일치

객체 지향 프로그래밍 언어로 짜여진 애플리케이션에서의 객체는 데이터 모델(테이블, 로우, 칼럼)과 정확하게 일치하지 않아 그 사이에 전환 계층이 필요합니다. 이 분리를 임피던스 불일치(impedance mismatch)라고 부릅니다.

many-to-one 이나 many-to-many 관계를 표현할 때 이 점이 특히 두드러집니다..

다대일과 다대다 관계

관계모델에서 다대일로 관계를 설정하는 경우를 생각해보겠습니다. 예를 들어, 여러 사람 들은 한 지역 에 거주할 수 있습니다.

사람 테이블

사람거주지 ID
철수1
영희1
영철2

거주지 테이블

id거주지
1서울
2부산

서울이나 부산을 그대로 사람 테이블의 거주지에 때려박지 않고 ID로 따로 관리하는 이유는 데이터 중복 문제를 해결하기 위함입니다. 중복 문제 외에도 다음 이점을 취할 수 있습니다.

  • 거주지가 일관된 스타일과 철자를 가지게 된다.
  • 모호함을 회피할 수 있다(이름이 같은 여러 도시가 있는 경우).
  • 갱신이 편리하다.
  • Localization이 용이하다.
  • 문자열로 데이터가 관리되는 것보다 검색이 용이하다.

이런 문제를 해결하기 위해 중복을 제거하는 것이 스키마 정규화와 관련된 핵심 개념입니다. 글쓴이는 경험적으로, 한 곳에 저장할 수 있는 값이 중복된다면 그 스키마는 정규화되지 않았다고 본다고 합니다.

정규화는 many-to-one 관계에서 많이 나오는데, 이 관계는 사실 문서 모델에는 적합하지 않습니다. 문서 DB가 대부분 Join 에 대한 지원이 약하기 때문입니다. Join 이 필요없는 문서를 설계했다고 하더라도, 애플리케이션에 기능이 추가되면서 데이터는 점차 상호 연결되는 경향이 있는 데다, many-to-many 에서도 Join이 필요한 것은 매한가지입니다.

여기서 말하는 문서 모델은 오늘날의 문서 데이터베이스가 아니라 예전에 쓰이던 걸 말하는 듯 싶습니다. 뒤에서 many-to-one 에 문서모델이 적합하다는 설명이 있기 때문입니다.

관계형 데이터베이스와 오늘날의 문서 데이터베이스

어떤 데이터 모델이 애플리케이션 코드를 더 간단하게 할까에 대한 관점으로 관계형 데이터베이스와 문서 데이터베이스를 선택해볼 수 있습니다. 예를 들어 데이터끼리 상호 연결이 많다면 문서 모델은 곤란하지만 관계형 모델은 무난합니다. 그러나 문서 모델은 스키마를 변경해야 할 때 예전 문서를 읽은 경우를 처리하는 코드만 가지고 있으면 되나, 관계형 데이터베이스 스키마는 마이그레이션을 해주어야 합니다. 특히, MySQL은 ALTER TABLE 수행 시 전체 테이블을 복사하기 때문에 성능이 구립니다.

관계형 데이터베이스와 문서 데이터베이스는 시간이 지남에 따라 점점 더 비슷해지고 있습니다. 관계형과 문서의 혼합 모델은 미래 데이터베이스들이 가야 할 올바른 길입니다.

데이터를 위한 질의 언어

SQL은 선언형 질의 언어입니다. 즉, 목표를 달성하기 위한 방법을 적는 것이 아닌, 결과가 충족해야 하는 조건을 선언합니다. 방법을 찾는 일은 Query Optimizer가 수행합니다.

이로 인해 얻는 몇 가지 장점이 있습니다.

  • 명령형 API보다 간결하고, Query Optimizer가 내부 구현을 몰라도 알아서 성능을 향상시켜 준다.
  • SQL 하나하나는 순서가 바뀌어도 상관없다.
  • 병렬 실행에 적합하다.

웹에서의 선언형 질의

css selector(선언적 질의) 와 DOM API(명령형 질의)를 비교해서 보여주는데, 대충 선언형 Query Language가 더 좋다는 내용입니다.

맵리듀스 질의

MapReduce 는 많은 컴퓨터에서 대량의 데이터를 처리하기 위한 프로그래밍 모델로 구글에 의해 널리 알려졌습니다. Mongo DB의 Aggregation pipeline 을 떠올리면 될 듯 싶습니다.

그래프형 데이터 모델

many-to-one 관계 이거나 레코드 간 관계가 없다면 문서 모델이 적합합니다. 데이터가 서로 어느 정도 관계를 가지고 있다면 관계형 모델도 무난합니다. 그러나 데이터가 서로 긴밀하게 연결되어 many-to-many 가 아주 일반적이라면 그래프형 데이터 모델을 생각해볼 수도 있습니다.

속성 그래프

그래프형 데이터 모델은 그래프로 데이터를 표현합니다.

그래프의 각 정점(노드, vertex)는 다음과 같은 요소로 구성됩니다.

  • 고유한 식별자
  • outgoing 간선 집합
  • incoming 간선 집합
  • 속성 컬렉션(key-value)
1// 예시 1
2id: 1
3type: 사람
4name: 철수
5
6// 예시 2
7id: 2
8type: 도시
9name: 서울

각 간선은 다음과 같은 요소로 구성됩니다.

  • 고유한 식별자
  • 간선이 시작하는 정점(tail vertex)
  • 간선이 끝나는 정점(head vertex)
  • 두 정점 간 관계 유형을 설명하는 Label
  • 속성 컬렉션(key-value)
1// 예시: 철수는 서울에 살고 있다.
2id: 1
3tail_vertex: 1
4head_vertex: 2
5label: 살고 있다

예시에 써놓은 내용을 조금만 바꾸면 관계형 DB로도 표현해볼 수 있습니다.

이런 모델링은 확장성이 뛰어나 많은 유연성을 제공합니다.

사이퍼 질의 언어

그런데 저런 그래피 모델은 어떻게 쿼리를 할까요? Cypher는 그래프형 데이터 모델의 Query Language 입니다.

예를 들어 서울에 살고 있는 사람들을 조회하려면 다음과 같이 쿼리를 작성해볼 수 있습니다.

1MATCH
2 (person) -[:살고_있다]-> (서울:Location { name: '서울' })
3RETURN person.name

위와 같이 : 뒤에는 간선의 종류가 들어가고, 이 간선을 따라다니며 찾기를 수행합니다.

SQL의 그래프 질의

관계형 DB로 그래프 데이터를 표현할 수 있다는 걸 언급했었는데, 그 말은 SQL로 그래프 데이터를 조회할 수 있음을 의미합니다. 하지만 어렵습니다.

원하는 데이터를 찾으려면 간선들을 순회해야 하는데 이는 조인 수를 미리 고정할 수 없도록 만들기 때문입니다.

결론

어쨌든 중요한 건, 애플리케이션의 성격에 따라 적절한 데이터 모델(관계형, 문서형, 그래프형)을 골라야 한다는 사실입니다.

© 2023 by 피스타치오는 맛있어. All rights reserved.