[면접을 위한 CS 전공지식 노트] 데이터베이스 - 데이터베이스의 종류와 인덱스

Yijun Jeon·2024년 2월 7일
0

CS 전공지식

목록 보기
20/21
post-thumbnail

데이터베이스의 종류

관계형 데이터베이스

💡 관계형 데이터베이스 (RDBMS) 란?

행과 열을 가지는 표 형식 데이터를 저장하는 형태의 데이터베이스

  • SQL 언어로 조작
  • ex) MySql, PostgreSQL, 오라클, SQL Server, MSSQL
  • 표준 SQL을 지키기는 하지만 각각의 제품에 특화시킨 SQL 사용

MySQL

⭐️ 대부분의 운영체제와 호환되며 현재 가장 많이 사용하는 데이터베이스

  • C, C++로 만들어짐
  • MyISAM 인덱스 압축 기술, B-트리 기반의 인덱스, 스레드 기반의 메모리 할당 시스템, 매우 빠른 조인, 최대 64개 인덱스 제공
  • 대용량 데이터베이스를 위해 설계
  • 롤백, 커밋, 이중 암포 지원 보안 등의 기능 제공

🔗 MySQL 스토리지 엔진 아키텍처

👉 스토리지 엔진 : 데이터베이스의 심장 역할

  • 모듈식 아키텍처로 쉽게 스토리지 엔진을 바꿀 수 있으며, 데이터 웨어 하우징, 트랜잭션 처리, 고가용성 처리에 강점
  • 스토리지 엔진 위에 커넥터 API 및 서비스 계층을 통해 MySQL 데이터베이스와 쉽게 상호 작용
  • 쿼리 캐시를 지원해 입력된 쿼리 문에 대한 전체 결과 집합을 저장하기 때문에 사용자가 작성한 쿼리가 캐시에 있는 쿼리와 동일하면 서버는 단순히 구문 분석, 최적화 및 실행을 건너뛰고 캐시의 출력만 표시

PostgreSQL

⭐️ MySQL 다음으로 개발자들이 선호하는 데이터베이스 기술

  • VACUUM : 디스크 조각이 차지하는 영역을 회수할 수 있음
  • 최대 테이블 크기 : 32TB
  • SQL 뿐만 아니라 JSON 이용해 데이터에 접근 가능
  • 지정 시간 복구 기능, 로킹, 접근 제어, 중첩된 트랜잭션, 백업 등

NoSQL 데이터베이스

💡 NoSQL(Not Only SQL) 데이터베이스 란?

SQL을 사용하지 않는 데이터베이스

  • 전통적인 RDBMS와 다른 DBMS를 지칭하기 위한 용어로 데이터 저장에 고정된 테이블 스키마가 필요하지 않고 조인 연산 사용 불가능
  • 수평적으로 확장 가능
  • ex) MongoDB, redis 등

MongoDB

⭐️ JSON을 통해 데이터 접근 가능하며 Binary JSON 형태(BSON)로 데이터가 저장

  • 와이어드타이거 엔진이 기본 스토리지 엔진으로 장착된 키-값 데이터 모델에서 확장된 도큐먼트 기반의 데이터베이스
  • 확장성과 빅데이터 저장할 때 성능이 좋다
  • 고가용성, 샤딩, 레플리카셋 지원
  • 스키마를 정해 놓지 않고 데이터를 삽입할 수 있어 다양한 도메인의 데이터베이스를 기반으로 분석하거나 로깅 등을 구현할 때 강점
  • 도큐먼트를 생성할 때마다 다른 컬렉션에서 중복된 값을 지니기 힘든 유니크한 값인 ObjectID가 생성
    • 기본키로 유닉스 시간 기반의 타임스탬프(4바이트), 랜덤 값(5바이트), 카운터(3바이트)로 이루어짐

redis

⭐️ 인메모리 데이터베이스이자 키-값 데이터 모델 기반의 데이터베이스

  • 기본적인 데이터 타입 : 문자열(string)
  • 최대 512MB까지 저장
  • 이 외에도 셋(set), 해시(hash) 등 지원
  • pub/sub 기능을 통해 채팅 시스템, 다른 데이터베이스 앞단에 두어 사용하는 캐싱 계층, 단순한 키-값이 필요한 세션 정보 관리, 정렬된 셋(sorted set) 자료 구조를 이용한 실시한 순위표 서비스에 사용

인덱스

💡 인덱스 란?

데이터를 빠르게 찾을 수 있는 하나의 장치 - 마치 책의 마지막 장의 '찾아보기'


B-트리

💡 B-트리 란?

인덱스는 보통 B-트리라는 자료 구조로 이루어져 있음

  • 이는 루트 노드, 리프 노드, 루트 노드와 리프 노드 사이의 브랜치 노드로 나뉨

⭐️ 인덱스가 효율적인 이유

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

대수확장성 : 트리 깊이가 리프 노드 수에 비해 매우 느리게 성장하는 것을 의미


인덱스 만드는 방법

MySQL

⭐️ 클러스터형 인덱스세컨더리 인덱스 로 나뉨

🔗 클러스터형 인덱스 : 레코드들의 물리적인 저장 순서가 인덱스 순서와 동일하게 되도록 구성된 인덱스

  • 인덱스의 리프 노드가 곧 데이터 레코드
  • 인덱스 자체에 데이터가 포함됨
  • 사전과 유사
  • 보조 인덱스보다 검색 속도 빠름
  • 동일하거나 인접한 키 값 가진 레코드들은 물리적으로도 인접하게 저장되어 성능 향상
  • 데이터의 입력/수정/삭제는 더 느림
  • 테이블당 하나 설정 가능
  • 테이블 생성 시 기본키에 대해 클러스터 인덱스를 자동으로 생성
  • 기본키를 지정하지 않으면 먼저 나오는 UNIQUE 속성에 대해 클러스터 인덱스 생성

🔗 세컨더리 인덱스(보조 인덱스) : 클러스터 인덱스가 아닌 모든 인덱스

  • 보조 인덱스 생성시 별도의 페이지에 인덱스 구성
  • 책 뒤 <찾아보기>와 유사
  • 클러스터형보다 검색 느림
  • 데이터 입력/수정/삭제는 덜 느림
  • 테이블당 여러 개 생성 가능
  • create index... 명령어 사용
  • 하나의 인덱스만 생성할 것이라면 클러스터형 인덱스를 만드는 것이 세컨더리 인덱스 만드는 것보다 성능 좋음
    • ex) age라는 하나의 필드만드로 쿼리 보내면 클러스터형 인덱스만 필요 . age, name, email 등 다양한 필드를 기반으로 쿼리 보낼 땐 세컨더리 인덱스 사용

MongoDB

⭐️ 도큐먼트를 만들면 자동으로 ObjectID 가 형성 -> 해당 키가 기본키로 설정

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

인덱스 최적화 기법

1. 인덱스는 비용이다.

👉 인덱스는 두 번 탐색하도록 강요

  • 인덱스 리스트, 컬렉션 순으로 탐색하기 때문에 관련 읽기 비용이 듦
  • 컬렉션이 수정되었을 때 인덱스도 수정되어야 함

❗️ 따라서 쿼리에 있는 필드에 인덱스를 무작정 다 설정하는 것은 답이 아님

  • 컬렉션에서 가져와야 하는 양이 많을수록 인덱스 사용이 비효율적이 됨

2. 항상 테스팅하라.

👉 인덱스 최적화 기법은 서비스에서 사용하는 객체의 깊이, 테이블의 양 등에 따라 달라지므로 항상 테스팅 필요

  • explain() 함수를 통해 인덱스를 만들고 쿼리를 보낸 이후에 테스팅을 하며 걸리는 시간 최소화해야 함
EXPLAIN
SELECT * FROM t1
JOIN t2 ON t1.c1 = t2.c1

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

👉 보통 여러 필드를 기반으로 조회를 할 때 복합 인덱스를 생성하는데, 이 인덱스 생성 순서에 따라 성능이 달라짐

  1. 어떠한 값과 같음을 비교하는 ==이나 equal이라는 쿼리가 있다면 제일 먼저 인덱스로 설정
  2. 정렬에 쓰는 필드라면 그다음 인덱스로 설정
  3. 다중 값을 출력해야 하는 필드, 즉 쿼리 자체가 >이거나 < 등 많은 값을 출력해야 하는 쿼리에 쓰는 필드라면 나중에 인덱스 설정
  4. 유니크한 값의 정도 : 카디널리티. 이 카디널리티가 높은 순서를 기반으로 인덱스를 생성해야 한다. 예를 들어 age와 email이 있을 때, email이 더 높다. 즉 email이라는 필드에 대한 인덱스를 먼저 생성해야 함

0개의 댓글