Database
title: “[데이터베이스] 데이터베이스 기본 개념 “ date: 2019-05-21 15:05:28 -0400 categories: jekyll update —
데이터베이스
- 데이터베이스에서 Null 의 의미?
- missing
- unknown
- doesn’t apply
- 쿼리 실행 절차(출처)
- 사용자로부터 요청된 SQL 문장을 잘게 쪼개서 MySQL 서버가 이해할 수 있는 수준으로 분리한다. (SQL 파싱)
- SQL의 파싱 정보(파스 트리)를 확인하면서 어떤 테이블부터 읽고 어떤 인덱스를 이용해 테이블을 읽을지 선택한다.
- 두번째 단계에서 결정된 테이블의 읽기 순서나 선택된 인덱스를 이용해 스토리지 엔진으로부터 데이터를 가져온다.
- 트랜잭션 동작 원리(출처)
- 저장 프로시저의 동작 원리
- 쿼리의 반응속도를 빠르게 하려면 어떻게 해야 하나?
- Key
- 릴레이션의 후보키(candiate key)를 구성하는 속성들을
prime attribute
라고 한다. 나머지 attribute 들은non prime attribute
이다.
- 릴레이션의 후보키(candiate key)를 구성하는 속성들을
- 정규화
- 1NF tuple 의 유일성 attribute 의 원자성
- 2NF 모든 비주요 애트리뷰트가 주요 애트리뷰트에 대해서 완전 함수적 종속 키가 아닌 컬럼들이 각각의 후보키에 대해 결정되는 릴레이션 형태 if all of its nonkey attributes are dependent on all of the primary keys.
- 3NF has no determinants except the primary key 이행적 종석성 제거된 형태(비주요 애트리뷰트가 비주요 애트리뷰트에 의해 종속되는 경우가 없는 릴레이션 형태)
- BCNF if every determinant is a candiate key.
- 4NF MVD 가 table 당 1개씩만
-
인덱스 컬럼의 값과 해당 레코드가 저장된 주소를 키와 값의 쌍으로 인덱스를 만들어 두는 것이다. 인덱스는 항상 정렬된 상태를 유지하기 때문에 원하는 값을 탐색하는데는 빠르지만, 새로운 값을 추가하거나 삭제, 수정하는 경우에는 쿼리문 실행 속도가 느려진다.(정렬때문인가?) 인덱스는 데이터의 저장 성능을 희생하고, 대신 데이터의 읽기 속도를 높이는 기능이다.
인덱스에 걸리는 컬럼의 수가 많아질 수록 데이터 저장 성능이 떨어지고(why?), 인덱스의 크기가 비대해져서 오히려 역효과를 불러올 수 있다.
-
왜 인덱스에 b-tree 나 b+-tree 를 사용할까요? 하드 드라이브 같은 블록 디바이스에 저장된 데이터를 사용하기 위해서 최적화 된 자료구조이다. 반면 BST는 RAM 에 있는 자료구조를 위해 설계되고 최적화된 것이다. BST는 본질적으로 느립니다. 자가 균형을 하지도 않습니다.
- 적합하지 않은 곳은?(출처)
- 읽기보다 쓰기 작업이 많이 발생하는 테이블.
- 카디널리티(중복도..)가 낮은, 즉 한 필드 내에서 중복되는 값의 개수가 적은 필드라면 사용하지마라. O(logN)의 성능을 살리려면 높은 카디널리티 필드에 대해 인덱스를 활용해야 한다.
- 작고 고정된 크기의 테이블에 사용하지마라.
- Composite Index(출처)
-
- 레코드 삭제는 fragmentation을 일으킬 수 있다.
2가지 종류의 fragmentation
- logical fragmentation
- low page density
-
delete 문은 DML 이고,
truncate
문은 DDL이다. DML에 대해서만 rollback segments 가 사용된다. delete 는 트랜잭션을 발생시키고, 트랜잭션 로그를 남긴다.truncate
는 트랜잭션을 남기지 않고, 데이터 딕셔너리를 직접 지운다. 트랜잭션 로그를 남기지 않는다.HWM
(High Water Mark)(참고1, 참고2) -
클러스터링 vs 리플리케이션(출처1) 자동 fail over 나 active stanby 기능… 즉, 1분1초라도 서비스가 멈춰지질 원하지 않는다면 클러스터 리플리케이션은 문제 발생시 단독서버에 비해서 복구가 빠르지만 클러스터에 비하면 서비스가 멈춰 있는 시간이 발생하고 자동 fail over 기능도 없다. 클러스터는 동기화 방식, 리플리케이션은 비동기화 방식이다. 따라서, 리플리케이션은 일방적으로 데이터를 전달하여 복제를 하지만, 클러스터는 데이터를 복제한 후 결과를 확인하기 때문에 데이터 누락이 발생하지 않는다.
-
Query off Loading 처리량을 증가시키기 위한 설계 기법 DB 트랜잭션의 70~90%는 대부분 읽기와 관련된 것이다. 나머지 10~30% 가 create/delete/update와 같은 트랜잭션인데, 이 update 트랜잭션과 read 트랜잭션을 분리하는 기법이다.
- Master -> Staging -> Slave 로의 복제는 어떤 기술을 사용할까? CDC(Change Data Capture)
DBMS 들은 공통으로 C/U/D 와 같은 쓰기 관련 작업을 수행할 때, 데이터를 실제로 저장하기 전에 먼저 해당 작업에 대한 요청을
백로그
라는 곳에 저장한다.(백로그는 일반적으로 로컬 파일임) 이는 실제로 데이터를 쓰기 전에 장애가 났을 때, 재시작하면서 이 백로그를 읽어서 복구를 위한 용도로 사용된다.CDC
는 이 백로그를 이용해서 데이터를 복제하는데, Source DB로부터 이 백로그를 읽어서 복제하고자 하는 대상 DB에 Replay 하는 형식이다.
- Master -> Staging -> Slave 로의 복제는 어떤 기술을 사용할까? CDC(Change Data Capture)
DBMS 들은 공통으로 C/U/D 와 같은 쓰기 관련 작업을 수행할 때, 데이터를 실제로 저장하기 전에 먼저 해당 작업에 대한 요청을
-
샤딩(Sharding) 데이터베이스의 용량 한계를 극복하기 위한 기술이다. 데이터를 여러 개의 데이터베이스에 나눠 담는 방법이다.
- 수직적(Vertical) 샤딩 연속된 데이터에 대해서 범위 별로 데이터를 나누는 방법 ex) 10대, 20대, … , 80 대의 연령대별로 나누기
- 수평적(Horizontal) 샤딩 연속된 키가 아니라 ‘Category’와 같은 종류에 따라서 데이터를 수평적으로 분리하는 방법이다. ex) Korea, US, … , China
이와 같이 의미 있는 데이터를 사용하는 것은
데이터의 몰림 현상
이라는 것이 발생할 수 있다. 데이터 몰림 현상을 고려하여각 샤드 서버의 성능을 비대칭적으로 설계
할 수 있다. 데이터가 몰리는 20대, 30대의 샤드에 더 좋은 CPU와 메모리를 갖는 서버를 배치하는 것이다.만약, 데이터 편중 현상에 대한 예측이 어렵다면? 의미 없는 키를 사용해서 샤딩을 할 수 있다. 레코드를 등록할 때 키를 시퀀스를 이용해서 차례대로 부여한다. 그리고 이 키 값을 10으로 나눈 나머지 값을 가지고 샤드를 결정하면 데이터를 모든 샤드에 걸쳐서 골고루 분산시켜 배치할 수 있다.(해시방식)
샤딩을 구현하는 방법은?
- DBMS 단에서 샤딩을 지원하는 방법 ex. Azure 페더레이션 모델, MongoDB(1.6부터) 지원하는 DB 수준 샤딩
- OR Mapper와 같은 DB 접근용 프레임워크에서 샤딩을 제공하는 방법 es. Hibernate Shard
- 애플리케이션 코드 자체에서 지원하는 방법 키에 따라서 DB 인스턴스를 선택적으로 고를 수 있는 구조를 갖게 하기. 다른 샤드 간의 join 등은 불가능하기 때문에 구현할 때 이에 대한 고려가 필요하다.
결론. 애플리케이션의 복잡도가 올라가고 데이터가 편중되는 것을 방지하는 등 여러 가지 요소를 고려한 후에 설계, 반영해야 한다.