[기술면접] 데이터베이스 면접 대비 본문

CS/면접 대비

[기술면접] 데이터베이스 면접 대비

미니모아 2022. 5. 10. 15:41
반응형
반응형

데이터베이스 면접 대비

데이터베이스

데이터베이스를 사용하는 이유

이전 파일시스템의 데이터 종속성 문제와 중복성, 무결성 문제를 해결하기 위해 데이터 베이스를 사용한다. 데이터 베이스는 다음과 같은 특징을 가진다.

  • 데이터 독립성
  • 데이터의 무결성
  • 데이터의 보안성
  • 데이터의 일관성
  • 데이터 중복 최소화

인덱스

빠른 데이터 검색을 위해 컬럼의 값과 해당 레코드가 저장된 주소를 key-value 쌍으로 인덱스를 만들어두는 것이다.

인덱스가 왜 필요한지

데이터는 디스크로부터 가져오게 된다. 자주 쓰일 경우 매번 조회하는 것은 비효율적이므로 컴퓨터는 자주 사용되는 테이블을 메모리에 올린다.

메모리에 데이터가 있다면 빠르게 가져올 수 있지만 없다면 디스크 전체를 스캔해야하며 이것을 풀 테이블 스캔이라고 한다. 대용량 데이터일 경우 비효율적이다.

이를 해결하기 위해 인덱스를 사용하며 인덱스는 메모리에 저장된다.

인덱스의 구조와 원리

인덱스에서 가장 많이 사용되는 구조는 B-tree이다. B-tree는 이진 트리의 변형으로 자식 노드가 최대 2인 이진트리와 달리 B-tree는 자식 노드의 개수를 2개 이상으로 가진다.

B-tree에서 자료의 탐색은 수직적 탐색과 수평적 탐색으로 이루어진다.

  • 수직적으로 조건을 만족하는 첫 번째 레코드를 찾아 들어간다.
    • leaf 노드에 닿을 떄까지 child 주소를 찾아서 각 페이지를 타고 내려가게 된다.
  • 리프 노드에서 수평적으로 조건을 만족하는 레코드를 찾는다.
    • 리프 노드에 저장된 row 주소를 찾아서 디스크에서 조회하게 된다.

Inno DB 스토리지 엔진은 디스크에 데이터를 저장하는 가장 기본 단위를 페이지로 삼고 이것은 디스크의 읽기, 쓰기 작업의 최소 단위가 되므로 인덱스도 페이지 단위로 관리된다.

range scan

leaf 노드에서 스캔 시작점을 찾아서 찾고자 하는 작업에 도달하면 멈추는 것을 말한다. 풀 스캔에 반대되는 개념이다.

인덱스를 언제 쓰는 게 좋을까?

인덱스는 조건이 붙은 조회를 할 때는 매우 효율적이지만 삽입, 삭제, 수정일 때는 오히려 성능을 저하시킨다.

인덱스는 정렬된 상태로 데이터를 저장해야하기 때문이다.

성능 저하되는 상황

삽입을 할 때

  • 어느 자리에 들어가야하는지 찾는다
  • 원래 있던 데이터를 뒤로 시프트 시킨다.

이때 저장할 페이지가 꽉 찬 경우에는 다음 페이지로 옮겨야 해서 작업이 더 많아지게 된다.

또한 인덱스는 테이블과 별도의 객체이기 때문에 테이블에도 삽입하고, 인덱스에도 삽입을 해야하기 때문에 번거롭다.

삭제를 할 때

데이터를 실제로 삭제하는 게 아니라 인덱스 안에 사용 안함이라는 표시를 해주기 때문에 공간이 낭비된다.

업데이트를 할 때

인덱스에는 업데이트라는 개념이 없어서 삭제 후 삽입 해줘야하기 때문에 부하가 크다.

사용하면 좋을 경우

  • where 절에서 자주 사용되는 컬럼
  • 외래키가 사용되는 컬럼
  • join에 자주 사용되는 컬럼

인덱스 컬럼 설정 기준

Cardinality(기수성)이 높은 것을 선택해야한다.

속성 값에서 중복을 제거했을 때 요소의 개수가 가장 많은 것을 선택한다.

출처: https://youtu.be/e9PC0sroCzc

클러스터드 인덱스 vs 논 클러스터드 인덱스

클러스터드 인덱스

데이터가 순서대로 정렬되어 있기 때문에 범위 검색에 효율적이다.

삽입이나 삭제에 비용이 크고 정렬의 비용이 커지면 비효율적이다.

한 테이블에 하나만 만들 수 있다.

데이터를 인덱스로 지정한 컬럼에 맞춰서 정렬

  • 테이블 구조에 영향을 미치는 인덱스
  • 한 테이블에 하나만 생성 가능

클러스터 키로 검색 시 처리 성능이 매우 빠름

Inno DB에서는

  • PK는 항상 clusted index
  • unique index로 정의된 컬럼 중 하나
  • 보이지 않는 컬럼을 내부적으로 추가하여 사용

논 클러스터드 인덱스

해시 테이블 방식의 약한 참조로 되어 있어서 정렬되어 있지 않다.

순서가 상관 없다.

한 테이블에 여러개가 있을 수 있다.

추가 저장 공간이 필요하다.

Insert시 추가 작업이 필요하다. (인덱스 생성)

인덱스 키 값에는 해당 데이터에 대한 포인터가 존재

  • 인덱스의 구조는 데이터 행과 독립적
  • 한 테이블에 여러 개 생성 가능

정규화에 대해서

정규화 탄생 배경

하나의 릴레이션에서 여러 엔티티의 애트리뷰트들을 혼합하게 되면 정보가 중복 저장되며, 저장 공간을 낭비하게 된다. 또 중복된 정보로 인해 갱신 이상이 발생하게 된다. 이를 해결하기 위해 정규화 과정을 거치는 것이다.

이상

  • 삽입 이상 : 불필요한 데이터를 추가해야하지 삽입할 수 있는 상황
  • 갱신 이상 : 일부만 변경하여 데이터가 불일치하는 모순의 문제
  • 삭제 이상 : 투플 삭제로 인해 꼭 필요한 데이터까지 함께 삭제되는 문제

정규화란 무엇인가

정규화란 데이터의 중복을 줄이기 위해 관계형 데이터베이스에서 데이터를 구조화하는 작업이다. 정규화를 거치면 정규형을 만족하게 되는데 정규형이란 특정 조건을 만족하는 릴레이션의 스키마 형태를 말한다.

정규화의 종류

  • 1NF : 도메인이 오직 원자값만 포함해야한다.
  • 2NF : 기본키를 제외한 모든 속성이 완전 함수적 종속이어야한다.
  • 3NF : 기본키를 제외한 모든 속성이 이행 종속적이지 않아야한다.
  • BCNF : 결정자가 모두 후보키이다.

이외에 4NF와 5NF가 존재하지만 대부분의 데이터베이스의 목표 3NF이다. 3NF 테이블의 대부분이 삽입, 변경, 삭제 이상이 없으며 BCNF, 4NF, 5NF를 만족하기 때문이다.

정규화의 장단점

장점

이상을 해결할 수 있고 구조 확장시 재디자인을 최소화할 수 있다.

단점

또한 정규화가 과도하게 이루어졌을 경우 릴레이션 분해로 조인이 많아지고 이로 인해 질의에 대한 응답 시간이 느려질 수 있다. 개선을 위해 반 정규화를 사용할 수 있다.

트랜잭션

트랜잭션이란

여러 쿼리를 논리적으로 하나의 작업으로 묶어주는 것

하나의 트랜잭션은 커밋 혹은 롤백된다.

  • 커밋 : 트랜잭션으로 묶인 모든 쿼리가 성공되어 트랜잭션 결과를 실제 디비에 반영하는 것이다.
  • 롤백 : 쿼리 실행 결과를 취소하고 디비를 트랜잭션 이전 상태로 되돌리는 것

트랜잭션의 특징 ACID

  • Atomicitiy (원자성) : 트랜잭션은 DB에 모두 반영되거나, 전혀 반영되지 않아야 한다.
  • Consistency(일관성) : 트랜잭션 작업 처리 결과는 항상 일관성 있어야 한다.
  • Isolation(독립성) : 둘 이상의 트랜잭션이 동시 실행되고 있을 때 어떤 트랜잭션도 다른 트랜잭션 연산에 끼어들 수 없다.
  • Durability(지속성) : 트랜잭션이 성공적으로 완료되었으면 결과는 영구히 반영되어야 한다.

ACID 성질은 트랜잭션이 이론적으로 보장해야하는 성질이고 실제로는 성능을 위해 손실 보장이 완화되기도 한다.

예) 동일 연결에 100개의 데이터가 접속했을 때 독립성 유지를 위해서는 순차적으로 작업이 처리되어야한다. => 동시성이 떨어지게 된다.

동시성을 위한 방법으로 트랜잭션의 격리 레벨 설정이 있다.

트랜잭션 격리 수준

동시에 DB에 접근할 때 그 접근을 어떻게 제어할지에 대한 설정

4가지의 격리 레벨이 존재한다.

  • Read-Uncommitted
  • Read-Commited
  • Repeatable-read
  • serializable

밑으로 갈수록 격리 수준과 데이터 정합성이 높아지지만 동시성은 떨어진다.

read-uncommited

커밋 전의 트랜잭션의 데이터 변경 내용을 다른 트랜잭션이 읽는 것을 허용

더티 리드가 발생할 수 있다.

  • 트랜잭션 A가 작업한 내용을 커밋하기 전에 B가 해당 내용을 읽는다.
  • 만약 A가 해당 내용을 커밋하지 않고 롤백한다면 B는 무효가 된 데이터 값을 읽고 처리하기 때문 문제가 생긴다.

이외에 논 리티터블 리드와 팬텀 리드 문제가 발생할 수 있다.

read-commited

커밋이 완료된 트랜잭션의 변경사항만 다른 트랜잭션에서 조회 가능

트랜잭션이 이루어지는 동안 다른 사용자는 해당 데이터에 접근이 불가능하다.

논 리피터블 리드가 발생할 수 있다.

  • 같은 트랜잭션 내에서 select 문을 두 번 조회하여 하나는 commit 전에 조회하고 하나는 commit 후에 조회했을 때 값이 불일치하는 문제이다.

이 외에 팬텀 리드 문제가 발생할 수 있다.

repeatable-read

커밋이 완료된 데이터만 읽을 수 있는데, 한 트랜잭션이 조회한 데이터는 트랜잭션이 종료될 때까지 다른 트랜잭션이 변경하거나 삭제하는 것을 막는다. 한번 조회한 데이터는 다시 조회해도 같은 값을 조회한다. 즉 한 트랜잭션 범위 내에서 조회한 내용이 항상 동일함을 보장한다.

팬텀 리드 문제가 발생할 수 있다.

  • select 문을 사용할 때 발생할 수 있는 문제이다.
  • 해당 쿼리로 읽히는 데이터에 들어가는 행이 새로 생기거나 없어져 있는 현상이다.

serializable

한 트랜잭션에서 사용하는 데이터를 다른 트랜잭션에서 접근 불가

트랜잭션이 커밋될 때까지 모든 데이터에 잠금이 설정되 다른 트랜잭션에서 해당 데이터를 변경할 수 없게 된다.

트랜잭션 전파 타입

트랜잭션의 경계에서 트랜잭션이 어떻게 동작할 것인가

트랜잭션이 시작하거나 참여하는 방법에 관한 설정

트랜잭션이 처리되는 과정 안에서 또 다른 트랜잭션이 처리되는 경우, 부모 트랜잭션이 있냐 없냐에 따라 타입별로 트랜잭션의 경계를 설정할 수 있다.

출처 : https://youtu.be/9ZXIoh9PtwY

key 정리

후보키

튜플을 유일하게 식별하기 위해 사용하는 속성들의 부분 집합 (기본키로 사용할 수 있는 속성들)

  • 유일성 : 키로 하나의 Tuple을 유일하게 식별할 수 있음
  • 최소성 : 꼭 필요한 속성으로만 구성

기본키

후보키 중에 선택한 Main key

  • Null 값을 가질 수 없음
  • 동일한 값이 중복될 수 없음

대체키

후보키가 둘 이상일 때 기본키를 제외한 나머지 후보키

슈퍼키

한 릴레이션 내에 있는 속성들의 집합으로 구성된 키로서 릴레이션을 구성하는 모든 튜플들 중 슈퍼키로 구성된 속성의 집합과 동일한 값은 나타나지 않는다.

  • 유일성은 만족시키지만 최소성은 만족시키지 못한다.

외래키

다른 릴레이션의 기본키를 참조하는 속성 또는 속성들의 집합을 의미한다.

  • 스키마 간의 참조 관계를 표현하는데 중요한 도구
  • 외래키로 지정되면 참조 릴레이션의 기본키에 없는 값은 입력할 수 없다.

Primary Key와 Unique Key 차이

primiary key = 기본키, unique key = 유일성을 가지기 위해 설정한 키, 제약 조건 중에 하나로 유일한 값을 식별하는 것이 주된 목적이다.

기본키는 해당 테이블의 식별자 역할을 한다. 따라서 중복성이 없어야하고 null 값을 가질 수 없다. 학생을 식별하기 위해 학번을 사용하는 예

유니크 키는 유일성을 가지기 위해서 설정한 것으로 지정이 되면 중복이 되는 것을 제어하는 역할을 하게 된다. 학생 이름의 중복이 없게 하기 위해 중복된 이름의 뒤에는 숫자를 붙여 식별하는 예

유니크 키는 하나의 테이블에서 각각 컬럼마다 지정이 가능하지만 기본키는 한 테이블에서 오직 하나만 설정할 수 있다.

SQL - join

조인이란 두 개 이상의 테이블이나 데이터베이스를 연결하여 데이터를 검색하는 방법을 말한다. 테이블을 연결하려면, 적어도 하나의 칼럼을 서로 공유하고 있어야하므로 이를 이용하여 데이터 검색에 활용한다.

inner join

교집합으로 기준 테이블과 join 테이블의 중복된 값만 보여준다.

left outer join

기준테이블과 조인테이블의 중복된 값을 보여준다. 이때 중복된 값이 없더라도 왼쪽 테이블의 칼럼은 모두 보여준다.

right outer join

기준테이블과 조인테이블의 중복된 값을 보여준다. 이때 중복된 값이 없더라도 오른쪽 테이블의 칼럼은 모두 보여준다.

full outer join

합집합으로 두 테이블의 모든 데이터를 보여준다.

cross join

모든 경우의 수를 전부 표현해주는 방식이다. (카타시안 프로덕트)

self join

자기 자신과 자기 자신을 조인하는 것이다.

자기 자신이 갖고 있는 컬럼을 다양하게 변형시켜 활용할 때 자주 사용한다.

SQL injection

해커에 의해 조작된 SQL 쿼리문이 데이터 베이스에 그대로 전달되어 비정상적 명령을 실행시키는 공격 기법

RDBMS vs NoSQL

관계형 데이터 베이스 (RDBMS)

관계형 데이터베이스는 핵심적인 두 가지 특징이 있다.

  • 데이터는 정해진 데이터 스키마에 따라 테이블에 저장된다.
  • 데이터는 관계를 통해 여러 테이블에 분산된다.

따라서 스키마를 준수하지 않은 레코드는 테이블에 추가할 수 없다. 또한 데이터의 중복을 피하기 위해 관계를 이용한다. 하나의 테이블에서 중복 없이 하나의 데이터만을 관리하기 때문에 다른 테이블에서 부정확한 데이터를 다룰 위험이 없어지는 장점이 있다.

장점

  • 명확하게 정의된 스키마, 데이터 무결성 보장
  • 관계는 각 데이터를 중복 없이 한번만 저장

단점

  • 덜 유연함. 데이터 스키마를 사전에 계획해야하며 나중에 수정이 힘들다
  • 관계를 맺고 있어서 조인문이 많은 복잡한 쿼리가 만들어질 수 있음
  • 대체로 수직적 확장만 가능함

사용하는 경우

  • 관계를 맺고 있는 데이터가 자주 변경되는 애플리케이션의 경우
  • 변경될 여지가 없고, 명확한 스키마가 사용자와 데이터에게 중요한 경우

NoSQL

관계형 데이터 베이스를 지양하며 대량의 분산된 데이터를 저장하고 조회하는데 특화되었으며 스키마 없이 사용 가능하거나 느슨한 스키마를 제공하는 저장소를 말한다.

SQL과 달리 정해진 구조가 있는 것이 아니기 때문에 다른 구조의 데이터를 같은 컬렉션에 추가가 가능하다.

장점

  • 스키마가 없어서 유연함. 언제든지 데이터를 조정하고 새로운 필드를 추가할 수 있다.
  • 데이터는 애플리케이션이 필요로 하는 형식으로 저장되며 데이터를 읽어오는 속도가 빨라진다.
  • 수직 및 수평확장이 가능해서 애플리케이션이 발생키기는 모든 읽기/쓰기 요청 처리가 가능하다.

단점

  • 유연성으로 인해 데이터 구조 결정을 미루게 될 수 있다.
  • 데이터 중복을 계속 업데이트 해야한다.
  • 데이터가 여러 컬렉션이 중복되어 있기 때문에 수정시 모든 컬렉션에서 수행해야한다.

사용하는 경우

  • 정확한 데이터 구조를 알 수 없거나 변경/확장 될 수 있는 경우
  • 읽기를 자주 하지만, 데이터 변경은 자주 없는 경우
  • 데이터베이스를 수평으로 확장해야 하는 경우 (막대한 양의 데이터를 다뤄야하는 경우)

조인

컬렉션을 통해 데이터를 복제하여 각 컬렉션 일부분에 속하는 데이터를 정확하게 산출하도록 한다. 하지만 데이터가 중복될 위험이 있다. 따라서 조인을 잘 사용하지 않고 자주 변경되지 않는 데이터일 때 NoSQL을 쓰면 효율적이다.

cap 이론

  • Consistency (일관성) : 다중 클라이언트에서 같은 시간에 조회하는 데이터는 항상 동일한 데이터임을 보증하는 것
    • 동기식 : 데이터의 저장 결과를 클라이언트로 응답하기 전에 모든 노드에 데이터를 저장하는 동기식 방법 느리지만 데이터의 정합성 보장
    • 비동식 : 메모리나 임시 파일에 기록하고 클라이언트에 먼저 응답한 다음, 특정 이벤트 또는 프로세스를 사용하여 노드로 데이터를 동기화하는 방법. 응답시간이 빠르지만 쓰기 노드에 장애가 발생하였을 경우 데이터가 손실 될 수 있다.
  • Availability (가용성) : 모든 클라이언트의 읽기와 쓰기 요청에 대하여 항상 응답이 가능해야 함을 보증하는 것
    • 데이터 복제를 사용: 동일한 데이터를 다중 노드에 중복 저장하여 그 중 몇대의 노드가 고장 나도 데이터가 유실되지 않도록 하는 방법
  • Partition tolerance (네트워크 분할 허용성) : 지역적으로 분할된 네트워크 환경에서 동작하는 시스템에서 두 지역간의 네트워크가 단절되거나 네트워크 데이터의 유실이 일어나더라도 각 지역 내의 시스템은 정상적으로 동작해야함

저장 방식에 따른 븐류

key-value, document Model, column model, graph model

 

레디스 (Redis)

  • Remote Dictionary Server
  • database, cache
  • 메모리 상에 데이터를 저장하는 서버

Cache

나중의 요청에 대한 결과를 미리 저장했다가 빠르게 사용하는 것

데이터베이스보다 더 빠른 메모리에 더 자주 접근하고 덜 자주 바뀌는 데이터를 저장해서 빠르고 쉽게 접근하자는 개념으로 나온 것이 in memory database 레디스이다.

언제 쓰는지

  • 여러 서버에서 같은 데이터를 공유할 때
  • single server라면
  • Atomic 자료구조라면
  • cache 기능을 사용하기 위해서

주의점

  • 싱글 스레드 서버이기 때문에 시간 복잡도를 고려해야한다.
  • In-memory 특성상 메모리 파편화, 가상 메모리등의 이해가 필요하다

 

참고 출처:

https://youtu.be/e9PC0sroCzc

https://youtu.be/9ZXIoh9PtwY

https://github.com/gyoogle/tech-interview-for-developer

https://github.com/JaeYeopHan/Interview_Question_for_Beginner

https://youtu.be/Gimv7hroM8A

반응형
Comments