제가 공부한 내용을 정리하는 블로그입니다.
아직 많이 부족하고 배울게 너무나도 많습니다. 틀린내용이 있으면 언제나 가감없이 말씀해주시면 감사하겠습니다😁

데이터의 영속성


  • 레디스는 스냅샷 기능을 제공하여 메모리의 내용을 .rdb 파일로 저장. 해당 시점으로 복구 가능.

기본-복제 아키텍처를 제공(복구 기능 및 확장)


  • 기본-복제 아키텍처를 사용하여 비동기식 복제를 지원하여 데이터가 여러 복제 서버에 복제 될 수 있음.
  • 따라서 main 서버가 장애가 발생하는 경우 요청이 여러 서버로 분산될 수 있음으로 향상된 읽기 성능과 더 빠른 복구 기능 사용.
  • scalue-up, scale-in, scale-out을 제공하여 클러스터를 확장하여 일관된 성능과 안정성을 제공.

Single Thread


레디스는 싱글 스레드 아키텍처를 사용. ⇒ 한번의 1개의 명령어만 실행

  • Memcached는 멀티 스레드 지원.
  • 하나의 요청이 병목이 되면 그 다음 요청이 계속 blocking 상태이므로 O(n)의 시간복잡도를 보여줌.
    • O(n)의 시간복잡도를 갖는 명령어: Keys, flushall, FLUSHDB, Delte COLLECTIONS, Get All COLLECTIONS
  • Event Loop를 이용하여 요청을 수행
    • 실제 명령에 대한 작업은 커널 IO 레벨에서 멀티플렉싱을 통해 처리하여 동시성을 보장.
    • 커널 IO에서는 스레드 풀을 이용

Redis에서의 CRUD


READ

  • 레디스 서버에서 사용자가 요청한 데이터가 있는지 확인.
  • 데이터가 존재하는 경우.
    • 만료 여부를 확인.
    • 정보 반환
  • 데이터가 만료되었거나 존재하지 않는 경우
    • 데이터가 만료되었을 경우, 데이터 삭제.
    • 메인서버에 요청.
    • 메인 서버로부터 받은 데이터를 캐싱 및 DB에 저장한 후 데이터를 반환 후 종료

CUD

  • 데이터에 변화가 생겼으므로 해당하는 값은 캐싱된 데이터가 아닌 실시간 정보를 보내주어야 함.
  • 방문자의 CUD를 메인 서버에 요청.
  • 메인 서버는 요청받은 CUD를 처리하고 업데이트
  • 변경되기 이전의 데이터 값은 레디스 서버에서 찾아서 삭제 후 종료.

Redis 캐싱전략


웹 서비스 환경에서 시스템 성능 향상을 기대하는 기술 일반적으로 캐시는 메모리(RAM)을 사용하기에 DB보다
훨씬 빠르게 데이터를 응답할 수 있어서 이용자에게 빠르게 서비스를 제공 가능

하지만 기본적으로 RAM 용량은 16~32G 정도라, 데이터를 모두 캐시에 저장해버리면 용량 부족 현상이 일어나 시스템이 다운 될 수 있기에 어느 종류의 데이터를 캐시에 저장할지, 얼만큼의 데이터를 캐시에 저장할지, 얼마동안 오래된 데이터를 캐시에서 제거하는지에 대한 전략이 필요.

캐시 읽기 전략


Look Aside (Lazy Loding)

캐시를 옆에 두고 필요할 때만 데이터를 캐시에 로드하는 전략

 

Look Aside Diagram

  • Cache Aside 패턴이라고 부르기도 함.
  • 데이터를 찾을 때 우선적으로 캐시를 확인하는 법
    • 없으면 DB에서 조회.
  • 반복적인 읽기가 많은 시스템에서 적합
  • 캐시와 DB가 분리되어 가용되기 때문에
    • 원하는 데이터만 별도로 구성하여 캐시에 저장
    • 캐시 장애 대비 구성이 되어 있음.
      • 캐시(Redis)가 다운되더라도 DB에서 데이터를 가져올 수 있어, 서비스에 큰 장애는 없음.
  • Cache Store와 Data Store(DB) 간 데이터 정합성 문제가 발생할 수 있음
    • DB에서 캐시로 데이터를 미리 넣어주는 작업을 진행하기도 함. => Cache Warming
💡 Cache Warming
미리 Cache로부터 DB의 데이터를 밀어 넣어두는 작업을 의미.
이 작업을 수행하지 않으면 서비스 초기에 트래픽 급증 시 대량의 cache miss가 발생하여 데이터베이스 부하가 급증할 수 있음.(Thundering Herd)
다만, 캐시 자체는 용량이 작아 무한정으로 데이터를 들고 있을 수는 없어 일정 시간이 지나면 expire 되는데, 그러면 다시 Thundering Herd가 발생될 수 있기 때문에 캐시의 TTL을 잘 조정할 필요가 있음.

 

  • flow
    • cache hit
      • 어플리케이션에서 레디스로 데이터를 읽어옴
    • cache miss
      • 데이터베이스에 데이터 요청
      • 데이터를 데이터베이스에 저장.
  • 장점
    • 데이터 접근 시간을 줄임.
    • 처리량을 늘림

Read Through 패턴

캐시에서만 데이터를 읽어오는 전략(inline cache)

Read Through

  • Look Aside와 비슷하지만 데이터 동기화를 라이브러리 또는 캐시 제공자에게 위임하는 방식
  • 데이터를 조회하는데에 있어 속도가 느림
  • 데이터 조회를 캐시에만 의존하므로, Redis가 다운될 경우 서비스 이용에 차질.
  • 캐시와 DB 간의 데이터 동기화가 이루어져 데이터 정합성은 항상 일치
  • 읽기가 많은 서비스에 적합
  • flow
    • cache Store에 검색하는 데이터가 있는지
    • cache hit
      • 데이터 반환
    • cache miss
      • 캐시에서 DB에 데이터를 조회
      • 캐시를 업데이트
      • 데이터 반환
  • 장점
    • 직접적인 데이터베이스의 접근을 최소화
    • 데이터 정합성 일치
    • read에 소모되는 자원 최소화
  • 캐시가 문제가 발생했을 때 서비스에 차질이 있을 수 있으므로 Replication 또는 Cluster로 구성해서 가용성을 높여야 한다.

캐시 쓰기 전략


Write Back 패턴

Write Behind 패턴으로 부르기도 함
캐시와 DB 동기화를 비동기적으로.

Write Back

  • 캐시와 DB 동기화를 비동기적으로 관리하기에 동기화 과정이 생략
  • 데이터를 저장할 때 DB에 바로 쿼리하지 않고, 캐시에 모아서 일정 주기 배치 작업을 통해 DB에 반영
  • 캐시에 모아놨다가 DB에 쓰기 때문에 쓰기 쿼리 회수 비용과 부하를 줄일 수 있음.
  • Write가 빈번하면서 Read 하는데 많은 양의 Resource가 소모되는 서비스에 적합.
  • 데이터 정합성 확보
  • 자주 사용되지 않는 불필요한 리소스 저장.
  • 캐시에서 오류가 발생하면 데이터를 영구 손실.
  • flow
    • 모든 데이터를 Cache Store에 저장
    • 일정 시간이 지난 뒤 DB에 저장
  • 캐시가 일종의 Queue의 역할을 겸하게 됨.
  • 장점
    • DB 쓰기 횟수 비용과 부하를 줄일 수 있음
      • 캐시에 데이터를 모았다가 한번에 DB에 저장하기 때문에
    • 데이터베이스에 장애가 발생하더라도 지속적인 서비스를 제공할 수 있도록 보장 가능
  • Replication이나 Cluster 구조를 적용함으로써 cache 서비스의 가용성을 높이는 것이 좋고
  • Read-Through와 결합하면 가장 최근에 업데이트된 데이터를 항상 캐시에서 사용할 수 있는 혼합 워크로드에 적합.

Write Through 패턴

데이터베이스와 Cache에 동시에 데이터를 저장하는 전략.
Cache Store에도 반영하고 Data Store에 동시에 반영하는 방식

Write Through 패턴

  • 데이터를 저장할 때 먼저 캐시에 저장한 다음 바로 DB에 저장.(모아놓았다가 나중에 저장이 아닌 바로 저장)
  • Read Through와 마찬가지로 DB 동기화 작업을 캐시에게 위임.
  • DB와 캐시가 항상 동기화가 되어 있어, 캐시의 데이터는 항상 최신으로 유지
    • 데이터의 일관성을 유지할 수 있어서 안정적
  • 데이터의 유실이 발생하면 안되는 상황에 적합
  • 자주 사용되지 않는 불필요한 리소스 저장
  • 매 요청마다 두번의 Write가 발생하게 됨으로써 빈번한 생성 및 수정이 발생하는 서비스에서는 성능 이슈 발생
  • 기억장치 속도가 느릴경우, 데이터를 기록할 때 CPU가 대기하는 시간이 필요하기 때문에 성능 감소.

Write Around 패턴

모든 데이터는 DB에 저장.

Write Around

  • Write Through보다 훨씬 빠름
  • 모든 데이터는 DB에 저장(캐시를 갱신하지 않음)
  • Cache miss가 발생하는 경우에만 DB와 캐시에도 데이터를 저장.
  • 따라서 캐시와 DB내의 데이터가 다를 수 있음(데이터 불일치)

캐시 읽기 + 쓰기 전략 조합


  • Look Aside + Write Around 조합
    • 가장 일반적인 조합
  • Read Through + Write Aound 조합
    • 항상 DB에 쓰고, 캐시에서 읽을때 항상 DB에서 먼저 읽어오므로 데이터 정합성 이슈에 대한 완벽한 안전 장치를 구성할 수 있음.
  • Read Through + Write Through 조합
    • 데이터를 쓸 때 항상 캐시에 먼저 쓰므로 읽어올 때 최신 캐시 데이터 보장
    • 데이터를 쓸 때 항상 캐시에서 DB로 보내므로, 데이터 정합성 보장.

캐시 저장 방침


캐시 솔루션은 자주 사용되면서 자주 변경되지 않는 데이터의 경우 캐시 서버에 적용하여 반영할 경우 높은 성능향상을 이뤄낼 수 있음.
이를 Cache Hit Rating이라고 한다.
  • 캐시는 메모리에 저장되는 형태를 선호
  • 수십기가정도의 저장소를 보유하게 되며, 자주 사용되는 데이터를 어떻게 뽑아 캐시에 저장하고 자주 사용하지 않느 데이터를 어떻게 제거해 나갈 것이냐를 지속적으로 고민해야할 필요성이 있다.
  • 캐시를 저장하는 기준은 자주 사용되며 자주 변경되지 않는 데이터
  • 캐시는 언제든지 데이터가 날라갈 수 있는 휘발성
  • 데이터의 유실 또는 정합성의 문제도 항상 고려

캐시 제거 방침


  • 캐시 데이터의 경우 캐시 서버에만 단독으로 저장되는 경우도 있지만, 대부분 영구 저장소에 저장된 데이터의 복사본으로 동작하는 경우가 많음.
  • 2차 저장소(영구 저장소)에 저장되어 있는 데이터와 캐시 솔루션의 데이터를 동기화하는 작업이 반드시 필요.
    • 개발 과정에 고려사항이 늘어난다는 점을 기억.
  • 캐시 서버와 데이터베이스에 저장되는 데이터의 commit 시점에 대한 고려.
  • 캐시 만료 정책이 제대로 구현되어 있지 않는 경우, 클라이언트의 데이터가 변경되었음에도 오래된 정보가 캐싱되어있어 오래된 정보를 사용할 수 있다는 문제점이 발생.
    • 캐시된 데이터가 기간 만료되면 캐시에서 데이터가 제거되고, 응용 프로그램은 원래 데이터 저장소에서 데이터를 검색해야함.
    • 캐시 만료 주기가 너무 짧으면 데이터는 너무 빨리 제거되고, 캐시를 사용하는 이점이 줄어듦.
    • 반대로 너무 길면 데이터가 변경될 가능성과 메모리 부족 현상이 발생하거나, 자주 사용되어야 하는 데이터가 제거되는 등의 역효과

캐시 공유 방식 지침


  • 각 애플리케이션 인스턴스가 캐시에서 데이터를 읽고 수정 가능.
  • 애플리케이션이 캐시에 보유하는 데이터를 수정해야 하는 경우, 애플리케이션의 한 인스턴스가 만드는 업데이트가 다른 인스턴스가 만든 변경을 덮지 않도록 해야함.
    • 데이터의 정합성 문제
  • 먼저 캐시 데이터를 변경하기 전에 데이터가 검색된 이후 변경되지 않았는지 확인.
    • 변경되지 않았다면 즉시 업데이트.
    • 변경되었다면 업데이트 여부를 애플리케이션 레벨에서 결정하도록 수정
  • 캐시 데이터를 업데이트하기 전에 Lock을 잡는 방식
    • 조회성 업무를 처리하는 서비스에 Lock으로 인한 대기 현상이 발생
    • 데이터의 사이즈가 작아 빠르게 업데이트가 가능한 업무와 빈번한 업데이트가 발생하는 상황에 적용하기 용이.

 

참조

'Database > Redis' 카테고리의 다른 글

[Redis] Redis Data Type  (0) 2024.05.16
[Redis] Redis 기본  (2) 2024.05.10
[Redis] NoSQL이란  (0) 2024.04.30
[OSSCA2024] Redis 과제 3  (0) 2024.04.25
제가 공부한 내용을 정리하는 블로그입니다.
아직 많이 부족하고 배울게 너무나도 많습니다. 틀린내용이 있으면 언제나 가감없이 말씀해주시면 감사하겠습니다😁

 

String 유형


문자열을 Value로 사용하는 것은 가장 단순한 형태.
문자열을 Value로 사용하고, html 문자열을 캐시하는 식의 활용 방식이 있음.

특징

  • Value에 string, number들을 저장. => 저장시 별도의 타입이 존재하지 않음.

SET

  • 값을 세팅할 때는 SET을 사용
# 값이 이미 있으면 실패 : nx
# 값이 이미 있을 때만 성공 : xx
SET [keyName] [value]

GET

  • 값을 찾아올 때는 GET을 사용.
GET [keyName]

 

INCR, DECR

  • 값이 정수인 경우, INCR과 DECR(increment, decrement) 명령어 활용 가능.
INCR [keyName]
DECR [keyName]

 

EXISTS

  • value의 존재 여부를 확인
  • 있으면 1, 없으면 0을 반환
EXIST [key1] [key2] ...

DEL

  • 해당 key를 삭제
  • 삭제에 성공했으면 1, 실패하면 0 반환
DEL [key1] [key2] ...

EXPIRE

  • TTL 설정
  • 단위는 초
EXPIRE [keyName] 5

 

Lists


특징

  • Value에 list를 저장.

lpush / rpush

  • 왼쪽에 값을 넣어주거나 오른쪽에 값을 넣어줌.

lrange

  • 값을 조회. 이때 -1은 모두 가져오라는 뜻

rpop

  • 이를 이용해 queue 구현 가능

rbpop

  • 순차적인 분산 작업 구현 가능
  • rpop과 비슷하나 데이터가 없다면 데이터가 들어올 때까지 block 상태로 대기

 

Sets


특징

  • Value에 set을 저장.
  • list는 중복을 허용하나 set은 중복이 안됨.

SADD

  • 집합(Set)에 하나 이상의 멤버를 추가
    • SADD test_sets 1test_sets라는 이름의 집합에 멤버로 1을 추가

SMEMBERS

  • 집합(Set)에 모든 멤버를 반환
    • SMEMBERS test_sets test_sets라는 이름의 집합에 모든 멤버 반환

 

Sorted sets


특징

  • Value에 set을 저장.
  • 중복 불가능 하며, scores 필드를 기준으로 정렬됨
  • 중복이 안되면 동일한 value를 넣으면 기존 데이터의 score를 덮어서 데이터 순서가 바뀜.

zadd

  • Sorted Set에 멤버와 점수를 추가하는 데 사용
    • test_ssets라는 이름의 Sorted Set에 멤버 1과 점수 1을 추가. => 성공(1)
    • zadd test_ssets "a" 2은 에러발생
      • Sorted Set은 멤버의 순서를 기준으로 정렬하는데, 문자열은 정렬되지 않는 데이터 타입이기 때문.
    • 마지막으로 zadd test_ssets "0" 2와 같이 문자열 "0"을 멤버로 추가한 경우
      • 이 경우는 정상적으로 처리되며, 정수로 간주하여 추가.
      • 새로운 멤버가 추가되었으므로 (integer) 0이 반환.

zrange

  • zrange 명령어는 Sorted Set의 멤버들을 조회하는 명령어.
  • zrange test_ssets 0 -1 명령어는 test_ssets Sorted Set의 첫 번째 멤버부터 마지막 멤버까지 모두 조회. 

 

Hashes


특징

  • Hashes key/value 목록을 가짐.

hset

  • 명령어는 해시에 필드와 값을 설정
  • HSET htest username hihtest라는 이름의 해시에 username 필드에 hi 값을 설정합니다. 반환된 정수 값 1은 새 필드가 생성되었음을 나타냄
  • 같은 방식으로 HSET htest userpwd asdfhtest 해시에 userpwd 필드에 asdf 값을 설정

hget

  • 해시에서 특정 필드의 값을 가져옴.
  • HGET htest usernamehtest 해시에서 username 필드의 값을 가져옵니다. 여기서는 "hi"가 반환됩니다.
  • HGET htest temp는 존재하지 않는 필드인 temp의 값을 가져오려고 시도합니다. 이 경우, 해당 필드가 존재하지 않기 때문에 nil이 반환됩니다.

hgetall

  • 해시의 모든 필드와 값을 반환
  • HGETALL htesthtest 해시의 모든 필드와 값을 가져옵니다. 여기서는 "username", "hi", "userpwd", "asdf"가 번갈아가면서 반환

 

Bitmaps


특징

  • Value에 bit값 저장
  • 512MB 용량으로 2^32(42억)개의 bit 값들을 저장
  • boolean 옵션으로 많이 사용.(회원마다 공지 조회 여부)

setbit

  • setbit 명령어는 주어진 오프셋(offset)에 비트 값을 설정하는데 사용.
  • 여기서 "test_bits"라는 이름의 비트열(Bitfield)에 대해 첫 번째 비트(오프셋 0)를 1로 설정.
  • 새로운 비트가 설정되었으므로 (integer) 0을 반환.

getbit

  • getbit 명령어는 주어진 오프셋에 해당하는 비트 값을 가져오는데 사용.
  • "test_bits" 비트열의 첫 번째 비트(오프셋 0)의 값.
  • 비트 값이 1로 설정되어 있으므로 (integer) 1이 반환.

 

 

참조

'Database > Redis' 카테고리의 다른 글

[Redis] Redis 고급 및 캐싱전략  (0) 2024.05.16
[Redis] Redis 기본  (2) 2024.05.10
[Redis] NoSQL이란  (0) 2024.04.30
[OSSCA2024] Redis 과제 3  (0) 2024.04.25
제가 공부한 내용을 정리하는 블로그입니다.
아직 많이 부족하고 배울게 너무나도 많습니다. 틀린내용이 있으면 언제나 가감없이 말씀해주시면 감사하겠습니다😁

Redis


Key-Value Store의 하나의 DB
Remote Dictionary Server의 약자로, 원격 Dictionary 자료구조 서버라는 뜻
  • Key로 올 수 있는 자료형은 기본적으로 String이지만, Value는 다양한 타입을 지원함.
  • 메모리 기반 데이터베이스이기 때문에, Disk를 기반으로 하는 RDBMS보다 read가 빠름.
💡 잠깐! RDBMS도 쿼리를 통해 조회해오면, 메모리에 존재하는 Buffered Cache를 이용한다고 알고 있어요. (= Cache Hit)        Buffered Cache를 활용할 때의 RDBMS와 레디스는 조회 시간 차이가 없나요?

경험상 RDBMS에서 동일 select문 n회 조회할 때(cache hit)와 Redis의 조회 속도를 비교해보면 Redis가 더 빠른데요, 과거 AWS에서 monggo DB 담당하시는 이덕현 개발자님이 세미나에서 “RDBMS는 데이터의 직렬화, 역직렬화 과정이 있기 때문에 레디스보다 더 느린 것 같다"고 추론했다는 언급을 하신 적 있습니다.

 

자바 해시 맵과의 비교

공통점

  • 레디스, 해시 맵 모두 Key-Value 형태
  • 메모리 베이스 -> 디스크보다 빠른 접근 가능.
  • 원하는 Value를 원하는 자료구조로 사용 가능

차이점

분산 환경에서의 장점

  • 유저의 수가 늘어나 서버가 증설될 때 해시맵 데이터를 참조해야할 때

자바 해시맵을 이용한 분산환경

  • 자바 해시맵은 프로세스마다 메모리가 달라, 원격 프로세스간 동일한 해시 맵 데이터를 참조해야할 때 동기화가 어려움.

 

레디스를 이용한 분산환경

  • 별도의 레디스 서버를 구성하고, 해당 레디스에서 값을 꺼내 쓴다면 메모리 기반 데이터 구조의 빠른 응답성 데이터 정합성을 가져올 수 있음.

DBMS로서의 장점

  • Redis는 영속성을 제공하기에 다양한 옵션도 제공 가능
  • TTL 설정: 일정 시간이 지나면 데이터 삭제, 용량이 작은 메모리를 효율적으로 관리.
  • 분산 데이터 저장소 구성: Redis Cluster 등 분산환경에서 안정적인 데이터 관리
  • 보안 체계: 악성 스크립트 공격으로부터 안전 보장. TLS 지원.

레디스 특징

  • 쿼리를 사용할 필요 없이 명령어로 가능.
  • 데이터를 디스크에 쓰는 구조가 아니라 메모리에서 데이터를 처리하기 때문에 속도가 빠름.(인메모리 기반)
  • 여러 자료 구조를 지원(String, Lists, Sets, Sorted Sets, Hashes ...)

RESP 프로토콜

RESP(REdis Serialization Protocol)은 Redis 클라이언트가 Redis 서버와 TCP 커넥션을 맺어 통신할 때 사용하는 프로토콜.

더보기

RESP는 Redis의 client-server 통신에서만 사용.
Redis Cluster에서 노드간의 통신은 RESP가 아닌 binary protocol을 사용.

Request-Response 모델

Redis는 기본적으로 다음의 2가지 경우를 제외하고 Request-Response 모델을 사용.

  • Pipelining
    • 여러개의 명령어(Command)를 한번에 보내고 모든 답장이 올 때까지 기다림.
  • Pub/Sub
    • 어떤 Client가 특정 channel을 subscribe하면 push protocol로 전환되어 더이상 명령어를 보내지 않음.

Redis의 Request-Response 프로토콜은 다음과 같이 동작.

  • 클라이언트가 Bulk String의 Array 타입으로 명령어를 서버로 전송.
  • 서버는 클라이언트가 보낸 명령어에 맞는 타입으로 응답을 보냄.

RESP의 Data Types

RESP는 5가지의 데이터 타입이 존재.

데이터의 타입은 데이터의 첫번째 바이트를 통해 구분.

RESP를 통해 오고가는 Req와 Resp는 항상 "\r\n"으로 끝남.

  • Simple Strings: "+"
    • Simple Strings 타입은 binary-safe하지 않은 일반 문자열을 전송할 때 사용하는 데이터 타입
    • binary-safe한 문자열을 전송하려면 Bulk String타입으로 전송
    • 문자열은 Newline을 포함할 수 없음.
    • ex) "+OK\r\n"
  • Errors: "-"
    • 에러 정보에 대한 타입
    • 관습적으로 에러의 이름을 먼저 쓰고 발생 원인을 뒤에 적음.
    • ex) "-ERR unknown command 'foobar'\r\n" "-ERR unknown command 'foobar'\r\n"
  • Integers: ":"
    • 숫자의 크기는 signed 64bit 범위 내
    • INCR, LLEN, LASTSAVE와 같은 명령어에 대한 응답
    • 일부 명령어는 true/false의 의미로 1/0을 씀.
  • Bulk Strings: "$"
    • binary-safe한 문자열을 타나낼 때 사용하는 타입
    • "$"에 이어 문자열의 길이가 주어지고 "\r\n" 이후 실제 문자열
    • 빈 문자열을 나타낼 땐 "$0\r\n\r\n" 를 사용
    • null 값을 나타낼 때는 Null Bulk String이라고하며, "$-1\r\n" 를 사용
  • Arrays: "*"
    • 10진수로 배열의 크기와 "\r\n" 이 나옴.
    • 배열 내 원소는 각각 특정한 타입을 가질 수가 있으며, 그 타입은 모두 달라도 됨.
    • "*3\r\n:1\r\n+2\r\n$4\r\nbulk\r\n"
    • Null Array: "*-1\r\n"
    • 중첩된 Array도 가능

 

 

Redis 설치하기


Redis 공식 홈페이지, getting-started에서 설명.

Mac에서 설치하기

# brew가 없다면 https://brew.sh/

brew --version
brew install redis

# 설치를 완료했다면 Redis Server 실행
redis-server

# Redis Server에 접근하는 client 실행
redis-cli
  • 옵션을 주지 않고 부팅했을 때 Redis의 default 포트는 6379
  • cli를 실행하지 않고도, telnet으로 접속 가능 -> telnet 0 6379

hello시 첫 값들이 세팅되어 있음.

Key를 잡을 때 주의점

  • Key의 최대 길이는 512MB.(value도 마찬가지)
  • 매우 긴 키는 좋지 않음.
    • 1MB길이의 키는 메모리 관리 측면 뿐만 아니라 키를 조회할 때 고비용의 키 비교 로직을 실행해야 할 수 있기에 좋지 않음.
    • 키가 너무 길다면 SHA-1를 통해 해싱
    • 레디스를 사용하는 이유는 빠른 응답속도…!
  • 매우 짧은 키 역시 좋지 않음
    • 가독성을 해치는 키는 별로 좋지 않음.
  • 고정된 스키마를 활용
    • .이나 -주로 사용
    • comment:4321:reply.to, comment:4321:reply-to

참조

Redis, 자바 해시맵 비교: https://sihyung92.oopy.io/database/redis/1
RESP 프로토콜: https://redis.io/docs/latest/develop/reference/protocol-spec/#resp-simple-strings

'Database > Redis' 카테고리의 다른 글

[Redis] Redis 고급 및 캐싱전략  (0) 2024.05.16
[Redis] Redis Data Type  (0) 2024.05.16
[Redis] NoSQL이란  (0) 2024.04.30
[OSSCA2024] Redis 과제 3  (0) 2024.04.25
제가 공부한 내용을 정리하는 블로그입니다.
아직 많이 부족하고 배울게 너무나도 많습니다. 틀린내용이 있으면 언제나 가감없이 말씀해주시면 감사하겠습니다😁

NoSQL을 제대로 알기 전에 RDBMS의 특징을 제대로 알고 가보자!

 

RDBMS의 특징

  • Column과 Row가 두개 이상의 테이블
  • Row: 정보를 나타냄
  • Column: 이름, 주소 등 특정한 유형의 정보를 정렬
  • 스키마: 테이블과 필드 타입 간의 관계
  • 관계형 데이터베이스에서 스키마는 정보를 추가하기 전에 명확하게 정의되어 있어야 함.
    • 테이블과 필드의 설계를 확실히하고 데이터를 저장해야함.
    • 데이터 중복을 최소화, 데이터 정합성을 맞춰야 함.
    • 데이터의 유연성이 떨어지는 상황도 발생하기도 함.
  • SQL
    • 데이터베이스 설계자가 관계형 데이터베이스를 설계하는데 사용하는 프로그래밍 언어.
    • 쿼리를 통해 데이터를 생성, 검색, 수정, 삭제 가능.

NoSQL


Not Only SQL
기존 RDBMS 방식을 탈피한 데이터베이스 기존의 관계형 DB가 가지고 있는 특성뿐만 아니라 다른 특성들을 부가적으로 지원. RDBMS가 가지고 있는 한계를 극복하기 위해 데이터 저장소의 새로운 형태로 수평적 확장성을 지님으로써 문서, 그래프, 키 값, 인 메모리, 검색을 포함하여 다양한 데이터 모델을 사용.

NoSQL 특징

  • RDBMS와 달리 데이터 간의 관계를 정의하지 않음.
  • RDBMS에 비해 훨씬 더 대용량의 데이터를 저장 가능.
  • 반정형화, 비정형 데이터에 적합.
  • 분산형 구조이기에 확장성이 뛰어남.
  • 고정되지 않은 테이블 스키마를 가짐.
  • ACID대신 Eventual Consistency를 허용한다.
💡 ACID
ACID는트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질을 가르키는 약어로
원자성(Atomicity), 일관성(Consistency), 독립성(Isolation), 지속성(Durability)이 존재.

💡 Eventual Consistency
다양한 기기에 분산 저장되어 있는 데이터를 Update할 경우 실시간으로 다른 기기에 전파하기에 어려운데
이를 조금 타협하여 최신은 아닐 수 있지만 Update 전까지는 최신의 데이터를 반환.

 

NoSQL 유형

  • Graph Store: 서로 연관된 그래프 형식의 데이터를 저장
    • Node와 Edge에 데이터를 저장
    • Node: 사람, 장소 및 사물에 대한 정보가 저장.
    • Edge: 노드 간의 관계에 대한 정보가 저장.
    • 소셜 네트워크, 사기 탐지, 권장 엔진 같은 패턴을 찾아보기 위해 관계를 상세히 검토해야하는 사례에 적합.
    • Neo4j와 JanusGraph
  • Wide Column Store: Row가 아닌 Column 형태로 데이터를 저장
    • 테이블, 행 및 동적 열에 데이터를 저장
    • 각 행이 동일한 열을 가질 필요가 없다는 점에서 관계형 데이터베이스에 비해 뛰어난 유연성을 제공.
    • 대량의 데이터를 저장해야할 때 적합.
    • 사물인터넷 데이터와 사용자 프로필 데이터를 저장하는데 사용
    • Cassandra, HBASE
  • Document Store: 비정형 대량 데이터를 저장
    • JSON 객체와 비슷한 문서에 데이터를 저장.
    • 각 문서에는 필드와 값의 쌍이 포함
    • 일반적으로 값은 String, Number, Boolean, Array, Object 등 다양한 유형이 가능
    • MongoDB
  • Key-Value Store: 메모리 기반으로 빠르게 데이터를 저장 및 읽기
    • Key-Value 데이터베이스는 각 항목에 키와 값이 포함되어 있는 보다 간단한 유형의 데이터베이스
    • Value은 보통 Key를 참조하는 방식으로만 검색이 가능
    • Key-Value 데이터베이스는 대량의 데이터를 저장해야 하지만 검색을 위해 복잡한 쿼리를 수행할 필요가 없는 사례에 적합.
    • 일반적으로 사용자 선호도 저장 또는 캐싱에 사용
    • Redis, DynanoDB

NoSQL 장점

  • 유연성: 스키마가 없기 때문에 유연한 데이터구조
  • 확장성: 데이터 분산이 용이하며 성능 향상을 위한 Scale-up, Scale-out이 가능
  • 고성능: 특정 데이터 모델 및 액세스 패턴에 대해 최적화 되어 관계형 DB를 통해 유사한 기능을 충족하려 할 때보다 뛰어난 성능
  • 고기능성: 각 데이터 모델에 맞춰 특별히 구축된 뛰어난 기능의 API와 데이터 유형을 제공

NoSQL 단점

  • 데이터 중복 가능: 데이터 변경시 모든 컬렉션에서 수행해야 함.
  • 스키마가 존재하지 않아 명확한 데이터 구조를 보장하지 못함.
  • 제품 지원을 받기 어려움.

사용 요령

  • NoSQL은 데이터의 구조를 알 수 없는 경우 사용하는 것이 좋다.
  • Update가 많이 이뤄지지 않는 시스템이 좋다
  • Scale-out이 가능하다는 장점이 있어 막대한 데이터를 저장해야하는 경우 적합하다.
  • 기존의 정형화된 데이터 뿐만 아니라 메신저 텍스트, 음성 등 반정형화, 비정형화된 데이터도 저장하고 다루어야 하는 경우
  • 대규모 데이터를 다루는데 해당 데이터의 특징이 자주 바뀌는 경우
  • 강력한 일관성보다 성능과 가용성이 더 중요한 서비스인 경우
  • 굳이 ACID 특징이 필요 없는 읽기 전용 데이터를 관리하는 경우

참조

'Database > Redis' 카테고리의 다른 글

[Redis] Redis 고급 및 캐싱전략  (0) 2024.05.16
[Redis] Redis Data Type  (0) 2024.05.16
[Redis] Redis 기본  (2) 2024.05.10
[OSSCA2024] Redis 과제 3  (0) 2024.04.25
제가 공부한 내용을 정리하는 블로그입니다.
아직 많이 부족하고 배울게 너무나도 많습니다. 틀린내용이 있으면 언제나 가감없이 말씀해주시면 감사하겠습니다😁

과제 3

받은 내용을 그대로 다시 돌려주는 echo{영어이름} 명령을 만들어보자


과제 시작 전 배경지식..

Redis에 명령은 어디에 저장되어 있을까?

src/ 디렉토리 밑에 commands 시작하는 파일이 존재.

src/commands.h
src/commands.c
src/commands.def

 

추가: def 파일 정리

 

echo 명령은 어떻게 실행될까?

echo 명령어 확인

기본적으로 echo 명령은 받은 문자를 그대로 반환하는 명령이다. 

과정

// commands.h

// commands.c
#define MAKE_CMD(name,summary,complexity,since,doc_flags,replaced,deprecated,group,group_enum,history,num_history,tips,num_tips,function,arity,flags,acl,key_specs,key_specs_num,get_keys,numargs) name,summary,complexity,since,doc_flags,replaced,deprecated,group_enum,history,num_history,tips,num_tips,function,arity,flags,acl,key_specs,key_specs_num,get_keys,numargs
#define MAKE_ARG(name,type,key_spec_index,token,summary,since,flags,numsubargs,deprecated_since) name,type,key_spec_index,token,summary,since,flags,deprecated_since,numsubargs
#define COMMAND_STRUCT redisCommand
#define COMMAND_ARG redisCommandArg

// commands.def
{MAKE_CMD("echo","Returns the given string.","O(1)","1.0.0",CMD_DOC_NONE,NULL,NULL,"connection",COMMAND_GROUP_CONNECTION,ECHO_History,0,ECHO_Tips,0,echoCommand,2,CMD_LOADING|CMD_STALE|CMD_FAST,ACL_CATEGORY_CONNECTION,ECHO_Keyspecs,0,NULL,1),.args=ECHO_Args},

// server.h
void echoCommand(client *c);

//server.c
void echoCommand(client *c) {
    addReplyBulk(c,c->argv[1]);
}
  1. commands.h 파일에는 redis의 command에 대한 arg 타입들을 지정.
  2. commands.c 파일에는 함수타입을 지정.
  3. commands.def 파일에는 실제 함수를 지정하는 라인이 존재.
    1. echo 함수는 echoCommand를 실행.
  4. server.h 파일에는 echoCommand() 함수를 정의.
  5. server.c 파일에는 실제 echoCommand() 함수를 구현.

하는 프로세스로 동작을 하였다.

추가: 프로세스 정리

 

과제 수행

나의 이름과 좋아하는 숫자를 조합하여 echoHero17 명령어를 생성.

// commands.def
{MAKE_CMD("echoHERO17","Returns the given string.","O(1)","1.0.0",CMD_DOC_NONE,NULL,NULL,"connection",COMMAND_GROUP_CONNECTION,ECHO_History,0,ECHO_Tips,0,echoCommandHero17,2,CMD_LOADING|CMD_STALE|CMD_FAST,ACL_CATEGORY_CONNECTION,ECHO_Keyspecs,0,NULL,1),.args=ECHO_Args},

// server.h
void echoCommandHero17(client *c);

// server.c
void echoCommandHero17(client *c) {
    addReplyBulk(c, c->argv[1]);
}
  1. commands.def 파일에는 echoHERO17 명령어를 생성하고 echoHERO17은 echoCommandHero17()를 실행.
  2. server.h 파일에는 echoCommandHero17() 함수를 정의.
  3. server.c 파일에는 실제 echoCommandHero17() 함수를 구현.

실제 실행화면

다음과 같이 echoHERO17 명령어가 잘 실행되는 것을 볼 수 있다.

 

느낀점

레디스의 코드를 볼 수 있어서 좋았지만 아직 모르는 코드와 실행동작이 존재하였다. 과제 이후에도 블로그를 지속적으로 수정하면서 포스팅을 보안해 나가야겠다.

'Database > Redis' 카테고리의 다른 글

[Redis] Redis 고급 및 캐싱전략  (0) 2024.05.16
[Redis] Redis Data Type  (0) 2024.05.16
[Redis] Redis 기본  (2) 2024.05.10
[Redis] NoSQL이란  (0) 2024.04.30

Database 면접 스터디를 시작하게 된 계기

컴퓨터 공학과를 나왔지만 Database 수강을 실패하여 개인적으로 Database의 책을 찾아보고 공부하여 정리하였지만, Database의 개념이 부족하다고 생각이 들었다. 그때 인프런을 통해서 JSCode에서 진행하는 Database 면접 스터디를 확인하였고, 주저없이 신청하게 되었다.

각 주차별로 큰 주제가 있으며 그 주제 안에서 면접에서 충분히 질문이 가능한 항목들을 미리 운영진 분들께서 추려주어 해당 부분에 대해 한 주동안 학습해오고 스터디날 면접 스터디를 역할을 나누어 진행하는 것이 프로세스였다. 스터디를 해보지 않아서 비교하기는 어렵지만, 운영진들께서 체계적으로 프로세스를 준비한다는 것이 느껴졌고, 역할을 나누어서 면접을 진행하는 것이 큰 도움이 되었던 것 같다. 

그렇게 5주간의 Database 공부가 시작되었다.

 

활동내역

공부를 넘어서 주마다 과제가 있는데, 학습 내용을 블로그에 작성하는 것이 과제였다. 하지만 나는 학생때부터 계속 노션을 이용해와서 익숙한 노션이 아닌 tistory에 작성하는 것이 쉬운 일은 아니였는데, 한번 노션에 작성하고 초안으로 작성한 노션의 내용을 다시 tistory에 옮기면서 두번의 공부를 진행했다. 총 세번의 복습을 진행하였고, 스터디날 전까지 해당 부분을 계속해서 학습하였다.

 

1주차 항목 중 하나

역할 기여한 부분

데이터베이스 면접 스터디를 진행하면서 가장 크게 기여한 부분은 5주동안 꾸준히 참여한 것이라고 생각한다. 회사 퇴근하고 나서 따로 개념 정리를 하고 과제를 제출하며 면접 스터디를 진행하는 것은 쉬운 일이 아니였고 꽤나 공이 들어가는 테스크였다. 하지만 내가 공부한 부분을 면접을 통해 다른 사람들에게 공유하면서 정보를 제공하고, 내가 참고하지 못한 부분들에 대해서도 다른 분들이 도와주어 지식을 채워나갈 수 있었던 이유가 5주동안 꾸준히 참여한 큰 성과라고 생각한다. 다른 분들도 마찬가지로 면접 스터디에 열심히 임해주시고 준비해주어 상부상조의 결과가 되었던 것 같다. 

나를 바라본 이미지 및 장점

생각보다 초반부터 칭찬들이 이어져서 개인적으로 놀랐다. 이전 몇번의 면접을 본 경험과 준비를 착실히 해서 나온 결과라고 생각해서 무엇이든 노력을 안하면 안되는게 없다고 생각이 들었다. 말하는 속도에 따라 면접관이 이해를 할 수 있도록 질문에 대해 몇가지 특징들을 제시하면서 답변한 내용들이 대체적으로 좋다고 했다.

아쉬운 점이 있다면 프로젝트의 경험에 빗대어 면접관의 답변을 했으면 좋겠다는 의견도 있었다. 이 부분에 대해서는 부족하다고 느끼고 다음에 면접이 있다면 이 부분에 대해 접목시킬 생각이다.

배운점 느낀점 아쉬운점

개인 생활도 있었을 뿐더러 회사 업무도 있어 퇴근하고 나서 데이터베이스를 공부하고 정리하는 것은 여간 쉬운 작업은 아니였다. 하지만 어느 곳에서는 나보다 더 열심히 살아가고 준비하는 사람이 있다는 생각이 막연하게 있었지만 이번 면접 스터디를 하면서 실제 치열하게 공부하는 사람들을 보며 더욱 자극받았고, 나 또한의 동기부여가 되었다. 

그리고 아쉬운 점으로는 5주동안 진행하면서 뒤로 갈수록 해이해진 부분이 있었다. 초반에는 모든 꼬리질문에 대해서도 다 대답할 수 있도록 준비를 철저히 하였고 모든 내용에 대해 학습을 하였지만 4, 5주차가 되면서 이해가 되지 않은 부분도 머리로 이해하지 않고 텍스트로만 암기했던 부분이 있었던 것 같다. 비록 스터디는 끝났지만 이번 스터디에 정리한 내용을 토대로 계속해서 나의 데이터베이스 지식을 더 갈고닦아 더 많은 지식을 함유할 생각이다. 

 

 

'Database > JSCode' 카테고리의 다른 글

[JSCode] Database Week5  (2) 2023.12.05
[JSCode] Database Week4  (0) 2023.11.28
[JSCode] Database Week3  (1) 2023.11.21
[JSCode] Database Week2  (2) 2023.11.14
[JSCode] Database Week1  (1) 2023.11.07

Commit에 대해서 설명해주세요.

> `Commit`은 데이터베이스에서 **하나의 트랜잭션 단위**로 트랜잭션을 종료하고 해당 업데이트 정상적으로 처리했다는 것을 의미하는 것으로 변경된 사항을 **데이터베이스에 영구적으로 반영**됩니다. Commit 이후에는 모든 사용자가 변경한 데이터의 결과를 조회할 수 있으며 명령어로는 DDL문(CREATE, ALTER, DROP) 또는 (INSERT, DELETE, UPDATE)이 있습니다.
> 

### 트랜잭션 종료

- **DDL 실행**(`CREATE`, `ALTER`, `DROP`)
- **DCL**(`GRANT`, `REVOKE`)
- DEADLOCK과 같은 ERROR
- **Transaction**(`INSERT`, `UPDATE`, `DELETE`) 작업내용 취소

### SAVEPOINT

- 현재 트랜잭션을 분할하는 명령어
- `SAVEPOINT`는 `ROLLBACK TO SAVEPOINT`로 원하는 곳까지 ROLLBACK가능
- 여러개의 SQL문을 수행하는 트랜잭션의 경우, SAVEPOINT 지정 가능.

Rollback에 대해서 설명해주세요.

> `ROLLBACK`은 데이터베이스 작업 중에 **트랜잭션 처리 과정에서 발생한 변경사항을 취소**하고 트랜잭션 과정을 종료하는 명령어로써, 마지막 COMMIT(트랜잭션의 결과)으로 돌아갑니다. 또는 SAVEPOINT명령어를 사용하여 원하는 지점까지로 설정할 수 있습니다.
> 
- Transaction(INSERT, DELETE, UPDATE) 내용을 취소.
- COMMIT 내용 복구

### COMMIT과 ROLLBACK 장점

- 데이터 무결성 보장
- 데이터 원자성 보장
- 데이터 변경사항 확인 가능
- 논리적인 작업 그룹화 가능

Auto Commit 설정에 대해서 설명해주세요.

> `Auto Commit`이란 사용자가 Commit 명령을 따로 하지 않아도 **자동으로 모든 명령을 Commit**되어 즉시 반영되는 명령어를 말합니다. SQL로는 SET AUTOCOMMIT = 1/0(true/false)로 활성화 비활성화 가능합니다. SELECT으로 @AUTOCOMMIT을 확인할 수 있습니다. Commit이 된 트랜잭션은 ROLLBACK이 불가능하기에 주의해서 사용해야 합니다.
> 

### Auto Commit Case

- SQL*PLUS가 정상 종료된 경우
- DDL, DCL 수행된 경우

### Auto ROLLBACK Case

- SQL*PLUS 비정상 종료
- 컴퓨터의 다운

- mySQL에서는 auto commit이 default로 enable
- autocommit이 켜진 상태에서 start transaction하면 auto commit이 끊기고 transaction을 종료하면(commit, rollback) 다시 원래의 auto commit 상태로

트랜잭션에 대해 설명해주세요.

> `트랜잭션`은 데이터베이스 내에서 하나의 그룹으로 처리되어야하는 **명령문들을 모아놓은 작업단위**로 데이터베이스에 영구 저장되는 단위를 말합니다. 이런 논리적인 조각을 통해서 **데이터 무결성**을 지키기 위한 `COMMIT`과 `ROLLBACK`을 할 수 있습니다.
> 

### 개념

- 데이터의 일관성과 무결성을 보장하기위한 트랜잭션 관리.
- 트랜잭션
    - 데이터베이스 내에서 하나의 그룹으로 처리되어야하는 명령문들을 모아놓은 작업단위.
    - DBMS의 상호작용의 단위

### 특성

- ALL-OR-NOTHING

### 사용법

- Begin_transaction으로 시작, END_TRANSACTION으로 마무리.
- 내부에 명령문 기술
    • 트랜잭션의 성질 ACID에 대해서 설명해주세요.ACID
      • 원자성(Atomicity)
        • 트랜잭션 내의 쿼리는 모두 성공하거나 모두 실패해야 .
        • 트랜잭션은 논리적으로 쪼개질 수 없는 작업 단위이기 때문에 SQL문이 실패하면 지금까지의 모든 작업을 취소해서 아무 일도 없었던 것처럼 ROLLBACK을 해야함.
        • 이 속성에서 개발자은 언제 Commit 할 지 ROLLBACK할 지 판단.
        • 나머지 DB에 영구적으로 저장하는 것과 이전 상태로 되돌리는 것은 DBMS가 담당.
      • 일관성(Consistency)
        • 트랜잭션이 DB에 정의된 rule을 위반했는지 DBMS가 커밋하기 전에 확인 및 통지.
        • DB에 정의된 role 외에 애플리케이션 관점에서 트랜잭션이 consistent하게 동작하는 지는 개발자가 확인.
      • 독립성(Isolation)
        • 서로 다른 트랜잭션은 서로에게 영향을 주면 안됨. 다른 얘기로 여러 트랜잭션이 동시에 실행될 때도 혼자 실행되는 것처럼 동작하게 만듭니다. ⇒ 병행성
        • 동시성을 컨트롤할 때 성능 저하의 문제 발생 가능.
        • 따라서 DBMS의 종류에 따라 여러 종류의 isolation level을 제공.
          개발자는 isolation level 중에 어떤 level로 트랜잭션을 동작시킬지 설정 가능.
      • 지속성(Durability)
        • 커밋된 트랜잭션은 DB에 영구적으로 저장.
        • DB System에 문제가 발생하더라도 COMMIT된 트랜잭션은 DB에 남아있어야 하는 속성.
        • 영구적으로 저장한다는 뜻은 비휘발성 메모리(hdd, ssd …)에 저장함.
          이 속성은 기본적으로 DBMS에서 보장.
    •  

ACID는 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질을 가르키는 약어로
원자성(Atomicity), 일관성(Consistency), 독립성(Isolation), 지속성(Durability)이 있습니다.

  •  

트랜잭션 격리 수준이 뭘까요?

> `트랜잭션 격리 수준`이란 여러 트랜잭션이 동시에 처리될 때, 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있게 **허용할지 여부를 결정하는 것**입니다. 고립 수준이 높은 순서대로 `SERIALIZABLE`, `REPEATABLE READ`, `READ COMMITTED`, `READ UNCOMMITED`가 있습니다. 이 트랜잭션슬은 AUTO COMMIT이 FALSE인 상태에서만 발생합니다.
> 

|  | Dirty READ | Non-Repeatable Read | Phantom Read |
| --- | --- | --- | --- |
| READ UNCOMMITED | 발생 | 발생 | 발생 |
| READ COMMITTED | 없음 | 발생 | 발생 |
| REPEATABLE READ | 없음 | 없음 | 발생 |
| SERIALIZABLE | 없음 | 없음 | 없음 |

트랜잭션 격리 수준 READ UNCOMMITTED에 대해서 설명해주세요.

> `READ UNCOMMITTED`는 **커밋하지 않은 데이터에 접근할 수 있는 격리 수준**으로 다른 트랜잭션 중에도 작업 중인 데이터 조회가 가능하여 부정합 문제인 **Dirty READ**를 유발합니다. 따라서 MySQL에서는 최소한 READ COMMITTED 이상의 격리 수준을 사용해야합니다.
> 

### READ UNCOMMITTED

- **커밋하지 않은 데이터조차도 접근할 수 있는 격리수준**.
- 어떤 트랜잭션의 작업이 완료되지 않았는데도, 다른 트랜잭션에서 볼 수 있는 부정합 문제 ⇒ Dirty READ
    - 데이터가 조회되었다가 사라지는 현상
- 정합성이 많은 격리 수준이므로 MySQL을 사용하면 최소한 READ COMMITTED 이상의 격리 수준 사용해야함.
    • 트랜잭션 격리 수준 READ COMMITTED에 대해서 설명해주세요.READ COMMITTED
      • 커밋된 데이터만 조회.
      • Phantom Read에 더해 Non-Repeatable Read(반복 읽기 불가능)문제가 발생.
      • READ COMMITTED에서는 커밋된 데이터만 조회할 수 있으므로, REPEATABLE READ와 마찬가지로 언두 로그에서 변경 전의 데이터를 찾아서 반환.
    •  

READ COMMITTED커밋된 데이터만 조회할 수 있는 격리 수준으로 SELECT 조회 시 다른 트랜잭션에 의해 추가된 레코드를 발견하는 Phantom ReadNon-Repeatable Read가 발생할 수 있습니다.

  •  

트랜잭션 격리 수준 REPEATABLE READ에 대해서 설명해주세요.

> `REPEATABLE READ`는 **MVCC를 이용하여 한 트랜잭션 내에서는 동일한 결과를 보장하지만, 새로운 래코드의 추가를 막지 않는 격리수준**으로 `Pahntom Read`가 발생할 수 있으며
> 

### REPEATABLE READ

- 일반적인 RDBMS는 **변경 전 레코드를 UNDO 공간에 백업**. ⇒ 변경 전/후 데이터가 모두 존재하므로 동일한 레코드에 대해 여러 버전의 데이터가 존재하는 것을 `MVCC(Multi-Version Concurrency Control, 다중 버전 동시성 제어)`라고 부름.
- 이를 통해서 트랜잭션이 롤백된 경우 데이터 복원이 가능 및 트랜잭션 간에 데이터 제어 가능.
- 각각의 트랜잭션은 고유한 **트랜잭션 번호**가 존재하고 백업 레코드는 어느 트랜잭션에 의해 백업되었는지를 함께 저장.
- 데이터가 불필요하다고 판단되는 시점에 주기적으로 백그라운드 스레드를 통해 삭제.
- MVCC를 이용하여 한 트랜잭션 내에서는 동일한 결과를 보장하지만, 새로운 레코드가 추가되는 경우 부정합이 생길 수 있음.
- REPEATABLE READ는 새로운 레코드의 추가까지는 막지 않는다고 하였다. 따라서 SELECT로 조회한 경우 트랜잭션이 끝나기 전에 다른 트랜잭션에 의해 추가된 레코드가 발견될 수 있는데, 이를 유령 읽기(Phantom Read).
- 하지만 MVCC 덕분에 일반적인 조회에서 유령 읽기(Phantom Read)는 발생하지 않는다. 왜냐하면 자신보다 나중에 실행된 트랜잭션이 추가한 레코드는 무시하면 되기 때문
- Phantom Read가 발생하는 순간은 잠금이 사용되는 경우.
    - MySQL은 다른 RDBMS와 다르게 특수한 갭 락이 존재
- 트랜잭션 안에서 실행되는 SELECT라면 항상 일관된 데이터를 조회하게 된다. 하지만 트랜잭션 없이 실행된다면, 데이터의 정합성이 깨지는 상황 발생 가능

트랜잭션 격리 수준 SERIALIZABLE에 대해서 설명해주세요.

> `SERIALIZABLE`은 가장 엄격한 격리 수준으로 **트랜잭션을 순차적으로 진행하는 격리 수준**입니다. 동시 성능이 매우 떨어집니다. 이는 `SELECT FOR SHARE/UPDATE` 구문에서 사용합니다.
> 

### SERIALIZABLE

- 가장 엄격한 격리 수준
- 트랜잭션을 순차적으로 진행
- 여러 트랜잭션이 동일한 레코드에 동시 접근 불가능.
- 순차적으로 트랜잭션이 처리되어야 하므로 동시처리 성능이 매우 떨어짐
- MySQL에서 SELECT FOR SHARE/UPDATE는 대상 레코드에 읽기 쓰기 잠금을 걸음.
- 순수한 SELECT는 아무런 레코드 락이 없는데, SERIALIZABLE 격리 수준에서는 순수한 SELECT에서도 대상 레코드에 넥스트 키락을 읽기 잠금을 걸음.

DB 동시성 제어에 대해서 설명해주세요.

> `동시성 제어`는 여러개의 트랜잭션이 작업을 성공적으로 마칠 수 있도록 **트랜잭션의 실행 순서를 제어**하는 기법입니다. 이를 통해 데이터 무결성 및 일관성을 보장할 수 있습니다. 이를 위한 방법으로 Lock, TimeStamp, MVCC 등의 기법들이 있습니다.
> 

### 동시성 제어

- 여러개의 트랜잭션이 작업을 성공적으로 마칠 수 있도록 트랜잭션의 실행 순서를 제어하는 기법
- 목적
    - 트랜잭션의 직렬성 보장
    - 공유도 최대, 응답시간 최소, 시스템 활동의 최대 보장
    - 데이터 무결성 및 일관성 보장
- 동시성 제어를 하지 않은 경우 발생하는 문제점
    - **갱신손실(Lost Update)**
        - 하나의 트랜잭션이 갱신한 내용을 다른 트랜잭션이 덮어씀으로써 **갱신이 무효화**되는  것을 의미.
        - 두개이상 트랜잭션이 한개의 **데이터를 동시에 Update**할 때 발생.
    - **현황 파악 오류(Dirty Read)**
        - 읽기 작업을 하는 트랜잭션 1이 쓰기 작업을 하는 트랜잭션 2가 **작업한 중간에 데이터**를 읽기 때문에 발생하는 문제.
        - 작업중인 트랜잭션 2가 작업을 롤백한 경우 트랜잭션 1은 무효가 된 데이터를 읽게되고 잘못된 결과를 도출
    - **모순성(Inconsistency)**
        - 다른 트랜잭션들이 해당 항목 값을 갱신하는 동안 한 트랜잭션이 두개의 항목 값 중 **어떤 것은 갱신되기 전의 값을 읽고 다른 것은 갱신된 후의 값을 읽게되어** 데이터의 불일치가 발생하는 상황
    - **연쇄 복귀(Cascading Rollback)**
        - 두 트랜잭션이 **동일한 데이터 내용을 접근**할 때 발생
        - 한 트랜잭션이 데이터를 갱신한 다음 실패하여 Rollback 연산을 수행하는 과정에서 갱신과 Rollback 연산을 실행하고 있는 사이에 해당 데이터를 읽어서 사용할 때 발생할 수 있는 문제.
- 기법
    - Lock
        - shared Lock
        - Exclusive Lock
    - 2 Phase Locking
    - Timestamp Ordering
        - 트랜잭션을 식별하기 위하여 DBMS가 부여하는 유일한 식별자인 타임스탬프를 지정하여 트랜잭션 간의 순서를 미리 선택하는 동시성 제어 기법
        - 시스템에 들어오는 트랜잭션의 순서대로 시간 스탬프를 지정하여 동시성 제어의 기준으로 사용
        - 교착 상태를 방지하지만 Rollback 발생률이 높고 연쇄 복귀를 초래할 수 있음.
    - Validation
        - 트랜잭션을 수행하는 동안 어떠한 검사도 하지 않고, 트랜잭션 종료시에 일괄적으로 검사하는 기법
        - 트랜잭션 수행동안 그 트랜잭션을 위해 유지되는 데이터 항목들의 지역 사본에 대해서만 갱신이 이루어짐.
        - 트랜잭션 종료시에 동시성을 위한 트랜잭션 직렬화가 검증되면 일시에 DB로 반영
    - MVCC

| 기법 | 장점 | 단점 |
| --- | --- | --- |
| Locking(2PL) | 1. 데이터 오류 가능성 예방
2. 간단한 알고리즘 | 1. Lock 대기 시간 발생
2. Deadlock 발생 |
| Timestamp | 1. Dealock 발생 없음
2. 트랜잭션 대기 시간 없음 | 1. Rollback 발생확률 낮음
2. Cascading Rollback 가능 |
| Validation | 1. 동시 처리 능력 증가
2. 트랜잭션 대기 시간 없음 | 1. 장기 트랜잭션 철회시 자원낭비 |
| MVCC | 1. 최근 데이터 값을 선택
2. 동시성, 일관성 동시 해결 | 1. Undo 블록 IO에 따른 오버헤드 발생 |

갱신 손실 문제에 대해 설명해주세요.

> `갱신 손실 문제`는 **하나의 트랜잭션이 갱신한 내용을 다른 트랜잭션이 덮어씀으로써 갱신이 무효화** 되는 것을 의미합니다. 두개 이상의 트랜잭션이 한개의 데이터를 동시에 갱신할 때 발생하는 것으로 Lock을 통해서 해결가능합니다.
> 

### 갱신 손실 문제

- 하나의 트랜잭션이 갱신한 내용을 다른 트랜잭션이 덮어씀으로써 갱신이 무효화 되는 것.
- 두개 이상의 트랜잭션이 한개의 데이터를 동시에 갱신할 때 발생
    • DB 락에 대해서 설명해주세요.Locking 기법
      • Locking은 하나의 트랜잭션이 실행하는 동안 특정 데이터 항목에 대해서 다른 트랜잭션이 동시에 접근하지 못하도록 Mutual Exclusive 기능을 제공하는 기법
      • 종류
        • Shared lock
          • 읽기 연산만 가능
          • 하나의 데이터 항목에 대해 여러개의 공유 잠금이 가능
        • Exclusive lock
          • 배타 잠금을 설정한 트랜잭션은 데이터 항목에 대해서 읽기 연산과 쓰기 연산 가능
          • 동시에 여러개의 배타 잠금 불가능
      • 잠금 단위 ⇒ 잠금의 대상이 되는 데이터 객체의 크기를 의미.
        • 레코드의 필드 값. 레코드, 디스크 블럭, 테이블, 데이터베이스까지 하나의 잠금 단위가 될 수 있음.
        • 잠금 단위가 클수록 동시성 수준은 낮아지고 동시성 제어 기법은 간단해짐
        • 잠금단위가 작을 수록 동시성 수준은 높아지고 관리가 복잡해짐.
    •  

DB 락은 하나의 트랜잭션이 실행되는 동안 특정 데이터 항목에 대해서 다른 트랜잭션이 동시에 접근하지 못하도록 하는 기법으로 종류로는 Shared Lock과 Exclusive Lock이 있습니다. 잠금 단위는 레코드의 필드 값부터 테이블, 데이터베이스까지 될 수 있습니다.

    •  
    • DB 데드락에 대해서 설명해주세요.데드락
      • 두 트랜잭션이 각각 Lock을 정하고 다음 서로의 Lock에 접근하여 값을 얻어오려고 할 때 이미 각각의 트랜잭션에 의해 Lock이 설정되어 있기 때문에 양쪽 트랜잭션 모두 영원히 처리되지 않는 상태.
      • 데이터의 일관성과 무결성을 유지
      • 종류
      • row-level lock
        • shared lock
          • 데이터를 읽을 때 사용하는 Lock
          • Select문과 같이 클라이언트가 읽기 작업하는 데이터 영역
          • 하나의 데이터 항목에 대해서 동시에 두개 이상의 S-lock 설정이 가능.
        • exclusive lock
          • 데이터를 변경할 때 사용하는 lock
          • 트랜잭션이 완료될 때까지 Exclusive lock이 끝나기 전까지 어떠한 접근도 허용하지 않는다.
      • Table-level lock(Intention lock)
        • SQL server에서 shared lock이나 exclusive lock
      • Record lock
        • DB의 Index record에 걸리는 lock
        • shared lock과 exclusive lock
      • gap lock
        • 실제 존재하는 인덱스 레코드에 락을 거는 것이 아니고 범위를 지정하기 위해 인덱스 레코드 사이의 범위에 락을 거는 것.
        • DB index record의 gqp에 걸리는 lock ⇒ gap이란 index 중 DB에 record가 없는 부분.
        데드락 발생 줄이기
      • 인덱스 설정 → 인덱스가 없으면 Lock이 걸리는 범위가 훨씬 넓어지기 때문에 교착상태가 발생하기 쉬워진다. ex) update
      • Isolation Level 조정
        • 1) READ UNCOMMITED : Share-lock 사용안함.
        • 2) READ COMMITED : 매번의 read 마다 Consistent read를 통한 새로운 snap shot을 생성하며, Share-lock을 사용안함
        • 3) REPEATABLE READ : Shared Lock도 트랜잭션 종료시까지 지속된다. UPDATE, DELETE 상태일때 unique index에 대해 찾으면 → index record에만 lock (record lock)
        • range-type (범위로) 찾으면 → gap lock 사용
        • 4) SERIALIZABLE : Shared Lock이 트랜잭션 종료시까지 지속된다.
      • Lock Timeout 설정 ( 트랜잭션 처리속도를 최소화 )
      • 프로시저 우선순위 설정. 트랜잭션 진행방향을 같은방향으로 처리
      • 데드락 발생시 DBMS는 둘 중 한 트랜잭션에 에러를 발생시킴으로써 문제를 해결.
    •  

DB 데드락두 트랜잭션의 Lock을 논리적으로 설정을 잘못하여 두 트랜잭션 모두 기다리고 있는 상태를 의미합니다. 이를 예방하기 위해서는 개발자가 Lock을 사용할 때에는 논리적으로 설계를 해야합니다.

    •  
    • DB 회복에 대해서 설명해주세요.DB 회복
      • 트랜잭션들을 수행하는 도중 장애로 인해 손상된 데이터 베이스를 손상되기 이전의 정상적인 상태로 복구시키는 작업.
      • 유형
        • 트랜잭션 장애: 트랜잭션의 실행 시 논리적인 오류로 발생하는 에러
        • 시스템 장애: HW 시스템 자체에서 발생할 수 있는 에러
        • 미디어 장애: 디스크 자체의 손상으로 발생할 수 있는 에러
        로그
      • 트랜잭션이 반영한 모든 데이터의 변경사항을 데이터베이스에 기록하기 전에 미리 기록해두는 별도의 데이터베이스
      • 안전한 하드디스크에 저장되며 전원과 관계없이 기록이 존재
      • 로그의 구조: <트랜잭션 번호, 로그의 타입, 데이터 항목 이름, 수정 전 값, 수정 후 값>
      • 로그의 타입: START, INSERT, UPDATE, DELETE, ABORT, COMMIT 등 트랜잭션의 연산 타입
      • 로그파일을 이용한 복구
        • 로그파일에 트랜잭션의 시작(START)과 종료(COMMIT)가 있는 경우 REDO 수행
        • 로그파일에 트랜잭션의 시작(START)은 있고 종료(COMMIT)는 없는 경우 UNDO 수행
    •  

DB 회복은 트랜잭션을 수행하는 도중 장애로 인해 손상된 데이터베이스를 손상되기 전 상태로 복구시키는 작업으로 REDOUNDO를 통해 복구합니다.

  •  

REDO, UNDO에 대해서 설명해주세요.

> `UNDO`는 트랜잭션 **로그를 이용**하여 오류와 관련된 모든 변경을 **취소하여 복구**를 수행하고, `REDO`는 트랜잭션 **로그를 이용**하여 오류가 발생한 트랜잭션을 **재실행하여 복구를 수행**하는 것을 의미합니다.
> 

### REDO, UNDO

- REDO
    - 영속성을 보장
    - 무언가를 다시하는 행위(복구)
    - **REDO**는 복구를 할때 사용자가 했던 작업을 그대로 다시
- UNDO
    - 원자성을 보장
    - 무언가를 되돌리는 것.(작업 롤백, 읽기 일관성, 복구)
    - **UNDO**는 사용자가 했던 작업을 반대로 진행
    - 기록되는 데이터
        - INSERT시, insert된 로우의 id 기록
        - UPDATE시, 바뀐 칼럼의 바뀌기 전 값 기록
        - DELETE시, 지워진 모든 데이터 기록
- 복구 방법의 차이
    - UNDO를 통해 복구. ⇒ ROLLBACK
    - 시스템의 장애가 발생하면 UNDO 데이터도 모두 날아감
    - 시스템 장애시 REDO 데이터를 이용해서 마지막 CHECK POINT부터 장애까지 DB BUFFER CACHE를 복구. 이후 UNDO를 이용하여 COMMIT되지 않은 데이터를 모두 ROLLBACK 함으로써 복구 완료.

체크포인트 회복 기법에 대해서 설명해주세요.

> `체크포인트 회복 기법`은 **DB 회복을 하는 방법**으로 지연 갱신 회복 기법, 즉시 갱신 회복 기법 등이 있습니다.
> 

### 회복 기법

- 지연 갱신 회복 기법
    - 트랜잭션 커밋 완료까지 갱신 내용을 로그에 저장하고 DB에 저장하지 않고 지연
    - 중간에 갱신을 하지 않았으므로 undo는 필요 없고 원자성 보장
    - REDO만 하면 됨.
- 즉시 갱신 회복 기법
    - 데이터 변경 시 로그와 DB에 즉시 갱신
    - 커밋되기 전에 장애가 나면 UNDO 커밋 후에 장애가 나면 Redo
- 체크포인트 회복 기법
    - REDO, UNDO를 해야할 트랜잭션을 결정하기 위해서 이론적으로 로그 전체를 확인해야하는데 시간 소요 및 REDO. 필요없는 트랜잭션을 REDO해야하는 문제를 해결하는 기법
    - UNDO를 수행하여 회복하는 것을 후진 회복, REDO를 수행하여 회복하는 것을 전진회복.
- 그림자 페이징 회복 기법
    - 로그를 사용하지 않고 트랜잭션 실행동안 현재 페이지 테이블과 그림자 페이지 테이블 2개 관리기법.
    - 데이터 변경시 현재 테이블만 변경, 회복 시 현재 페이지 테이블을 그림자 테이블로 대체
    - UNDO 연산이 간단하며, REDO 연산이 필요 없기에 신속한 회복 가능
    - DB 페이지 변경 시 물리적 위치의 변경으로 인해 단편화가 발생.
- 미디어 회복 기법
    - 비휘발성 저장장치가 손상될 경우 사용되는 회복 기법
    - 주기적으로 데이터를 덤프하여 장애 시 최근 덤프를 DB에 적재
    - 덤프를 다른 저장소에 옮길 때 대용량 데이터 전송이 필요하며 이때 트랜잭션 처리를 중단해야하기에 CPU 낭비가 되어 비용이 많이 소모

MySQL InnoDB의 기본 트랜잭션 고립 수준은 뭘까요?

> `REPEATABLE READ`입니다. 바이너리 로그를 가진 MySQL의 장비에서는 최소 REPEATABLE READ 격리 수준 이상을 사용해야 한다고 합니다. InnoDB 스토리지 엔진은 트랜잭션이 ROLLBACK될 가능성에 대비해 변경되기 전 레코드를 `언두(Undo) 공간`에 백업해두고 실제 레코드 값을 변경합니다. 이러한 변경 방식을 `MVCC`라고 합니다.
>

'Database > JSCode' 카테고리의 다른 글

[JSCode] Database 면접 스터디 회고록  (3) 2023.12.08
[JSCode] Database Week4  (0) 2023.11.28
[JSCode] Database Week3  (1) 2023.11.21
[JSCode] Database Week2  (2) 2023.11.14
[JSCode] Database Week1  (1) 2023.11.07

이상 현상이 뭘까요?

이상현상은 데이터베이스의 테이블을 설계를 잘못하여 데이터를 가공할 때 데이터의 무결성이 깨지는 현상을 말합니다. 그 유형으로는 삽입이상, 갱신이상, 삭제이상으로 구성되어 있습니다.

 이상현상

  • 정규화를 거치지 않은 릴레이션에서 발생할 수 있는 이상 현상.
  • 데이터들이 불필요하게 중복.
  • 속성들의 종속관계를 하나의 릴레이션에 표현하기에 발생.
  • 삽입이상
    • 데이터 삽입 시 의도와 다른 값들도 삽입되는 것.
  • 삭제이상
    • 데이터 삭제 시 의도와 다른 값들도 연쇄 삭제되는 것.
  • 갱신이상
    • 데이터 갱신 시 일부 튜플만 갱신되어 모순 발생.
  • 데이터 정규화를 통해 해결.
    학번 이름 나이 성별 강의코드 강의명 전화번호
    1011 이태호 23 AC1 데이터베이스 개론 010-1234-5678
    1012 강민정 20 AC2 운영체제 010-5325-6913
    1013 김현수 21 AC3 자료구조 010-5830-3291
    1013 김현수 21 AC4 웹 프로그래밍 010-5830-3291
    1014 이병철 26 AC5 알고리즘 010-2348-5892

삽입 이상(Insertion Anomaly)에 대해서 설명해주세요.

삽입이상은 자료를 삽입할 때 의도하지 않은 자료까지 삽입해야만 자료를 테이블에 추가 가능한 현상을 말합니다. 위 테이블을 기준으로 강의를 아직 수강하지 않는 학생에게는 null값이 들어가야하는 문제가 생기는 경우를 의미합니다.

갱신 이상(Update Anomaly)에 대해서 설명해주세요.

갱신이상이란 중복된 데이터 중 일부 데이터만 수정되어 데이터 간의 일관성이 깨지는 현상을 의미합니다. 강의코드 AC3의 김현수의 전화번호를 변경할 때 1013의 김현수의 전화번호가 모두 바뀌어야 하는데 AC3의 데이터에 해당하는 김현수의 전화번호만 바뀌는 현상을 의미합니다.

삭제 이상(Deletion Anomaly)에 대해서 설명해주세요.

삭제이상이란 정보를 삭제할 때 의도하지 않은 정보까지 삭제되어 버리는 현상을 의미합니다. AC1인 데이터베이스 개론의 강의를 삭제하게 되면 이태호 학생의 데이터까지 삭제되는 현상이 발생합니다.

함수 종속성이 무엇인가요?

함수 종속성이란 속성들 간의 관련성을 말합니다. 이를 이용하여 이상현상을 예방할 수 있도록 릴레이션을 설계하는 과정이 정규화입니다.
    • 함수 종속성
      • 릴레이션의 속성 A와 B에 대해서 A값에 의해 B값이 유일하게 정해지는 관계
        (B는 A에 함수 종속이다. A → B, A는 결정자, B는 종속자)
      • 완전 함수 종속
        • 기본키를 구성하는 모든 속성에 종속되는 경우
      • 부분 함수 종속
        • 기본키를 구성하는 속성의 일부에 종속되거나, 기본키가 아닌 다른 속성에 종속되는 경우
      • 이행적 함수 종속
        • A→B, B→C가 종속관계일 때 A→C가 성립하는 경우
        학번 이름 학년 과목번호 성적
                 
      • 위와 같은 릴레이션이 있을 때(기본키: (학번, 과목번호)) 
      • 학생은 이름, 학번만 알아도 유일하게 결정.
      • 성적은 (학번, 과목번호)로 유일하게 결정
      • 학년과 이름은 (학번, 과목번호)에 대해 부분 함수 종속
      • 성적은 완전함수 종속

완전 함수적 종속은 뭔가요?

완전 함수적 종속은 X의 값이 Y의 값에 모두 포함되어 있는 것을 의미합니다

부분 함수적 종속은 뭔가요?

부분 함수적 종속은 X의 부분집합이 Y에 종속되어 있을 때를 의미합니다.

이행적 함수적 종속은 뭔가요?

이행적 함수적 종속은 함수 종속 관계가 X → Y, Y → Z일 때 논리적으로 X → Z가 성립될 때 Z가 X에 이행적으로 함수에 종속되었다고 합니다.
이름 성별 주소 지역
       
  • X(이름, 성별) → Y(주소)
  • Y(주소) → Z(지역)
  • X(이름, 성별) → Z(지역)
  • X → Z

정규화(Normalization)에 대해서 설명해주세요.

정규화는 데이터의 이상현상을 예방하고 효과적인 연산을 하기위한 기법으로, 릴레이션 간의 함수 종속성을 파악하여 기본키와 외래키를 이용하여 릴레이션을 효과적으로 설계하는 과정을 의미합니다.

 정규화

  • 속성간의 종속성으로 인해 발생하는 이상현상을 릴레이션 설계 시에 제약조건을 통해서 이상현상을 없애는 과정.
  • 정규형의 차수가 높아질수록 제약사항이 많아지고 엄격해지지만 이상현상의 발생 가능성이 떨어진다.
  • 릴레이션의 특성에 따라서 적합한 정규형을 선택해야함.

장점

  • 이상현상 해결
  • 속성의 구조 추가로 인해 DB 구조를 확장하는 경우, 구조 변경 최소화

제 1 정규형에 대해서 설명해주세요.

제 1정규형은 릴레이션의 모든 속성의 도메인이 원자 값만으로 구성되어 있어야한다는 특성으로 예를 들어~~

제 1 정규형

  • 제 1 정규형만 지킨다면 데이터 중복 이상현상이 발생할 수 있다.
  • 기본키에 완전 함수 종속되지 못한 칼럼이 있다면 갱신, 삭제, 삽입 이상이 일어날 가능성 존재.
    부분 함수적 종속을 제거하여 제 2 정규형을 만족하도록.
    학번 과목코드
    CS123 B31, A15
    CS345 N04
    학번 과목코드
    CS123 B31
    CS123 A15
    CS345 N04
  • 왼쪽 테이블의 과목코드의 칼럼이 원자 값이 아님.
  • 오른쪽 테이블로 변경해야함.

제 2 정규형에 대해서 설명해주세요.

제 2정규형은 릴레이션이 제1 정규형에 속하고, 기본키가 아닌 모든 속성이 기본키에 완전 함수 종속되어야 한다는 특성으로 예를 들어~~
학번 과목코드 성적 강의실
CS123 B31 80 1공 502
CS123 A15 90 1공 503
CS345 N04 87 클러스터 402

 

  • 테이블의 기본키: (학번, 과목코드)
  • (학번, 과목코드) -> 성적
  • (과목코드) -> 강의실
학번 과목코드 성적
CS123 B31 80
CS123 A15 90
CS345 N04 87
과목코드 강의실
B31 1공 502
A15 1공 503
N04 클러스터 402
  • 테이블을 분리하여 제 2정규형 만족

제 2 정규형

  • 이행적 함수 종속이 존재하면 갱신이상이 가능.
    이행적 함수 종속을 제거하여 제 3정규형을 만족하도록

제 3 정규형에 대해서 설명해주세요.

제 3 정규형은 릴레이션이 제 2 정규형에 속하고, 모든 속성이 기본키에 이행적 함수 종속되지 않아야한다는 특성으로 예를 들어~~
학번 과목코드 수강료
CS123 B31 70000
CS123 A15 45000
CS345 N04 70000

 

  • 기본키: 학번
  • 학번 -> 과목코드
  • 과목코드 -> 수강료
  • 학번 -> 과목코드
학번 과목코드
CS123 B31
CS123 A15
CS345 N04
과목코드 수강료
B31 70000
A15 45000
N04 70000
  • 학번 -> 과목코드
  • 과목코드 -> 수강료 분리
  • 이를 통해 갱신 이상 해결 가능

BCNF 정규형에 대해서 설명해주세요.

BCNF 정규형은 제 3 정규화를 진행한 테이블에 대해 모든 결정자가 후보키가 되도록 테이블을 분해하는 것으로
학번 과목명 담당교수
100 C123 P1
100 C234 P2
200 C123 P1
300 C234 P3
400 C234 P4
 
  • 3 정규형은 만족하지만 다음과 같은 이상 현상 가능
    • 삽입이상: 새로운 교수가 특정 과목을 담당한다는 새로운 정보를 추가할 수 없다. 적어도 한 명 이상의 수강 학생이 필요하다.
    • 갱신이상: 학번 100이 C234 과목을 취소하면, P2가 C234 과목을 담당한다는 정보도 삭제된다.
    • 삭제이상: 삭제 이상 : - 갱신 이상 : P1의 과목이 변경되면 P1인 행을 모두 찾아 변경시켜주어야 한다.
  • 원인은 결정자(Determinant)가 후보키(Alternative Key)로 취급되고 있지 않기 때문이다.
  • 후보키는 슈퍼키(super key) 중에서 최소성을 갖는 키이므로 이 릴레이션에서는 (학번, 과목명)이나 (학번, 담당교수)가 후보키가 된다.
  • 담당 교수만으로는 후보키가 될 수 없다. 하지만, 후보키가 아님에도 과목명을 결정할 수 있기 때문에 담당 교수는 결정자에 속한다. 
    학번 담당교수
    100 P1
    100 P2
    200 P1
    300 P3
    400 P4
    담당교수 과목명
    P1 C123
    P2 C234
    P3 C234
    P4 C234

반정규화에 대해서 설명해주세요.

반정규화는 정규화를 통해 릴레이션을 디자인할 시 릴레이션의 분해나, 데이터베이스의 성능이 떨어지는 결과를 초래할 수 있습니다. 따라서 이러한 경우를 예방하기 위한 기술로 종류로는 테이블 통합/분할/추가/중복 속성 추가등이 있습니다. 반정규화 과정을 거치게 되면 데이터의 일관성이나 무결성이 보장되지 않을 수 있기에 개발자가 데이터 관리를 더욱 신경써야합니다.

 반정규화

  • 시스템의 성능 향상을 위해 정규화된 데이터 모델을 통합하는 작업
  • 종류
    • 테이블 통합
    • 테이블 분할
    • 테이블 추가
    • 중복 속성 추가
  • 시스템의 성능 향상
  • 데이터의 일관성이나 무결성 보장 불가능
    • 검색기능 향상
    • 갱신, 삭제 성능 낮아짐
  • 대상
    • 수행 속도가 많이 느린 경우
    • 테이블의 JOIN연산을 지나치게 사용하여 데이터를 조회하는 것이 어려운 경우
    • 테이블에 많은 데이터가 있고, 다량의 범위 혹은 특정 범위를 자주 처리해야하는 경우.

'Database > JSCode' 카테고리의 다른 글

[JSCode] Database 면접 스터디 회고록  (3) 2023.12.08
[JSCode] Database Week5  (2) 2023.12.05
[JSCode] Database Week3  (1) 2023.11.21
[JSCode] Database Week2  (2) 2023.11.14
[JSCode] Database Week1  (1) 2023.11.07

+ Recent posts