[데이터베이스] 핵심 개념
in CS
- 정규화
- 비정규화
- 트랜잭션
- ACID
- 뷰
- 인덱스
- 클러스터 인덱스 vs 비클러스터 인덱스
- 무결성
- 트리거
- 프로시져
- 커밋, 롤백
- JDBC 와 ODBC 차이
- 교착 상태
- RDBMS 와 NOSQL 차이
- 윈도우 함수
- coalesce
- FULL OUTER JOIN 과 CROSS JOIN 차이
- nested loop join, sort merge join, hash join
- 쿼리 실행 순서
- 쿼리 튜닝
- 힌트
- 컬럼 기반 포맷
정규화
- 테이블을 분할할 때 데이터 중복을 최소화
- insert,delete,update 시 이상현상 방지
- 릴레이션 분해로 JOIN 연산이 응답시간이 느려짐
비정규화
- 비정규화 데이터베이스(대규모 데이터)는 읽는 시간을 최적화하도록 설계됨
- 데이터 중복해서 저장
- JOIN 최소화
트랜잭션
- 데이터베이스의 상태를 변화시키기 위해 수행하는 논리적인 작업 단위(SQL를 통한 DB 접근)
- ACID 를 만족해야 함
ACID
- 원자성: 트랜잭션이 DB에 모두 반영되거나 전혀 반영되지 않거나(커밋 or 롤백)
- 일관성: 트랜잭션 처리 결과는 항상 일관성(글자 제한 같은 것들 만족하도록)
- 독립성: 둘 이상의 트랜잭션이 동시에 실행될 때 서로 영향을 주면 안됨
- 지속성: 커밋이 되면 그 결과는 영구적으로 반영. 장애에도 견디도록
뷰
하나 이상의 테이블에서 유도된 가상 테이블 허용된 데이터를 제한적으로 보여주기 위한 것(권한 별로 보여주는 데이터 구분) 별도 저장이 필요치 않음
인덱스
- 검색 속도를 높이기 위해 사용
- B+ 트리나 해시인덱스 사용
- 데이터가 정렬되어 디스크에 들어감
- 테이블의 컬럼을 인덱스화하면, Full scan 하지 않고 B+ tree 구조를 통해 향상된 속도로 검색
- 사용하면 좋은 경우: 검색이 빈번한 경우. where 절, 외래키, join 에 자주 사용되는 컬럼
- 피해야 하는 경우: 데이터 중복이 높은 컬럼. DML 이 자주 일어나는 컬럼(인덱스 재작성)
클러스터 인덱스 vs 비클러스터 인덱스
- 클러스터 인덱스: 테이블 당 하나만 생성. 인덱스로 지정된 컬럼으로 row 정렬(물리적으로 재배열). 테이블 자체가 인덱스
- 비클러스터 인덱스: 테이블 당 여러개 생성. 원본은 정렬안되고 인덱스 페이지만 정렬
무결성
- 데이터의 정확성, 일관성, 유효성을 가지게 하는 것
- PK는 널이 아님. 참조 관계는 항상 일치. 자료형 일치 등
트리거
- 자동으로 실행되도록 정의된 프로시저(insert, delete, update 이전 혹은 이후 자동으로 호출)
- 업무 규칙 보장, 자동화, 무결성 강화
프로시져
사전에 컴파일된 SQL 쿼리 모음
커밋, 롤백
- 커밋: 정상적으로 처리되어 트랜잭션이 반영됨
- 롤백: 트랙잭션 처리가 비정상 종료되어 DB 일관성을 깨뜨렸을 때 모든 연산을 취소시키는 연산
JDBC 와 ODBC 차이
- JDBC 는 자바에서 DB에 접근하는데 사용
- ODBC 는 응용프로그램에서 DB 접근하기 위한 표준 인터페이스(MS 가 개발)
교착 상태
- 2개 이상의 트랜잭션이 특정 자원(테이블 혹은 컬럼)의 lock 을 획득하고 다른 트랜잭션의 lock 를 요구하는 상황
- 방지하는 법: 트랜잭션을 자주 커밋. 정해진 순서로 테이블 접근. SELECT ~ FOR UPDATE 사용 피함
RDBMS 와 NOSQL 차이
- NOSQL은 스키마가 없음(비정형 데이터 저장에 적합)
- 관계가 없으니 JOIN도 없음
- 분산처리에 용이 (scale out)
윈도우 함수
- 행과 행 간 관계를 정의하기 위한 함수
- 순위, 합계, 평균 등
coalesce
복수의 인자들을 입력했을 때 순차적으로 NULL이 아닌 인자 값을 리턴
FULL OUTER JOIN 과 CROSS JOIN 차이
FULL OUTER JOIN 은 조건에 대한 로직이 들어가는데, CROSS JOIN 은 그냥 카테시안 프로덕트(모든 경우의 수)
nested loop join, sort merge join, hash join
- nested loop join: 두개 테이블 행을 각각 모두 확인하여 조인. 중첩 for 문이랑 비슷. 행이 적은 테이블을 driving 테이블로 선정하는 것이 좋음. 조인 컬럼에 인덱스가 있어야 효율적
- sort merge join: 조인 컬럼으로 정렬한 후 조인함. 정렬하기 때문에 인덱스를 사용한것과 비슷한 효과. 인덱스가 없는 컬럼에 유리
- hash join: 대용량 데이터에서 많이 사용. 일반적으로 위 2개 보다 빠름. hash table 을 사용하여 탐색 조인. outer table 이 충분히 작고 (hash table 생성), 중복 컬럼이 없어야함(해시 충돌)
쿼리 실행 순서
FROM-WHERE-GROUP BY-HAVING-SELECT-ORDER BY
쿼리 튜닝
- 분산 db든 아니든 가장 중요한 것 지역성을 높이는 것(디스크면 순차 io, 분산 db면 셔플 최소화)
- 인덱스 컬럼에는 가급적 = 사용 (LIKE 는 느림)
- HAVING 보단 WHERE 에서 필터링(쿼리 순서 상)
- DISTINCT 는 내부적으로 정렬 작업을 수반하므로 최대한 자제
- UNION 대신 UNION ALL 사용(UNION 은 정렬과 중복 제거 기능이 있음)
- 임시 테이블 활용(JOIN 전에 임시테이블로 어느정도 필터링 한후 JOIN)
- nested view 는 성능 저하 원인. 최대한 자제
힌트
- SQL을 튜닝하기 위한 지시 구문
- optimizer 보다 나은 성능을 내기 위해 사용
- 보통 조인에서 많이 사용(NL, MERGE, HASH 등)
컬럼 기반 포맷
- 일반적인 db는 레코드 단위로 읽고 쓰는 것에 최적화
- 각 행을 하나의 덩어리로 디스크에 저장
- 컬럼단위로 압축 및 저장하게 되면 필요한 컬럼만 읽을 수 있어서 빠름
- 유사한 데이터를 모아서 저장하기 때문에 압축률도 좋음
- 대신 대규모 업데이트나 삽입은 오래 걸림
- 대표적으로 파케이랑 orc 가 있음(파케이는 임팔라, 스파크 등에 최적화, orc 는 hive 에 최적화)