[CS지식] 데이터베이스

5tr1ker·2023년 1월 25일
0

CS 지식

목록 보기
3/6
post-thumbnail

데이터베이스

일정한 규칙 , 혹은 규약을 통해 구조화되어 저장되는 데이터의 모음입니다. 해당 데이터베이스를 제어, 관리하는 통합 시스템를 DBMS라고 하며 데이터베이스 안에있는 데이터들은 특정 DBMS마다 정의된 쿼리 언어를 통해 생성 , 조회 , 수정 , 삭제를 할 수 있습니다. 또한 데이터베이스는 실시간 접근 , 동시 공유가 가능합니다.

엔터티

사람 , 장소 , 물건 등 여러 개의 속성을 지닌 명사를 의미하며 약한 엔터티와 강한 엔터티로 나뉩니다.

약한 엔터티와 강한 엔터티

만약 A과 혼자서 존재하지 못하고 B의 존재 여부에 따라 종속적이라면 A는 약한 엔터티이고 , B는 강한 엔터티가됩니다.

릴레이션

데이터베이스에서 정보를 구분하여 저장하는 기본 단위입니다. 엔터티에 관한 데이터는 릴레이션 하나에 담아서 관리하며 관계형 데이터베이스에서는 테이블이라 부릅니다.

속성

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

도메인

릴레이션에 포함된 각각의 속성들이 가질 수 있는 값의 집합을 말합니다.

레코드 ( 튜플 )

릴레이션에서 행 단위로 쌓이는 데이터를 말합니다.

필드

추후 추가 예정

필드 타입

  • 숫자 타입 : tinyint , smallint , mediumint , int , bigint
  • 날짜 타입 : date , datetime , timestamp ( datetime은 8바이트 , timestamp는 4바이트로 사용할 수 있는 날짜 범위가 다릅니다. )
  • 문자 타입 : char , varchar , text , blob , enum , set
    - char : 고정 길이 문자열로 설정한 길이 값으로 고정해서 저장합니다.
    -varchar : 가변 길이 문자열로 입력된 데이터의 길이에 맞춰 저장합니다.
    따라서 유동적이지 않은 길이의 문자열이면 char이 효율적이고 , 유동적인 길이라면 varchar 로 저장하는것이 좋습니다.
  • text : 큰 문자열을 저장할 때 쓰이며 게시판의 본문을 저장할 때 씁니다.
  • blob : 이미지나 동영상을 저장할 때 사용하지만, 보통 AWS S3 을 이용해 파일을 올리고 경로를 varchar 에 저장합니다.
  • enum : 열거형이며 , 단일 선택만 가능하고 목록에 없는 값일경우 빈 문자열이 삽입됩니다. 또한 메모리를 적게 사용하는 이점이 있습니다.
  • set : enum과 비슷하지만 여러 개의 데이터를 선택할 수 있으며 비트 단위의 연산을 할 수 있습니다.
    @ enum과 set은 모두 공간적으로 이점을 볼 수 있지만 어플리케이션을 수정할 때 목록을 수정해야 한다는 단점이 있습니다.

관계

1 : 1

1 : 1 관계는 테이블을 두 개로 나눠 테이블의 구조를 쉽게 이해하게 만들어줍니다.

1 : N 과 N : N

1 : N 은 한 개체가 다른 많은 개체를 포함하는 관계를 말합니다.
N : N 은 서로 많은 개체를 포함하는 관계이지만 , 두개의 테이블을 직접 연결하지 않고 , 1 : N , 1 : M 관계를 갖는 두개의 테이블로 나눕니다.

테이블간의 관계를 조금 더 명확하게 해주고 , 테이블 자체의 인덱스를 위해 설정하는 장치입니다. 이때 값이 중복되지 않은 유일성과 최소 필드만 사용해 키를 형성하는 최소성이 있습니다.

기본키

PK 또는 프라이머리키라고 하며 유일성과 최소성을 만족하는 키입니다. 테이블의 데이터 중 고유하게 존재해야 합니다. 이때 중복되는 값을 제외하는 과정에서 중복되지 않은 것을 자연스럽게 선택하는 자연키 와 인위적으로 키를 생성하는 인조키로 나뉩니다. 이때 자연키는 언젠가 변하는 속성을 가지며 , 인조키는 변하지 않아 보통 기본키를 인조키로 설정합니다.

외래키

다른 테이블의 기본키를 그대로 참조하는 값으로 , 개체와의 관계를 식별하는데 사용되며 중복을 허용합니다.

후보키

기본키가 될 수 있는 후보들이며 유일성과 최소성을 동시에 만족합니다.

대체키

후보키가 두 개 이상일 때 기본키로 지정하고 남은 후보키입니다.

슈퍼키

각 레코드에서 유일하게 식별할 수 있는 유일성을 갖춘 키 입니다.

ERD

데이터베이스를 구축할 때 가장 기초적인 뼈대 역할을 하며 , 릴레이션간의 관계들을 정의한 것입니다. 구축한 후 디버깅 , 재설계가 필요한 경우에 설계도 역할을 담당합니다. 하지만 관계형 구조로 표현할 수 있는 데이터를 구성하는데 유용하지만 , 비정형 데이터는 충분히 표현할 수 없는 단점이 있습니다.

정규화 과정

릴레이션 간의 잘못된 종속 관계로 인해 데이터베이스에 이상 현상이 발생해 이를 해결하거나 , 저장 공간을 효율적으로 사용하기 위해 릴레이션을 여러 개로 분리하는 과정입니다. 정규화 과정은 정규형 원칙을 기반으로 정규형을 만드는 과정으로 , 정규화된 정도는 정규형으로 표현합니다. 기본 정규형은 밑의 4가지가 있습니다.

정규형 원칙

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

제 1 정규형

릴레이션의 모든 도메인은 더 이상 분해될 수 없는 원자 값으로 구성되어야 하며 , 한 개의 기본키에 두 개 이상의 값을 가지는 반복집합은 안된다.

제 2 정규형

릴레이션이 제 1 정규형이며 부분 함수의 종속성을 제거한 형태를 말합니다. 부분 함수의 종속성 제거란 기본키가 아닌 모든 속성이 기본키에 완전 함수 종속적인 것을 말합니다. 이때 릴레이션은 동등한 릴레이션으로 분해해야하고 , 정보 손실이 발생하지 않아야 합니다.

제 3 정규형

제 2 정규형이며 기본키가 아닌 모든 속성이 이행적 함수 종속을 만족하지 않아야 합니다. 이행적 함수 종속은 A 와 B 가 연결되고 , B 와 C가 연결되었다면 논리적으로 A와 C는 연결되어 있는데 이때 C가 A에 이행적으로 함수 종속이 되었다고 합니다.

보이스/코드 정규형

제 3 정규형이고 , 결정자가 후보키가 아닌 함수 종속 관계를 제거하여 릴레이션의 함수 종속 관계에서 모든 결정자가 후보키인 상태를 말합니다.

트랜잭션

데이터베이스에서 하나의 논리적 기능을 수행하기 위한 작업의 단위를 말하며 , 데이터베이스에 접근하는 방법은 쿼리이므로 , 여러 개의 쿼리를 하나로 묶는 단위를 말합니다. 이에 특징은 원자성 , 일관성 , 독립성 , 지속성이 있으며 하나로 ACID 특징이라고 합니다.

원자성

트랜잭션과 관련된 일이 모두 수행되었거나 되지 않았거나를 보장하는 특징입니다. 예를 들어 트랜잭션을 커밋했는데 문제가 발생하여 롤백하는 경우 이후에 모두 수행되지 않는 것을 말합니다.

커밋

트랜잭션 단위로 수행이 성공적으로 처리되어 변경된 내용이 모두 영구적으로 저장되는 것을 말합니다.

롤백

트랜잭션 단위로 수행이 일어나기 전으로 돌리는 것을 말합니다.

트랜잭션 전파

매 호출마다 커넥션 객체를 넘기는 작업을 최소화 하기위해, 여러 트랜잭션 관련 메서드들을 하나의 트랜잭션으로 묶는것을 말합니다.

커밋과 롤백때문에 데이터 무결성이 보장됩니다.

일관성

허용된 방식으로만 데이터를 변경해야 하는 것을 말하며 , 데이터베이스에 기록된 모든 데이터는 여러 가지 조건 , 규칙에 따라 유효함을 가져야 합니다.

격리성

트랜잭션 수행시 서로 끼어들지 못하게 하는것을 말하며 , 여러 트랜잭션들은 서로 격리되어 순차적으로 실행되는 것처럼 작동되어야 합니다. 격리성은 여러 개의 격리 수준으로 나뉘어 격리성을 보장합니다.

격리 수준

  • Serializable : 가장 높은 격리 수준으로 트랜잭션을 순차적으로 진행시키는 것을 말하며 , 여러 트랜잭션이 동시에 같은 행에 접근할 수 없어 , 교착 상태가 일어날 확률이 높고 성능이 가장 떨어집니다.
  • Repeatable_read : 한 트랜잭션이 수정한 행을 다른 트랜잭션이 수정할 수 없게 막아주지만 새로운 행이 추가되는 것은 막지않아 팬텀 리드가 발생할 수 있습니다.
  • Read_Committed : 가장 많이 사용하는 격리 수준으로 다른 트랜잭션이 커밋하지 않은 정보는 읽을 수 없으며 , 커밋 완료된 데이터만 조회할 수 있습니다. 팬텀 리드반복 가능하지 않은 조회가 발생할 수 있습니다.
  • read_Uncommitted : 가장 낮은 격리 수준으로 한 트랜잭션이 커밋하기 전에 다른 트랜잭션에 노출될 수 있지만 가장 빠릅니다. 팬텀 리드반복 가능하지 않은 조회 , 더티 리드 가 발생할 수 있습니다.
    (방대한 양으로 어림잡아 집계 낼때 사용해도 괜찮습니다.)

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

  • 팬텀 리드 (Phantom Read) : 한 트랜잭션 내 동일한 쿼리를 보냈을 때 조회 결과가 다른것을 말합니다.
  • 반복 가능하지 않은 조회 ( non-repeatable read ) : 한 트랜잭션 내 같은 행을 두번 이상 조회했을 때 , 결과 값이 다른것을 말합니다.
  • 더티 리드 ( dirty read ) : 반복 가능하지 않는 조회와 유사하며 한 트랜잭션이 수행중일 때 다른 트랜잭션에 의해 수정되었지만 커밋되지 않은 데이터를 읽을 수 있을 때 발생합니다.

지속성

성공적으로 수행된 트랜잭션은 영원히 반영되어야 하는 것을 말합니다. 이는 데이터베이스에 시스템 장애가 발생해도 원래 상태로 복구하는 회복 기능이 있어야 함을 말하며 이를 위해 체크섬 , 저널링 , 롤백을 제공합니다.

  • 체크섬 : 중복 검사의 한 형태로 , 오류 정정을 통해 무결성을 보호합니다.
  • 저널링 : 데이터베이스에 변경된 값을 반영하기전에 로킹하는것을 말합니다.

무결성

데이터의 정확성 , 일관성 , 유효성을 유지하는 것을 말하며 , 무결성이 유지되어야 데이터의 신뢰가 생기며 무결성의 종류는 다음과 같습니다.

  • 개체 무결성 : 기본키로 선택된 필드는 빈 값을 허용하지 않습니다.
  • 참조 무결성 : 참조 관계에 있는 두 테이블의 데이터는 항상 일관된 값을 유지해야 합니다.
  • 고유 무결성 : 속성 값은 설정한 조건에 맞는 고유한 값을 가집니다.
  • NULL 무결성 : NULL 이 올 수 없는 조건이 있다면 , 그 속성은 NULL이 될 수 없습니다.

인덱스

데이터를 빠르게 찾을 수 있는 하나의 장치로 , 책 안에 찾고자 하는 항목을 찾아보기를 통해 빠르게 찾는것과 비슷하며 , 보통 B-트리라는 자료 구조로 이루어져 있습니다.

B-트리

루트 노드와 리프 노드가 있고 , 루트 노드와 리프 노드 사이에는 브랜치 노드가 존재합니다. 루트 노드부터 탐색을 시작하여 브랜치 노드를 거쳐 리프 노드까지 내려오면서 정렬된 값을 기반으로 탐색을 하는 트리입니다.

인덱스가 효율적인 이유

모든 요소에 접근할 수 있는 균형 잡힌 트리 구조와 트리 깊이가 대수확장성 때문입니다. 대수확장성은 트리 깊이가 노드 수에 비해 느리게 성장하는 것을 말하며, 일반적으로 인덱스의 한 깊이가 증가할 때 마다 인덱스 항목은 4배씩 증가합니다.

인덱스를 만드는 방법

Mysql의 경우 클러스터형 인덱스와 세컨더리 인덱스가 있으며 , 클러스터형 인덱스는 테이블당 하나만 만들 수 있으며 .primary key 또는 unique not null 옵션으로 만들 수 있으며 , 세컨더리 인덱스는 create index 명령어를 기반으로 만들 수 있습니다. 클러스터형 인덱스는 하나의 인덱스만 생성할 때 성능이 좋고 , 여러 보조 인덱스로 쿼리를 보낼때는 세컨더리 인덱스를 사용합니다.

인덱스 최적화 기법

인덱스는 비용이다.

인덱스는 두번 탐색하도록 강요하며 , 인덱스 리스트와 컬렉션 순으로 탐색하기에 읽기 비용이 발생합니다. 또한 컬렉션이 수정되었을 때 , 인덱스도 수정되어야 하는데 이때 B-트리의 높이를 균형있게 조절하는 비용과 , 데이터를 효율적으로 분산하는 비용이 듭니다. 따라서 모든 필드를 인덱스로 설정하는 것과 조회하는 컬렉션의 양이 많을 수록 비효율적입니다.

항상 테스팅 하라

인덱스 최적화 기법은 서비스 특징마다 다르며 , 서비스에서 사용하는 객체의 깊이와 테이블의 양이 다르기에 항상 테스팅을 하여 걸리는 시간을 최소화 하는것이 중요합니다.

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

여러 필드를 기반으로 조회할 때 복합인덱스를 생성하는데 인덱스를 생성할 때 생성 순서에 따라 인덱스 성능이 달라지며 , 같은 , 정렬 , 다중 값 , 카디널리티 순으로 생성해야 합니다.

조인

하나의 테이블이 아니라 두 개 이상의 테이블을 묶어 하나의 결과물로 만드는 것을 말합니다.

조인의 종류

  • 내부 조인 : 두 테이블 간의 교집합을 나타냅니다.
  • 왼쪽 조인 : 오른쪽 테이블의 일치하는 부분을 왼쪽 테이블을 기준으로 완전한 레코드를 만들며 일치하는 오른쪽 테이블이 없다면 null 값이 됩니다.
  • 오른쪽 조인 : 왼쪽 테이블의 일치하는 부분을 오른쪽 테이블을 기준으로 완전한 레코드를 만들며 일치하는 왼쪽 테이블이 없다면 null 값이 됩니다.
  • 합집합 조인 : 양쪽 테이블에서 일치하는 부분을 양쪽 테이블의 모든 레코드를 만들며 일치하는 항목이 없다면 누락된 쪽에 null 값이 됩니다.

조인의 원리

중첩 루프 조인

중첩 for 문과 같은 원리로 조건에 맞는 조인을 하는 방법이며 , 랜덤 접근에 대한 비용이 많이 증가하므로 대용량 테이블에서는 사용하지 않습니다. 이때 작은 블록으로 나눠 블록 하나씩 조인하는 블록 중첩 루프 조인 방식이 있습니다.

정렬 병합 조인

각 테이블을 조인할 필드를 기준으로 정렬하고 정렬이 끝난 이후에 조인 작업을 하는 방법입니다. 조인할 때 사용할 인덱스가 없고 대용량 테이블을 조인하며 조인 조건으로 범위 비교 연산자가 있을 때 씁니다.

해시 조인

해시 테이블을 기반으로 조인하는 방법입니다. 두 테이블 중 하나의 테이블이 메모리에 온전히 들어간다면 중첩 루프 조인보다 더 효율적이며 동등조인에서만 사용할 수 있습니다. Mysql 에서 해시 조인 단계는 밑의 두 단계로 나뉩니다.

빌드 단계

입력 테이블 중 크기가 더 작은 테이블을 메모리 내 해시 테이블에 빌드하며 , 조인에 사용되는 필드는 해시 테이블의 키가 됩니다.

프로브 단계

각 레코드를 읽어 키에 일치하는 레코드를 찾아 결과값을 반환합니다.

해시 조인은 각 테이블을 한번씩만 읽기 때문에 중첩 루프 조인보다 성능이 좋습니다.

profile
https://github.com/5tr1ker

0개의 댓글