관계형 데이터 모델

  • 데이터는 테이블이라는 관계로 구성되고 순서가 없는 튜플(Tuple)의 형태 (로우의 모음 row)
  • 질의 최적화기 (Optimizer) : 어떤 순서로 실행할지를 결정하고 사용할 색인을 자동 결정한다.
  • 다대일, 다대다 관계표현 : 외레키

정규화: 데이터의 중복을 없애는 것

회사정보 테이블

company_id company_name company_type company_number reg_date
101 (주)운송물류 물류 12353512 2024-08-10 13:00:00
102 (주)교통 전기버스 12335642 2024-05-20 15:15:27

차량정보 테이블

car_id comapny_id car_number car_type driver_id reg_date
1100 101 차량12가3069 버스 10 2024-09-20 13:13:20
1102 101 차량12바2019 물류 2 2024-08-12 13:25:20
1103 102 차량12가3208 전기버스 8 2024-09-20 15:30:20

운행기록 테이블

car_id company_id speed start_date end_date latitude longitude
1100 101 80 2024-08-05 12:25:35 2024-08-05 12:25:36 127.12 234.45
1100 101 80 2024-08-05 12:25:36 2024-08-05 12:25:37 127.12 234.45
1102 102 45 2024-08-10 14:25:36 2024-08-10 14:25:37 127.24 234.55
1102 102 45 2024-08-10 14:25:37 2024-08-10 14:25:38 127.24 234.55
SELECT company.company_name as company_name, car.car_no as car_no, history.drive_record
FROM company company, car car, drive_history history 
WHERE company.company_id = car.company_id
AND car.car_id = history.car_id;

문서형 데이터모델

  • 대규모 데이터 셋이나 쓰기 처리율이 높은 것들에 대해 최적화 되어 있음
  • 스키마가 존재하지 않기 때문에 유연함
  • 모든 관련 정보가 한 곳에 중앙집중화되어 있기 때문에 한 번의 질의 조회로 충분

스키마: 데이터가 어떤식으로 저장이 되는지에 대한 데이터 구조

{
    "_id" : "66f82a1a62afc70d7a072f8a",
    "company_id" : 101,
    "driver_history" : [
        {
            "speed" : 80,
            "start_date" : "2024-08-05T12:25:35Z",
            "end_date" : "2024-08-05T12:25:36Z",
            "latitude" : 127.15,
            "longitude" : 234.34,
            "gaspedal" : 35,
            "azimuth" : 330
        },
        {
            "speed" : 80,
            "start_date" : "2024-08-09T13:25:35Z",
            "end_date" : "2024-08-09T13:25:36Z",
            "latitude" : 127.15,
            "longitude" : 234.34,
            "gaspedal" : 35,
            "azimuth" : 330
        },
        // 운행기록데이터
    ]
}

그래프형 데이터 모델

데이터간 연결관계가 복잡할 경우 그래프 데이터 모델링하는 것이 자연스러움

예시: 페이스북이나 linked in처럼 사람들 간의 관계를 표현하는 방식, 사기 탐지, 경로 최적화 등

  • 정점 (vertex): 노드, 엔티티
  • 간선 (edge): 관계, 호

데이터를 위한 질의 언어

명령형

특정 순서로 특정 연산을 수행하게끔 컴퓨터에게 지시함

def getShark(animals):
    sharks = []
    for animal in animals:
        if animal == 'Sharks':
            sharks.append(animal)
    return sharks
const liElements = document.getElementsByTagName("li");
for (let i = 0; i < liElements.length; i++) {
	if (liElements[i].className === 'selected') {
		let children = liElements[i].childNodes;
		for (let j = 0; j < children.length; j++) {
			let child = children[j];
			if (child.nodeType === Node.ELEMET_NODE && child.tagName === 'P') {
				child.setAttribute('style', 'background-color: blue');
			}
		}
	}
}

선언형

방법이 아닌 알고자하는 데이터의 패턴 - 어떤 순서로 특정 연산을 수행하지는 최적화도구등이 결정

SELECT animals_nic_name, animals_shape 
FROM animals
WHERE family = 'Sharks';
li.selected > p {
    background-color: blue;
}

맵리듀스 질의

  • 대량의 데이터를 처리하기 위한 프로그래밍 모델
  • 많은 문서를 대상으로 읽기 전용 질의를 수행할 때 사용
  • 함수형 프로그래밍의 map, reduce 함수와 유사
db.observations.mapReduce(
	function map() {
		var year = this.observationTimestamp.getFullYear();
		var month = this.observationTimestamp.getMonth() + 1;
		emit(year + "-" + month);
	},
	function reduce(key, values) {
		return Arrays.sum(values);
	},
	{ 
		query : { family : "Sharks" },
		out : "monthlySharkReport"
	}
)
db.monthlySharkReport.find().pretty();

Aggregate

맵리듀스의 사용자 정의 함수를 정의하지 않고도, 맵-리듀스 로직 작성 가능

db.observations.aggregate([
	{ $match: { family: "Sharks" } },
	{ $group: {
		_id: {
			year: { $year: "$observationTimestamp" },
			month: { $month: "$observationTimestamp" }
		},
		totalAnimals: { $sum: "$numAnimals" }
	} }
])

댓글남기기