TIL

02장 데이터 모델과 질의 언어

관계형 모델과 문서 모델

NoSQL의 탄생

객체 관계형 불일치

다대일과 다대다 관계

데이터를 위한 질의 언어

웹에서의 선언형 질의

맵리듀스 질의

SELECT date_trunc('month', observation_timestamp) AS observation_month, 
	sum(num_animals) AS total_animals
FROM observations
WHERE faily = 'Sharks' 
GROUP BY obervation_month;
db.observations.mapReduce(
	function map() { // 2
		var year = this.observationTimestamp.getFullYear();
		var month = this.observationTimestamp.getMonth() + 1;
		emit(year + "-" month, this.numAnimals); // 3
	},
	function reduce(key, values) { // 4
		return Array.sum(values); // 5
	},
	{
		query: { family: "Sharks" }, // 1
		out: "monthlySharkReport"
	}
)
  1. 상어 종만 거르기 위한 필터를 선언적으로 지정
  2. map은 자바스크립트 함수다.
    • 질의와 일치하는 모든 문서에 대해 한 번씩 호출
    • this는 문서 객체로 설정
  3. map 함수는 키(년 - 월)와 값(관측치에 있는 동물 수)을 방출한다.
  4. map이 방출한 키-값 쌍은 키로 그룹화된다.
    • 같은 키를 갖는 모든 키-값 쌍은 reduce 함수를 한 번씩 호출한다.
  5. reduce 함수는 특정 월의 모든 동물 수를 합친다.
  6. 최종 출력은 monthlySharkReport 컬렉션에 기록한다.

그래프형 데이터 모델

속성 그래프

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);

사이퍼 질의 언어

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

SQL의 그래프 질의

WITH RECURSIVE 
-- 미국 출생자 찾기
born_in_us AS (
    -- 기본 케이스: 직접 미국에서 태어난 사람
    SELECT p.person_id, p.name 
    FROM Person p
    JOIN Location l1 ON p.birth_location_id = l1.id 
    WHERE l1.name = 'United States'
    
    UNION ALL
    
    -- 재귀 케이스: 하위 지역에서 태어난 사람
    SELECT p.person_id, p.name
    FROM Person p
    JOIN Location l ON p.birth_location_id = l.id
    JOIN Location parent ON l.parent_id = parent.id
    JOIN born_in_us b ON parent.id = b.person_id
),

-- 유럽 거주자 찾기
lives_in_eu AS (
    -- 기본 케이스: 직접 유럽에 사는 사람
    SELECT p.person_id, p.name
    FROM Person p
    JOIN Location l2 ON p.current_location_id = l2.id
    WHERE l2.name = 'Europe'
    
    UNION ALL
    
    -- 재귀 케이스: 하위 지역에 사는 사람
    SELECT p.person_id, p.name
    FROM Person p
    JOIN Location l ON p.current_location_id = l.id
    JOIN Location parent ON l.parent_id = parent.id
    JOIN lives_in_eu e ON parent.id = e.person_id
)

-- 두 조건을 모두 만족하는 사람 찾기
SELECT DISTINCT us.name
FROM born_in_us us
JOIN lives_in_eu eu ON us.person_id = eu.person_id[1][2];

트리플 저장소와 스파클

시맨틱 웹

스파클 질의 언어

PREFIX : <run:example:>

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