이 책에 대하여
Designing Data-Intensive Applications
이 책은 OReilly 에서 출간한 Designing Data-Intensive Applitions의 한국어 번역본인 데이터 중심 애플리케이션 설계 를 읽고 정리한 포스팅입니다.
주위에서 추천이 많은 책이기도 하고 내용도 좋은 명저이기도 해서 정리도 할겸 당분간 이 책의 내용을 정리하여 포스팅할 생각입니다. 블로그 주인이 책을 읽고 정리한 글이기 때문에 잘못된 내용이나 부족한 내용이 있을 수 있습니다. 이에 대해서는 댓글로 지적해주시면 좋을 것 같습니다.
데이터 모델
- 해결하려는 문제를 어떻게 생각하는지?
- 데이터 모델을 표현하는 방법
- 애플리케이션 개발자는 API 모델링
- 데이터 구조를 저장할때 JSON, XML, 관계형 데이터베이스 테이블, 그래프 모델로 표현
- 관계형 모델(relational model)
- 문서 모델(document model)
- 그래프 기반 데이터 모델(graph-based data model)
- DB SW를 개발하는 엔지니어는 JSON, XML, 관계형, 그래프 데이터를 메모리나 디스크 또는 네트워크 상의 바이트 단위로 표현
- HW 엔지니어는 전류, 빛의 파동, 자기장 등의 관점에서 바이트를 표현
관계형 모델
- 1970년 에드가 코드(Edgar Codd)가 제안
- 근원 → 비즈니스 데이터리 처리로 등장
- 목표 → 정리된 인터페이스 뒤로 구현 세부 사항을 숨기기 위함
- 데이터베이스 내부 데이터 표현에 대해 고민하지 않아도됨
NoSQL
- Not Only SQL
- NoSQL이라는 말은 어떤 특정 기술을 참고한 것이 아니기에 적절하지는 않다
- 2009년 오픈소스, 분산환경, 비관계형 데이터베이스 밋업(meetup)용 인기 트위터 해시태그
- 왜 나왔는지?
- 대규모 데이터셋이나 높은 쓰리 처리량 달성을 관계형 DB보다 쉽게 하고 싶어서(관계형 DB보다 높은 확장성을 가지고 싶다)
- 무료 오픈소스 SW에 대한 선호도 확산
- 관계형 모델에서 지원하지 않는 특수 질의 동작
- 관계형 스키마의 제한에 대한 불만과 더욱 동적이고 표현력이 풍부한 데이터 모델에 대한 바람
- 애플리케이션의 요구사항은 저마다 다르기 떄문에 특정 요구사항에서 선택한 기술이 다른 요구사항에서는 다르게 작용 할 수 있다.
- 이러한 특성 때문에 가까운 미래에서는 관계형 DB + 비관계형 데이터스토어와 함께 사용 될 것이다
- 이런 개념을 종종 다중 저장소 지속성(polyglot persistence)라고 함
객체 관계형 불일치
- 대부분의 애플리케이션은 객체지향 언어로 만들어진다
- 객체 모델와 데이터베이스 모델(테이블, 로우, 컬럼) 사이에 불일치가 발생
- 이러한 불일치를 Impedence mismatch 라고한다
- 이 불일치를 해결하기 위해 전환 계층이 필요한데 ActiveRecord, Hibernate와 같은 ORM 프레임워크가 이 둘사이의 불일치를 줄이는 전환 계층 코드(boilerplate code)를 줄여주지만 두 모델의 차이를 완벽히 줄여주진 않는다
다대일과 다대다 관계
- ID를 문자열로 할지? 정수값으로 할지? → 중복의 문제
- 사용자 인터페이스에 자유 텍스트 필드가 있다면 평문 저장이 나을 수 있다(평문 채택의 경우)
- 모든 레코드에 정보를 중복 저장해야함
- ex> 지역 칼럼을 포함하는 사람 테이블에 “서울” 이라는 문자열이 중복 저장됨
- 드롭다운 리스트나 자동완성 기능을 만들어 사용자에게 선택하게 하는 것이 더 나을 수 있는데 이것을 채택하면 장점은(정수값을 채택하는 경우)
- 모든 레코드에 정보를 갖는 형태가 아닌 정보를 참조하는 형태
- ex> “서울”이라는 문자열 정보의 ID를 참조
- 장점
- 일관된 입력
- 중복 제거로 인한 모호함 회피
- 갱신의 편의성
- 한 곳에만 저장되므로 해당 ID의 정보만 수정하면 이것을 저장하는 모든곳이 정보가 변경됨
- 현지화 지원
- 더 나은 검색
- 예를 들어 서울에 있는 어떤 건물을 찾는다고 했을때 지역 목록에 강남이 있다면 강남을 서울에 있는 지역으로 표현 할 수 있다
- 문자열을 사용한 경우에는 강남과 서울은 전혀다른 문자열이기 때문에 데이터로 봤을떄에는 다른 지역으로 인식한다
- ID를 사용하게 된다면 ID 자체의 값은 아무런 의미가 없어야지 변경가능성에 벗어날 수 있다
- 의미를 가지게 된다면 ID를 변경해야 하는데 ID의 정보가 중복돼 있으면 모든 중복을 변경해야 한다
- 이러한 중복을 제거하는 일이 데이터베이스 정규화의 핵심이다
문서 데이터베이스는 역사를 반복하고 있나?(문서 데이터베이스에서의 다대다 표현의 해결 방법)
- 1970년대 비즈니스 데이터 처리를 위해 가장 많이 사용한 DB는 IBM의 IMS(Information Management System) 이다
- IMS의 데이터 설계는 계층 모델이라 부르고 이것은 JSON 구조와 비슷하게 중첩된 레코드 트리로 표현한다
- 문서 DB 처럼 IMS에서도 일대다 관계는 잘 동작하지만 다대다 표현이 어려웠고 조인을 지원하지 않는다
- 다대다 표현이 어렵기 때문에 데이터를 중복으로 표현할지? 참조를 수동으로 해결할지 결정해야 했다
- 이러한 어려움을 해결하기 위한 해결책은 관계형 모델과 네트워크 모델이 있다
네트워크 모델(코다실 모델)
- 계층 모델을 일반화
- 계층 모델의 트리구조에서 모든 레코드는 정확하게 하나의 부모가 있지만 네트워크 모델에서는 다중 부모가 있을 수 있다
- 원하는 레코드에 접근하는 유일한 방법은 최상위 레코드(root)부터 순차적으로 찾는 것이다 이를 접근 경로라고 한다
- 가장 간단한 경우 접근 경로가 연결 목록의 순회와 같을 때이다
- 루트부터 순차적으로 시작하여 원하는 것을 찾을때까지 한번에 하나씩 순회하는 방식
- 다대다 관계에서는 다양한 경로가 어떤 레코드에 도달할 수 있다(다중 부모가 있는 경우)
- 이렇게 다양한 경로인 경우에 모든 경로를 추적 해야한다
- 단점
- 질의와 갱신을 위한 코드가 복잡하여 유연하지 못한 문제
- 원하는 데이터 경로가 없다면 수많은 DB 질의 코드를 살펴봐야하고 새로운 접근 경로를 다루기 위해 코드를 재작성
관계형 모델
- 테이블, 로우의 컬렉션이 전부
- 네트워크 모델과 달리 개발자가 접근 경로를 생각할 필요가 없다
- 접근 경로를 질의 최적화기(query optimizer)가 대신 작성
- 네트워크 모델에 비해 유지보수가 쉽다
두 모델과 문서 데이터베이스와의 비교
- 계층 모델
- 테이블이 아닌 상위 레코드 내에 중첩된 레코드를 저장
- 다대일, 다대다 표현 시 근본적으로 관계형 데이터베이스와 다르지 않다
- 서로를 고유한 식별자로서 참조하는데 관계형 모델에서는 외래키, 문서 모델에서는 문서참조(document reference)라고 부른다
- 이 식별자들은 조인이나 후속 질의를 사용해 읽기 시점에 확인한다
데이터 모델의 차이점으로서 관계형 데이터베이스와 문서 데이터베이스
- 문서 데이터베이스
- 스키마 유연성, 지역성(Locality)에 기인한 더 나은 성능
- 관계형 데이터베이스
문서 모델에서의 스키마 유연성(SchemaLess vs Schema)
- 쓰기 스마키(Scema-On-Write)
- 정적 타입의 느낌
- 관계형 데이터베이스의 전통적인 접근방식
- 스키마는 명시적이고 데이터베이스는 쓰여진 모든 데이터가 스키마를 따르고 있음을 보장
- 읽기 스키마(Scema-On-Read)
- 동적 타입의 느낌
- 데이터 구조가 데이터를 읽을때 해석됨
- 데이터가 모두 동일한 구조가 아닐 때 유리함
- 문서 데이터베이스일때 데이터 타입이 변경된 경우
- 새로운 필드가 추가된 경우 필드가 추가된 채로 새 문서를 작성하면 된다
- 예전 데이터 타입인 경우 예전 구조를 읽는 코드를 추가하면 된다
- 관계형 데이터베이스일때 데이터 타입이 변경된 경우
- 스키마 변경이 필수적
- MySQL의 경우 ALTER TABLE을 할 시에 전체 테이블을 복사하기 때문에 테이블의 구조가 매우 크다면 시간이 오래 걸릴 수 있음
데이터를 위한 질의 언어
- SQL은 선언형 질의 언어인 반면 IMS와 코다실은 명령형 코드를 사용하여 데이터베이스의 질의한다
- 명령형 코드
- 순서대로 어떤 연산을 수행하게끔 컴퓨터에 지시함
- 명령어를 특정 순서로 수행하게끔 지정하기 떄문에 병렬 처리가 어렵다
- 선언형 질의
- 알고자 하는 데이터 패턴에 해당하는 조건, 데이터를 어떻게 변환(정렬, 그룹화, 집계) 할지를 지정함
- 어떤 색인(index) 어떤 조인(join) 함수를 사용하고 어떤 순서로 실행할지는 질의 최적화기(query optimizer)가 결정함
- 결과를 결정하기 위한 알고리즘을 지정하는게 아니라 결과의 패턴만 지정하기 때문에 병렬 실행으로 성능이 좋아질 가능성이 크다