본문 바로가기
스터디

[데이터 중심 애플리케이션 설계] 2장 데이터 모델과 질의 언어

by 메릴린 2022. 12. 30.
728x90

[데이터 중심 애플리케이션 설계] 를 읽고 정리하는 글

 

데이터 중심 애플리케이션 설계 | 마틴 클레프만 - 교보문고

데이터 중심 애플리케이션 설계 | 데이터는 오늘날 시스템을 설계할 때 마주치는 많은 도전 과제 중에서도 가장 중심에 있다. 확장성, 일관성, 신뢰성, 효율성, 유지보수성과 같은 해결하기 어려

product.kyobobook.co.kr

상황에 따라 영어 원문이 더 이해하기 쉬운 경우 영어 원문을 이용해 정리하였다. (영어 원문 출처)


데이터 모델의 중요성

소프트웨어가 어떻게 작성됐는지 뿐만 아니라 문제를 어떻게 생각해야 하는지에 지대한 영향을 미침

데이터 모델은 그 위에서 소프트웨어가 할 수 있는 일과 할 수 없는 일에 지대한 영향을 주므로 애플리케이션에 적합한 데이터 모델을 선택하는 것은 매우 중요하다.

 

애플리케이션 데이터 모델 구조

  • 계층적
  • 하위계층의 복잡성 숨김
  • 다양한 그룹의 사람들이 효율적으로 작업할 수 있다.

 

데이터 저장과 질의를 위한 다양한 범용 데이터 모델

  1. 관계형 모델 (relational model)
  2. 문서 모델 (document model)
  3. 그래프 기반 모델 (graph-based data model)

 

관계형 모델과 문서 모델

오늘날 가장 잘 알려진 모델: SQL

  • 25-30년 정도 우위 차지
  • 근원: 비즈니스 데이터 처리, 트랜잭션 처리, 일괄 처리
  • 경쟁자: 네트워크 모델, 계층 모델, 객체 데이터베이스, XML 데이터베이스

NoSQL의 등장

  • 최신 대항마
  • 트위터 해시태그에서 기원 → Not Only SQL

NoSQL의 장점

  • 확장성 (쓰기에서)
  • 무료 오픈소스 소프트웨어
  • 관계형 모델에서 지원하지 않는 특수 질의 동작
  • 동적이고 표현력이 풍부한 데이터 모델에 대한 수요 증가

객체 관계형 불일치

애플리케이션 개발 언어: 객체지향 프로그래밍 언어

⇒ 애플리케이션 코드와 데이터베이스 모델 객체 사이의 전환 계층 필요! (임피던스 불일치(impedance mismatch))

예시: 링크드인 프로필 (이력서) 데이터 모델

  • user_id : 모델 고유 식별자
  • first_name : 문자열
  • last_name : 문자열
  • summary : 문자열
  • region_id : 지역에 대한 식별자
  • industry_id : industry에 대한 식별자
  • photo_url : 문자열
  • positions : { job_title: 문자열, organization: 문자열 }의 배열
  • educations : { school_name: 문자열, start: num|null , end: num|null }의 배열
  • contact_info : { sns_type: url }의 key-value 조합

위에는 책에서 나온 예제2-1. JSON 문서로 표현한 링크드인 프로필을 조금 더 단순화 한 것이다.

 

이력서같은 데이터는 모든 내용을 데이터 하나에 다 갖추고 있는 '문서'라서 JSON 표현에 매우 적합하다.

 

이를 관계형 스키마를 통해 저장할 경우 positions, education, contact_info 각각 모두 요소마다 row를 생성해야 하고 user_id와 연결해야 한다. (일대다)

⇒ 관계형 데이터 베이스에서 유저 정보를 가져오기 위해 많은 조인 연산을 필요로 함

 

Figure 2-2. One-to-many relationships forming a tree structure.

일대다 관계는 위와 같은 트리 구조를 가지기 때문에 문서 데이터베이스에 더 유리하다.

 

 

📌 지역성(locality)

관계형 스키마를 이용해 다중 테이블(multi-table)스키마로 이력서를 저장할 경우 프로필을 가져오려면 '다중 질의' 또는 하위 테이블 간의 '다중 조인'을 수행해야 한다. 즉, 일대다 관계가 많은 데이터 유형
하지만 JSON 표현에서는 모든 정보가 한 곳에 있어 질의 하나로 충분하다.

이런 경우, JSON 표현이 다중 테이블(multi-table)보다 더 나은 지역성(locality)를 갖는다고 말한다.

 

다대일과 다대다 관계

예제2-1.에서는 region_id와 industry_id를 이용해 식별자를 저장했고 그 지역이나 업계 정보를 문자열로 입력하지 않았다.

 

만약 사용자가 지역과 업계를 입력할 수 있는 자유 텍스트 필드가 있다면 평문 저장이 합리적이지만

지역과 업계 정보를 드롭다운 혹은 자동완성으로 해 사용자가 '선택'하게 만들면 예제2-1.과 같은 방식이 합리적이다.

 

후자의 방식을 선택할 경우 장점은 다음과 같다.

  • 일관된 스타일과 철자
  • 모호함 회피
  • 갱신의 편의성
  • 현지화 지원
  • 더 나은 검색

식별자(id)로 저장할 경우 그 내용이 바뀌어도 이를 참조하는 다른 데이터에 영향을 주지 않는다.

다대일 관계

중복된 데이터를 정규화하려면 다대일(many-to-one)관계(많은 사람들이 한 지역에 살고 사람들이 한 업계에서 일한다.)가 필요한데 문서 데이터베이스는 대개 조인에 약하다.

 

다대다 관계

추천서 기능을 추가한다고 하면 다대다 관계를 필요로 한다.

  • 이력서의 추천서에 추천인의 이름과 사진 등이 보여진다.
  • 추천인이 이름과 사진 정보를 갱신하면 이를 반영해야 한다는 뜻이다.

Figure 2-4. Extending resumes with many-to-many relationships.

다대다 관계로 넘어갈 경우 문서 데이터베이스는 더 취약해진다.

 

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

결론부터 말하자면 코다실과 같은 네트워크 모델의 전철을 밟고 있지 않다.

  • 계층 모델 → 네트워크 모델, 관계형 모델 두 개로 분기
  • 다대다 관계의 표현 → 역사적으로 지속되는 논쟁!!
  • 네트워크는 다대다 관계의 표현에서 매우 불리

네트워크 모델 (코다실 모델)

계층 구조의 일반화, 계층 모델의 트리 구조에서는 하나의 부모, 

네트워크 모델은 다중부모 가능

 

레코드 간의 연결은 외래키보다는 '포인터'방식.

하나의 레코드에 접근하지 위해 최상위 레코드(root record)에서부터 연속된 연결 경로를 따른다 접근 경로

 

수동 접근 경로 선택은 매우 제한된 하드웨어 성능을 가진 과거 70년대에는 효율적으로 사용할 수 있었으나 코다실에서의 질의는 'n차원 데이터 공간을 항해하는 것'

→ 모델을 바꾸는 작업 매우 어려움

 

관계형 모델

  • 외래 키를 이용해 수월한 접근 가능
  • 관계(테이블)는 단순히 튜플(로우)의 컬렉션이 전부고, 알려진 모든 데이터를 배치한다.
  • 질의 최적화기를 통한 단순하고 범용성 높은 질의 형식
📌 다대다 관계에 있는 데이터 삽입시 관계형 모델과 네트워크 모델

관계형 모델: 외래 키에 대한 조인을 질의를 할 때 수행, 외래 키 관계를 신경쓰지 않고 데이터 삽입 가능
네트워크 모델(코다실): 삽입하면 사실상 조인이 수행된 상태

 

<질의 최적화기>

  • 질의의 처리 순서, 즉, 접근 경로를 자동으로 수행
  • 새로운 방식으로 데이터에 질의하고싶은 경우 새로운 색인을 선언하기만 하면 자동으로 이를 적용해 처리 → 새로운 기능 추가 용이
  • 데이터베이스를 사용하는 모든 애플리케이션이 사용 가능한 범용성

 

문서 데이터베이스와의 비교

문서 데이터베이스는 한 가지 측면에서 계층 모델로 돌아갔다.

⇒ 상위 레코드 내에 중첩된 레코드(예제2-1.의 positions, education, contact_info와 같은 일대다 관계)

 

<다대일과 다대다 관계에서의 관계형과 문서 데이터베이스 비교>

관계형 데이터베이스 문서 데이터베이스
외래 키 문서 참조(document reference)

다대다 관계의 표현을 충분히 해낼 수 있다.

 

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

어떤 데이터 모델이 애플리케이션 코드를 더 간단하게 할까?

CASE1. 애플리케이션 데이터가 문서와 비슷한 구조(일대다 관계 트리로 보통 한 번에 전체 트리를 적재)일 경우

→ 문서 모델 (BUT 문서 내 중첩 항목을 바로 참조할 수 없다. 문서가 너무 깊게 중첩되지 않으면 문제 X)

 

CASE2.다대다 관계도 필요할 경우?

문서 데이터베이스의 매력 ↓

조인을 흉내낼 경우 복잡도가 애플리케이션을 이동하고 데이터베이스 내 특화된 코드로 진행되는 조인보다 느리다.

→ 관계형 모델

 

CASE2-1. 상호 연결이 매우 많은 데이터의 경우

 그래프형 데이터 모델 > 관계형 모델(무난) > 문서 모델

 

CASE3. 데이터가 여러 다른 유형으로 구성되어 있을 때 (여러 이유로 구조 변경)

→ 읽기 스키마 접근 방식이 유용, 문서 모델 유용, 그래프 모델도 유용하다.

 

CASE4.전체 문서에 자주 접근해야 할 경우

→ 저장소 지역성(storage locality) → 문서 모델 유용

 

문서 데이터베이스와 관계형 데이터베이스 통합

  • 관계형 데이터베이스: XML, JSON 지원
  • 문서 데이터베이스: 조인 지원

 

데이터 질의 언어

질의 언어의 종류

  1. 선언형 질의 : SQL, 관계 대수 구조와 유사
  2. 명령형 코드를 통한 질의 : IMS와 코다실

명령형 코드를 통한 질의는 특정 순서로 특정 연산을 수행

 

선언형 질의 언어는 명령형보다 더 간결하고 상세 구현(순서 결정과 수행)이 질의 최적화기에게 넘어가 있어 시스템 성능 향상이 가능하다.

 

이렇듯 순서로부터 자유롭기 때문에 선언형 질의 언어는 병렬 실행에도 적합

웹에서의 선언형 질의

"selected"라는 class를가진 <li> element의 하위에 있는 <p> element를 강조하고 싶다고 하자.

  • CSS, XSL :  문서의 스타일을 지정하기 위한 선언형 언어
  • JS를 통해 구현할 경우 <li> element들을 일일이 순회하며 "selected"를 class로 갖고 있는지 확인하고 갖고 있다면 그 <li> element에서 <p> element를 찾아 스타일을 지정해주어야 한다.
li.selected > p {
    background-color: blue;
}

위는 CSS 예시이다.

var liElements = document.getElementsByTagName("li"); 
 
for (var i = 0; i < liElements.length; i++){
	if (liElements[i].className === "selected") { 
    	var children = liElements[i].childNodes; 
        for (var j = 0; j < children.length; j++) {
        	var child = children[j];
            if (child.nodeType === Node.ELEMENT_NODE && child.tagName === "P") { 
            	child.setAttribute("style", "background-color: blue");
            }
         }
     }
}

위는 JS 예시로 명령형의 경우 웹에서도 훨씬 복잡한 것을 확인할 수 있다. 또한 여러 문제도 있다. (책 참조)

맵리듀스 질의

맵리듀스(MapReduce) : 많은 컴퓨터에서 대량의 데이터를 처리하기 위한 프로그래밍 모델

선언형 질의 언어와 명령형 질의 API의 중간 정도

 

NoSQL에서의 제한된 형태의 맵리듀스 지원: 많은 문서를 대상으로 읽기 전용(read-only) 질의를 수행할 때 사용

관계형 DB의 선언형 질의의 이점을 가져올 수 있다.

 

맵리듀스는 map(collect)reduce(fold, inject) 함수를 기반으로 한다. 질의로직은 반복적으로 호출하는 조각 코드로 표현한다.

몽고DB의 맵리듀스 기능

해양 생물학자가 바다에서 동물을 볼 때마다 데이터베이스에 관찰 기록, 한 달에 얼마나 자주 상어를 발견하는지 보고서 작성

db.observations.mapReduce( 
    function map() {
    	var year = this.observationTimestamp.getFullYear(); 
        var month = this.observationTimestamp.getMonth() + 1; 
        emit(year + "-" + month, this.numAnimals);
    },
    function reduce(key, values) { 
    	return Array.sum(values);
    },
    {
    	query: { family: "Sharks" },
        out: "monthlySharkReport" 
    }  
);

⇒ map과 reduce 함수를 어떻게 작성하는지가 포인트

 

  • map 함수를 통해 각 문서를 key-value 쌍으로 구성된 형태로 emit을 통해 방출한다. (ex. emit("1995-12", 3), emit("1995-12", 4))
  • reduce 함수에서는 동일한 key를 가진 쌍들에 대해 그룹화를 진행하고 같은 키를 가진 그룹은 reduce 함수를 한 번 호출한다. (같은 key를 가진 value 들이 배열 형태로 넘어감) (ex. reduce("1995-12", [3, 4]))

 

그래프형 데이터 모델

다대다 관계가 매우 일반적인 데이터를 모델링할 때 유용하다.

구성요소

  • 정점(vertex, node, entity)
  • 간선(edge, relation, 호(arc)) 

가장 큰 특징

완전히 다른 유형의 객체를 일관성 있게 저장할 수 있는 강력한 방법을 제공한다.

 

Figure 2-5. Example of graph-structured data (boxes represent vertices ,&nbsp; arrows represent edges).

여기서 정점은 사용자, 대륙, 국가, 주, 지역을 나타내고 간선은 사용자의 태어난 곳, 사용자 간의 관계, 지역 간의 관계를 나타낸다.

종류

  • 속성 그래프 모델 (property graph model) : 네오포제이(Neo4j), 타이탄(Titan), 인피티니티그래프(InfiniteGraph)
  • 트리플 저장소 모델 (triple-store model) : 데이토믹(Datomic), 알레그로그래프(AllegroGraph) ... etc

그래프용 선언형 질의 언어

  1. 사이퍼(Cypher)
  2. 스파클(SPARQL)
  3. 데이터로그(Datalog)

속성 그래프 (property graph model)

vertex 구성 요소

  • A unique identifier
  • A set of outgoing edges
  • A set of incoming edges
  • A collection of properties (key-value pairs)

edge 구성 요소

  • A unique identifier
  • 간선의 시작 정점 The vertex at which the edge starts (the tail vertex)
  • 간선의 끝 정점 The vertex at which the edge ends (the head vertex)
  • 간선의 두 정점 사이의 관계 유형을 설명하는 레이블 A label to describe the kind of relationship between the two vertices
  • A collection of properties (key-value pairs)

주요한 특징들

  1. 정점은 다른 정점과 간선으로 연결된다. 이때 연결을 제한하는 별도의 스키마는 존재하지 않는다.
  2. 어떤 정점이든 그 정점의 incoming edges와 outgoing edges를 효율적으로 찾을 수 있다. 즉 정점을 따라 그래프를 순회(Graph traversal)할 수 있다.
  3. 다른 유형의 간선, 정점에 대해서 자유로운 저장이 가능하며 데이터 모델을 깔끔하게 유지할 수 있다.

그림 2-5.가 그래프형 데이터 모델에 적합한 이유

  1. 나라마다 다른 지역구조 (다양한 유형의 데이터)
    : 프랑스는 '주(départment)', '도(région)' 의 지역구조인 반면 미국은 '군(country)'과 '주(state)' 의 구조이다.
  2. 그래프의 확장성/발전성
    : 루시와 알랭 뿐만 아니라 다른 사람들에 대한 정보를 추가하기 편하다. 거주 정보뿐만 아니라 음식 알레르기를 저장할 수 있고 알레르기 성분과 그 성분이 포함된 음식 간의 관계도 추가해 각 사람들이 먹을 수 있는 안전한 음식이 무엇인지 알아내는 질의를 작성할 수 있다.
    ⇒ 애플리케이션 기능 확장이 유리!

사이퍼 (Cypher) 질의 언어

  • 속성 그래프를 위한 선언형 질의 언어
  • 네오포제이 그래프 데이터베이스용으로 만들어짐

다음은 Lucy와 Lucy의 거주 정보에 대한 데이터 생성문의 예시이다. (예제2-3)

CREATE
    (NAmerica:Location {name:'North America', type:'continent'}),
    (USA:Location {name:'United States', type:'country' }),
    (Idaho:Location {name:'Idaho', type:'state' }),
    (Lucy:Person {name:'Lucy' }),
    (Idaho) -[:WITHIN]-> (USA) -[:WITHIN]-> (NAmerica),
    (Lucy) -[:BORN_IN]-> (Idaho)

아래는 미국에서 유럽으로 이민 온 사람을 찾는 사이퍼 질의이다. (예제 2-4.)

MATCH
    (person) -[:BORN_IN]-> () -[:WITHIN*0..]-> (us:Location {name:'United States'}),
    (person) -[:LIVES_IN]-> () -[:WITHIN*0..]-> (eu:Location {name:'Europe'})
RETURN person.name

'미국에서 유럽으로 이민 온' 사람은 미국의 지역으로 향하는 'BORN_IN' outgoing 간선을 가지고 이와 동시에 프랑스의 지역으로 향하는 'LIVES_IN' outgoing 간선을 가진다.

 

사람의 'BORN_IN' 간선이 향하는 지역과 'LIVES_IN' 간선이 향하는 지역이 각각 미국과 유럽에 속하는지는 그 지역의 'WITHIN' 간선이 향하는 Location 정점에 각각 'United States'와 'Europe'의 name 값을 가진 정점이 있는지 확인하면 된다. 

 

'미국에서 태어났는가'와 '유럽에서 사는가'에 대한 질의를 예제2-4.에서와 같이 표현하고 있다.

SQL에서의 질의

결론부터 얘기하자면 '매우' 복잡하다. 단 사이퍼에선 단 2줄로 표현됐던 것과 달리 미국에서 유럽으로 이민 온 사람을 찾는 질의가 SQL에서는 29줄로 '매우' 길어진다.

 

이는 다양한 데이터 모델이 서로 다른 사용 사례를 만족하기 위해 설계됐다는 사실을 보여주며 각 애플리케이션마다 적합한 데이터 모델을 선택하는 작업은 중요하다.

트리플 저장소

속성 그래프 모델과 그 구조는 거의 동등하나 정점과 간선을 표현하는 방식이 조금 다르다.

구성 요소

모든 정보를 간단한 세 부분 구문(three-part statements) 형식으로 저장한다.

  • 주어
  • 서술어
  • 목적어

(주어, 서술어, 목적어)의 형태로 작성하며 여기서 주어는 그래프의 정점과 동일하다.

 

목적어는 두 가지 중 하나다. 

  1. 문자열이나 숫자 같은 원시 데이터타입의 값. 이 경우 트리플의 서술어와 목적어는 주어 정점에서 속성의 키, 값과 동등하다. 예를 들어 (루시,나이,33)은 {"age": 33} 속성을 가진 정점 lucy와 같다.
  2. 그래프의 다른 정점. 이 경우 서술어는 그래프의 간선이고 주어는 꼬리 정점(간선의 시작 정점)이며 목적어는 머리 정점(간선의 끝 정점)이다. 예를 들어 (루시, 결혼하다, 알랭)에서 주어와 목적어인 루시와 알랭은 모두 정점이고 서술어 결혼하다는 두 정점을 잇는 간선의 레이블이다.

터틀(Turtle) 형식의 트리플로 작성된 데이터 예시 (예제 2-7.)

@prefix : <urn:example:>.

_:lucy a :Person; :name "Lucy"; :bornIn _:idaho.
_:idaho a :Location; :name "Idaho"; :type "state"; :within _:usa.
_:usa a :Location; :name "United States"; :type "country"; :within _:namerica.
_:namerica a :Location; :name "North America"; :type "continent".

위 예시에 정점은 "_:(정점 이름)" 의 형식으로 표현되었다.

서술어와 목적어가 주어 정점의 속성 키, 값 쌍(key-value)이라면 _:lucy :name "Lucy"와 같이 표현되고,

목적어가 다른 정점이고 서술어가 주어와 목적어를 잇는 간선의 레이블일 경우 _:lucy :bornIn _:idaho 와 같이 표현된다.

시멘틱 웹

시멘틱 웹은 트리플 저장소 모델과 완전히 독립적이지만 많은 사람들이 둘을 밀접한 관계에 놓는다.

 

시멘틱 웹은 웹 사이트를 사람이 읽는 것을 넘어서 컴퓨터도 읽을 수 있는 데이터 형태로 게시하는 것에서 출발했는데 RDF(자원 기술 프레임워크, Resource Description Framework)가 서로 다른 웹사이트가 일관된 형식으로 데이터를 게시하기 위한 방법을 제시한다.

RDF 데이터 모델

RDF는 데이터를 사람이 읽을 수 있는 형식으로 표현하며 때때로 XML 형식을 쓰기도 하지만 이 형식은 오히려 더 내용을 장황하게 만든다. 한눈에 쉽게 보기 위해서 터틀/N3를 선호한다.

 

이때 트리플 데이터 형식을 쓰는데 RDF에서 트리플의 주어, 서술어, 목적어가 주로 URI라는 특징이 있다. 이는 인터넷 전체의 데이터 교환을 위해 설계했기 때문이다.

스파클(SPARQL) 질의 언어

스파클(SPARQL Protocol and RDF Query Language의 준말)은 RDF 데이터 모델을 사용한 트리플 저장소 질의 언어이다. 

PREFIX : <urn:example:>

SELECT ?personName WHERE {
    ?person :name ?personName.
    ?person :bornIn / :within* / :name "United States".
    ?person :tivesIn / :within* / :name "Europe".
}

미국에서 유럽으로 이민 온 사람을 찾는 스파클 질의(예제 2-9.)는 사이퍼보다 더 간결해진다.

 

RDF가 속성과 간선을 구별하지 않고 서술어만 사용하기 때문에 속성 매칭에도 동일한 구문을 사용할 수 있다. 위의 예시를 보면 'bornIn'과 'within'은 간선에 해당하는 서술어이고 name은 속성의 키에 해당하는 서술어임에도 같은 방식(":(이름)")의 방식으로 서술된 것을 확인할 수 있다.

그래프 데이터베이스와 네트워크 모델의 비교

  코다실 데이터베이스 그래프 데이터베이스
데이터 유형 유연성 측면 중첨 가능한 레코드 타입을 지정하기 위해 스키마가 필요 스키마 지정없이 자유롭게 다양한 유형의 정점과 정점을 잇는 간선 생성 가능
데이터 접근 방식 무조건 레코드의 접근 경로 중 하나를 탐색 각 정점은 고유한 id를 가지고 있어 직접 참조도 가능하고 색인을 사용해 특정 값을 가진 정점을 빠르게 찾을 수 있다.
데이터의 삽입 레코드의 하위 항목은 정렬된 집합이기에 이를 고려해야 한다. 정점과 간선은 정렬되어 있지 않다. 질의에서 결과를 정렬할 뿐이다.
질의 언어 유형 명령형 질의 언어 고수준 선언형 질의 언어

초석: 데이터 로그

질의 언어의 기반이 되는 초석

구성 요소 형태

서술어(주어, 목적어)로 작성한다. (예제 2-10.)

name(namerica, 'North America'). 
type(namerica, continent).
name(usa, 'United States'). 
type(usa, country). 
within(usa, namerica).
name(idaho, 'Idaho'). 
type(idaho, state). 
within(idaho, usa).
name(tucy, 'Lucy'). 
born_in(tucy, idaho).

질의 형태

프롤로그의 부분집합 형태로 표현된다. (예제 2-11.)

within_recursive(Location, Name) :- name(Location, Name). /* Rule 1 */

within_recursive(Location, Name) :- within(Location, Via), /* Rule 2 */
								 within_recursive(Via, Name).

migrated(Name, BornIn, LivingIn) :- name(Person, Name), /* Rule 3 */
								 born_in(Person, BornLoc), 
                                 within_recursive(BornLoc, BornIn), 
                                 lives_in(Person, LivingLoc), 
                                 within_recursive(LivingLoc, LivingIn).

?- migrated(Who, 'United States', 'Europe').
/* Who = 'Lucy'. */

미국에서 유럽으로 이민 온 사람을 찾는 질의를 위와 같이 표현할 수 있다.

 

사이퍼와 스파클과 달리 단계를 나누어 질의를 진행하는데 먼저 새로운 서술어를 데이터베이스에 전달하는 규칙(rule)을 정의한다. 위 예제에서 새로 정의된 서술어는 'within_recursive'와 'migrated'이다.

 

규칙에서 대문자로 시작하는 단어는 변수이고 :-연산자의 오른편에 있는 모든 서술어의 대응을 찾으면 규칙이 적용된다.

  1. name(namerica, 'North America') exists in the database, so rule 1 applies. It generates within_recursive(namerica, 'North America').
  2. within(usa, namerica) exists in the database and the previous step generated within_recursive(namerica, ' North America'), so rule 2 applies. It generates within_recursive(usa, 'North America').
  3. within (id a ho, usa) exists in the database and the previous step generated within_recursive(usa, 'North America'), so rule 2 applies. It generates within_recursive(idaho, 'North America').

위와 같이 규칙 1,2를 반복 적용해 북아메리카(또는 다른 장소)에 있는 모든 장소를 찾을 수 있다. 규칙3를 통해서는 'BornIn' 장소(그 장소에 속한 하위 장소들, idaho와 같은)에서 태어나 'LivingIn' 장소(그 장소에 속한 하위 장소들, london과 같은)에서 사는 모든 사람들을 찾을 수 있다. 

 

정리

현재 다양한 데이터 모델들이 존재하고 있고 각 데이터 모델마다 장단점이 있어 애플리케이션마다 저장할 데이터의 특성을 파악한 후 적절한 데이터 모델을 골라야 한다.

다양한 데이터 모델과 질의 언어가 존재하지만 책에 나온 관계형, 문서, 그래프 데이터베이스의 대표적인 특징을 기반으로 데이터 특성에 따라 어떤 데이터 모델이 적합한지 표현해보면 위와 같이 표현해볼 수 있을 것 같다.

728x90
반응형

댓글