본문 바로가기
CS/데이터베이스

[면접을 위한 CS 전공지식 노트] 데이터베이스

by merona99 2023. 7. 7.
반응형

chapter 4) 데이터베이스


SECTION1 데이터베이스의 기본

데이터베이스(DB, DataBase) : 일정한 규칙, 규약을 통해 구조화되어 저장되는 데이터의 모음

DBMS(DataBase Management System) : 해당 데이터베이스를 제어, 관리하는 통합 시스템

 

데이터베이스와 dbms

  • ex) DMBS(mysql), 응용 프로그램(Node.js, php)

 

1. 엔터티(entity)

  • 사람, 장소, 물건, 사건, 개념 등 여러 개의 속성을 지닌 명사
  • ex) 엔터티(회원), 속성(이름, 아이디, 주소, 전화번호)

 

약한 엔티티와 강한 엔티티

  • A가 혼자서 존재하지 못하고 B의 존재 여부에 따라 종속적이라면 A는 약한 엔티티, B는 강한 엔티티
  • ex) 약한 엔티티(방), 강한 엔티티(건물)

2. 릴레이션(relation)

  • 데이터베이스에서 정보를 구분하여 저장하는 기본 단위
  • 엔터티에 관한 데이터를 데이터베이스는 릴레이션 하나에 담아서 관리
  • ex) 데이터베이스에서 관리되는 엔터티(회원) -> 릴레이션(테이블(rmdbs), 컬렉션(NoSQL))

3. 속성(attibute)

  • 릴레이션에서 관리하는 구체적이며 고유한 이름을 갖는 정보

4. 도메인(domain)

  • 릴레이션에 포함된 각각의 속성들이 가질 수 있는 값의 집합
  • ex) 속성(성별), 도메인(남,여)

5. 필드와 레코드

  • 필드 : 속성 중 데이터베이스의 컬럼값이 되는 것
  • 레코드 : 테이블에 쌓이는 행(row) 단위의 데이터

필드 타입 종류

타입 종류
숫자 TYNYINT(1), SMALLINT(2), MEDIUMINT(3), INT(4), BIGINT(8)
날짜 DATE(날짜O시간X, 3), DATETIME(날짜O시간O, 8), TIMESTAMP(날짜O시간O, 4)
문자 CHAR(고정), VARCHAR(가변), TEXT, BLOB(이미지, 동영상의 파일 경로), ENUM, SET

ENUM : 단일 선택만 가능하며 x-small 등이 0,1 등으로 매핑되어 메모리를 적게 사용한다는 이점이 있음

SET : 다중 선택이 가능하고 비트 단위의 연산을 할 수 있으며 최대 64개의 요소를 넣을 수 있음

 


6. 관계

관계화살표

1:1 관계

  • 유저 - 유저 이메일
  • 한 유저는 고유의 이메일을 가지고 있음

 

1:N 관계 (일대다 관계)

  • 유저(장바구니) - 상품
  • 한 유저당 여러 개의 상품을 장바구니에 넣을 수 있음

 

N:M 관계

  • 학생 - 강의
  • 학생도 강의를 많이 들을 수 있고 강의도 여러 명의 학생을 포함할 수 있음

7. 키

  • 테이블 간의 관계를 조금 더 명확하게 하고 테이블 자체의 인덱스를 위해 설정된 장치
  • 종류 : 기본키, 외래키, 후보키, 슈퍼키, 대체키

유일성 : 중복되는 값이 없는 것

최소성 : 필드를 조합하지 않고 최소 필드만 써서 키를 형성할 수 있는 것

 

기본키(PK, Primary Key) : 유일성과 최소성을 만족하는 키

자연키 인조키(일반적으로 사용)
중복된 값들을 제외하며 중복되지 않는 것을 '자연스레' 뽑다가 나오는 키
언제가는 변하는 속성을 가짐
인위적으로 생성한 고유 식별자(sequence, auto increment)
변하지 않음

외래키(FK, Foreign Key) : 다른 테이블의 기본키를 그대로 참조하는 값으로 개체와의 관계를 식별하는 데 사용

 


SECTION2 ERD와 정규화 과정

 

ERD(Entity, Relationship Diagram) : 데이터베이스를 구축할 떄 가장 기초적인 뼈대 역할을 하며, 릴레이션 간의 관계들을 정의한 것

 

1. ERD의 중요성

  • 서비스를 구축할 때 가장 먼저 신경 써야 할 부분
  • 관계형 구조로 표현할 수 있는 데이터를 구성하는 데 유용할 수 있지만 비정형 데이터를 충분히 표현할 수 없다는 단점

2. 예제로 배우는 ERD

 

요구사항

  • 영업사원은 0~N명의 고객을 관리한다.
  • 고객은 0~N개의 주문을 넣을 수 있다.
  • 주문에는 1~N개의 상품이 들어간다.

정답

승원 영업부서의 ERD


3. 정규화 과정

릴레이션 간의 잘못된 종속 관계로 인해 데이터베이스 이상 현상이 일어나서 이를 해결하거나, 저장 공간을 효율적으로 사용하기 위해 릴레이션을 여러 개로 분리하는 과정

 

데이터베이스 이상 현상 : 회원이 한 개의 등급을 가져야 하는데 세 개의 등급을 갖거나 삭제할 때 필요한 데이터가 같이 삭제되고, 데이터를 삽입해야 하는데 하나의 필드 값이 NULL이 되면 안 되어서 삽입하기 어려운 현상

 

정규형 원칙

  • 같은 의미를 표현하는 릴레이션 이지만 좀 더 좋은 구조로 만들어야 할 것
  • 자료의 중복성은 감소해야 함
  • 독립적인 관계는 별개의 릴레이션으로 표현해야 하며, 각각의 릴레이션을 독립적인 표현이 가능해야 하는 것

 

정규형 내용
제1정규형 릴레이션의 모든 도메인이 더 이상 분해될 수 없는 원자 값만으로 구성되어야 함
반복 집합이 있다면 제거해야 함
제2정규형 릴레이션이 제1정규형이며 부분 함수의 종속성을 제거한 형태
제3정규형 제2정규형이고 기본키가 아닌 모든 속성이 이행적 함수 종속(transitive FD)을 만족하지 않는 상태

부분 함수의 종속성 : 기본키가 아닌 모든 속성이 기본키에 완전 함수 종속적인 것

이행적 함수 종속 : A->B, B->C 이면 논리적으로 A->C가 성립할 때 집합 C가 집합 A에 이행적으로 함수 종속이 되었다고 함

 


SECTION3 트랜잭션과 무결성

트랜잭션

  • 데이터베이스에서 하나의 논리적 기능을 수행하기 위한 작업의 단위
  • 데이터베이스에 접근하는 방법은 쿼리이므로, 즉 여러 개의 쿼리들을 하나로 묶는 단위
  • ACID 특징 : 원자성, 일관성, 독립성, 지속성

 

1. 원자성(atomicity)

"all or nothing"

  • 트랙잭션과 관련된 일이 모두 수행되었거나 되지 않았거나를 보장하는 특징
  • 트랜잭션을 커밋했는데, 문제가 발생하여 롤백하는 경우 그 이후에 모두 수행되지 않음을 보장하는 것
  • 트랜잭션 단위로 여러 로직들을 묶을 때 외부 api를 호출하는 것이 있으면 안됨

커밋과 롤백

커밋(commit) : 여러 쿼리가 성공적으로 처리되었다고 확정하는 명령어

  • 트랜잭션 단위로 수행되며 변경된 내용이 모두 영구적으로 저장되는 것
  • "커밋이 수행 되었다." = "하나의 트랜잭션이 성공적으로 수행되었다."

롤백(rollback) : 트랜잭션으로 처리한 하나의 묶음 과정을 일어나기 전으로 돌리는 일(취소)

  • 커밋과 롤백 덕에 데이터의 무결성이 보장됨
  • 데이터 변경 전에 변경 사항을 쉽게 확인할 수 있고 해당 작업을 그룹화할 수 있음

 

2. 일관성(consistency)

  • '허용된 방식'으로만 데이터를 변경해야 하는 것
  • 데이터베이스에 기록된 모든 데이터는 여러 가지 조건, 규칙에 따라 유효함을 가져야 함
  • ex) 0원인 통장에서 500만원을 입금할 수 없음

 

3. 격리성(isolation)

  • 트랜잭션 수행 시 서로 끼어들지 못하는 것
  • 복수의 병렬 트랜잭션은 서로 격리되어 마치 순차적으로 실행되는 것처럼 작동되어야 하고, 데이터베이스는 여러 사용자가 같은 데이터에 접근할 수 있어야 함

위로 갈수록 동시성이 강해지고 아래로 갈수록 격리성이 강해짐

 

격리 수준에 따라 발생하는 현상

팬턴 리드(phantom read) 한 트랜잭션 내에서 동일한 쿼리를 보냈을 때 해당 조회 결과가 다른 경우
반복 가능하지 않은 조회(non-repeatable table) 한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 다른 경우
더티 리드(dirty read) 반복 가능하지 않은 조회와 유사하며 한 트랜잭션이 실행 중일 때 다른 트랜잭션에 의해 수정되었지만 아직 '커밋되지 않은' 행의 데이터를 읽을 수 있을 때 발생

 

격리수준

SERIALIZABLE 트랜잭션을 순차적으로 진행시키는 것
여러 트랜잭션이 동시에 같은 행에 접근할 수 없음
매우 엄격한 수준으로 해당 행에 대해 격리시키고, 이후 트랜잭션이 이 행에 대해 일어난다면 기다려야 함
교착 상태가 일어날 확률도 많고 가장 성능이 떨어지는 격리 수준
REPEATABLE_READ 하나의 트랜잭션이 수정한 행을 다른 트랜잭션이 수정할 수 없도록 막아주지만 새로운 행을 추가하는 것은 막지 않음
READ_COMMITTED 가장 많이 사용되는 격리 수준이며 MySQL, PostgreSQL, SQL Server, 오라클의 기본값
READ_UNCOMMITTED와 달리 다른 트랜잭션이 커밋하지 않은 정보는 읽을 수 없음
어떤 트랜잭션이 접근한 행을 다른 트랜잭션이 수정할 수 있음
READ_UNCOMMITTED 가장 낮은 격리 수준으로, 하나의 트랜잭션이 커밋되기 이전에 다른 트랜잭션에 노출되는 문제가 있지만 가장 빠름
데이터 무결성을 위해 되도록 사용하지 않는 것이 이상적이나, 몇몇 행이 제대로 조회되지 않더라도 괜찮은 거대한 양의 데이터를 '어림잡아' 집계하는 데는 사용하면 좋음

 

※ 장고의 격리수준

더보기

Q) 장고의 격리수준은?

  • Django는 데이터베이스 관리 시스템(DBMS)에 따라 다양한 격리 수준을 지원함
  • Django 자체에는 기본 격리 수준이 정의되어 있지 않으며, 사용하는 데이터베이스 엔진의 기본 격리 수준을 따름
  • SQLite : 기본적으로 serializable 격리수준을 사용

 

 

4. 지속성(durability)

  • 성공적으로 수행된 트랜잭션은 영원히 반영되어야 하는 것을 의미함
  • 이는 데이터베이스에 시스템 장애가 발생해도 원래 상태로 복구하는 회복 기능이 있어야 함

※체크섬 : 중복 검사의 한 형태로, 오류 정정을 통해 송신된 자료의 무결성을 보호하는 단순한 방법

※저널링 : 파일 시스템 또는 데이터베이스 시스템에 변경 사항을 반영(commit)하기 전에 로깅하는 것, 트랜잭션 등 변경 사항에 대한 로그를 남기는 것

 


무결성

  • 데이터의 정확성, 일관성, 유효성을 유지하는 것
  • 무결성이 유지되어야 데이터베이스에 저장된 데이터 값과 그 값에 해당하는 현실 세계의 실제 값이 일치하는지에 대한 신뢰가 생김
이름 설명
개체 무결성 기본키로 선택된 필드는 빈 값을 허용하지 않음
참조 무결성 서로 참조 관계에 있는 두 테이블의 데이터는 항상 일관된 값을 유지해야 함
고유 무결성 특정 속성에 대해 고유한 값을 가지도록 조건이 주어진 경우 그 속성 값은 모두 고유한 값을 가짐
NULL 무결성 특정 속성 값에 NULL이 올 수 없다는 조건이 주어진 경우 그 속성 값은 NULL이 될 수 없다는 제약 조건

 


SECTION4 데이터베이스의 종류

관계형 데이터베이스(RDBMS) : 행과 열을 가지는 표 형식 데이터를 저장하는 형태의 데이터베이스를 가리키며 SQL이라는 언어를 써서 조작함

종류 : MySQL, PostgreSQL, 오라클, SQL Server, MSSQL 등

 

1. MySQL

  • 대부분의 운영체제와 호환되며 현재 가장 많이 사용하는 데이터베이스
  • C, C++로 만들어졌으며 MyISAM 인덱스 압축 기술, B-트리 기반의 인덱스, 스레드 기반의 메모리 할당 시스템, 매우 빠른 조인, 최대 64개의 인덱스를 제공함
  • 대용량 데이터베이스를 위해 설계되어 있고 롤백, 커밋, 이중 암호 지원 보안 등의 기능을 제공하며 많은 서비스에서 사용함

SECTION5 인덱스

1. 인덱스의 필요성

  • 인덱스 : 데이터를 빠르게 찾을 수 있는 하나의 장치
  • 인덱스를 설정하면 테이블 안에 내가 찾고자 하는 데이터를 빠르게 찾을 수 있음

2. B-트리

  • 인덱스는 보통 B-트리라는 자료 구조로 이루어져 있음
  • 구성 : 루트 노드, 리프 노드, 브랜치 노드(루트 노드와 리프 노드 사이에 있음)

B-트리

 

Q) 10을 찾아라

더보기

A) 트리 탐색은 맨 위 루트 노트부터 탐색이 일어나며 브랜치 노드를 거쳐 리프 노드까지 내려옴.

    '10보다 같거나 클 때까지 <='를 기반으로 첯음 루트 노드에서는 7 이후 아래 노드로 내려와 9,11 등

    정렬된 값을 기반으로 탐색하는 것을 볼 수 있음.

    이렇게 루트 노드부터 시작하여 마지막 리프 노드에 도달해서 10이 가리키는 데이터 포인트를 통해 결과값을

    반환하게 됨.

 

    순서) 7 -> 15 ->  9 -> 11 -> 10 총 5번의 탐색이 필요함.

 

Q) 리프 노드와 브랜치 노드의 차이점은?

 

Q) 리프 노드와 브랜치 노드의 최대/최소 갯수는?

 

 

인덱스가 효율적인 이유 : 효율적인 단계를 거쳐 모든 요소에 접근할 수 있는 균형 잡힌 트리 구조와 트리 깊이의 대수확장성 때문

 

※ 대수확장성 : 트리 깊이가 리프 노드 수에 비해 매우 느리게 성장하는 것을 의미함. 기본적으로 인덱스가 한 깊이씩 증가할 때마다 최대 인덱스 항목의 수는 4배씩 증가함

 

트리 깊이 인덱스 항목의 수
3 64
4 256
5 1,024
6 4,096
7 16,384
8 65,536
9 262,144
10 1,048,576

트리의 대수 확장성

 

트리 깊이 10개짜리로 100만 개의 레코드를 검색할 수 있다는 의미


3. 인덱스를 만드는 방법

 

MySQL 기준

클러스터형 인덱스와 세컨더리 인덱스가 있으며, 클러스터형 인덱스는 테이블당 하나를 설정할 수 있음

  • primary key 옵션으로 기본키 -> 클러스터형 인덱스
  • 기본키로 만들지 않고 unique not null 옵션 붙이기 -> 클러스터형 인덱스
  • create index... 명령어 기반 -> 세컨더리 인덱스
클러스터형 인덱스 사용 경우 세컨더리 인덱스 사용 경우
age라는 하나의 필드만으로 쿼리를 보내는 경우 age, name, email 등 다양한 필드를 기반으로 쿼리를 보내는 경우

 

MongoDB 기준

도큐먼트를 만들면 자동으로 ObjectID가 형성되며, 해당 키가 기본키로 설정됨

세컨더리키도 부가적으로 설정해서 기본키와 세컨더리키를 같이 쓰는 복합 인덱스를 설정할 수 있음


4. 인덱스 최적화 기법

인덱스 최적화 기법은 데이터베이스마다 조금씩 다르지만 기본적인 골조는 똑같음

 

1) 인덱스는 비용이다

  • 인덱스는 두 번 탐색하도록 강요함
  • 인덱스 리스트, 그다음 컬렉션 순으로 탐색하기 때문이며, 관련 읽기 비용이 발생함
  • 컬렉션이 수정되었을 때 인덱스도 수정되어야 함
  • 즉, 쿼리에 있는 필드에 인덱스를 무작정 다 설정하는 것은 답이 아니며 컬렉션에서 가져와야 하는 양이 많을수록 인덱스를 사용하는 것은 비효율적

 

2) 항상 테스팅하라

  • 서비스에서 사용하는 객체의 깊이, 테이블의 양 등이 다르기 때문에 인덱스 최적화 기법은 서비스 특징에 따라 달라짐
  • exlpain() 함수를 통해 인덱스를 만들고 쿼리를 보낸 이후에 테스팅을 하며 걸리는 시간을 최소화 해야함

 

3) 복합 인덱스는 같음, 정렬, 다중 값, 카디널리티 순이다

여러 필드를 기반으로 조회를 할 때 복합 인덱스 사용함

 

※ 순서

  1. ==, equal
  2. 정렬에 쓰는 필드
  3. 다중 값을 출력해야 하는 필드, >, < 등 많은 값을 출력해야 하는 쿼리에 쓰는 필드
  4. 카디널리티(유니크한 값의 정도)가 높은 순서

SECTION6 조인의 종류

조인(join) : 두 개 이상의 테이블을 묶어서 하나의 결과물을 만드는 것

여러 테이블을 조인하는 작업이 많을 경우 MongoDB 보다는 관계형 데이터베이스를 써야함 -> 조인 연산 성능이 비교적 떨어지기 때문

 

조인의 종류

 

1. 내부 조인(inner join) : 왼쪽 테이블과 오른쪽 테이블의 두 행이 모두 일치하는 행

SELECT * FROM TableA A
INNER JOIN TableB B ON
A.key = B.key

2. 왼쪽 조인(left outer join) : 왼쪽 테이블의 모든 행

SELECT * FROM TableA A
LEFT JOIN TableB B ON
A.key = B.key

3. 오른쪽 조인(right outer join) : 오른쪽 테이블의 모든 행

SELECT * FROM TableA A
RIGHT JOIN TableB B ON
A.key = B.key

4. 합집합 조인(full outer join) : 두 개의 테이블을 기반으로 조인 조건에 만족하지 않는 행까지 모두 표기

SELECT * FROM TableA A
FULL OUTER JOIN TableB B ON
A.key = B.key

SECTION7 조인의 원리

1. 중첩 루프 조인(NLJ, Nested Loop Join)

  • 중첩 for 문과 같은 원리로 조건에 맞는 조인을 하는 방법
  • 랜덤 접근에 대한 비용이 많이 증가하므로 대용량의 테이블에서는 사용x

※ 블록 중첩 루프 조인(BNL, Nlock Nested Loop) : 중첩 루프 조인에서 발전한 조인할 테이블을 작은 블록으로 나눠서 블록 하나씩 조인하는 방식

 

 

2. 정렬 병합 조인

  • 각각의 테이블을 조인할 필드 기준으로 정렬하고 정렬이 끝난 이후에 조인 작업을 수행하는 조인
  • 조인할 떄 쓸 적절한 인덱스가 없고 대용량의 테이블들을 조인하고 조인 조건으로 <, > 등 범위 비교 연산자가 있을때 사용

 

3. 해시 조인

  • 해시 테이블을 기반으로 조인하는 방법
  • 두 개의 테이블을 조인한다고 했을 떄 하나의 테이블이 메모리에 온전히 들어간다면 보통 중첩 루프 조인보다 더 효율적임

 

MySQL의 해시 조인 단계

 

1) 빌드 단계

  • 입력 테이블 중 하나를 기반으로 메모리 내 해시 테이블을 빌드하는 단계
  • 두 개의 테이블 중 바이트가 더 작은 테이블을 기반으로 해서 테이블을 빌드함 
  • 조인에 사용되는 필드해시 테이블의 키로 사용 됨

2) 프로브 단계

  • 프로브 단계 동안 레코드 읽기를 시작하며, 각 레코드에서 키와 일치하는 레코드를 찾아서 결과값으로 반환함
  • 각 테이블은 한 번씩만 읽게 되어 중첩해서 두 개의 테이블을 읽는 중첩 루프 조인보다 보통은 성능이 더 좋음
  • 사용 가능한 메모리 양은 시스템 변수 join_buffer_size에 의해 제어되며, 런타임 시에 조정할 수 있음

 

 

 


참고문서 : 면접을 위한 CS 전공지식 노트

 

반응형

'CS > 데이터베이스' 카테고리의 다른 글

[데이터베이스] 정규화  (1) 2021.10.28
[데이터베이스] 관리의 개요  (0) 2021.10.17
[데이터베이스] 기본 개념  (0) 2021.10.17

댓글