DB

데이터베이스, 한재엽님의 Part 1-5 데이터베이스를 기반으로 여러분들의 블로그를 참조!

데이터베이스

데이터베이스

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

기존의 파일 시스템을 이용한 데이터 관리의 경우

  • 데이터 종속성
  • 데이터 중복성
  • 데이터 무결성 의 문제가 존재
데이터베이스의 특징
  1. 데이터 독립성
    • 물리적 독립성 : 데이터베이스의 사이즈를 늘리거나, 성능향상을 위한 데이터 파일 증가 및 신규 추가에도 응용프로그램을 수정할 필요가 없음
    • 논리적 독립성 : 데이터베이스는 논리적 구조를 통해 다양한 응용 프로그램의 논리적 요구 충족 가능
  2. 데이터 무결성
    • 여러 경로를 통해 잘못된 데이터가 발생하는 경우를 방지, 데이터 유효성 검새를 통해 데이터 무결성 구현
  3. 데이터 보안성
    • 인가된 사용자만을 접근허용하도록 계정 및 접근 권한 관리
  4. 데이터의 일관성
    • 연관된 정보를 논리적 구조로 관리하여 데이텨 변경에 따른 데이터 불일치성을 배제
    • 작업 중 일부 데이터만 변경되어 나머지 데이터와 일치하지 않는 경우 배제
  5. 데이터 중복 최소화
    • 데이터 통합 관리를 통해 자료의 중복문제 해결

** 무결성(Integrity)와 일관성(consistency)의 차이에 관한 stackoverflow

데이터베이스의 성능

  • 데이터베이스의 성능 이슈는 디스크I/O 시간의 단축과 직결
  • 보통 순차 I/O가 랜덤 I/O보다 빠름
  • DB 쿼리 튜닝을 통해 랜덤 I/O를 줄이는 것이 중요


Index

인덱스(Index)란 무엇인가?

  • DBMS에서 테이블의 모든 데이터를 검색하여 결과를 가져온다면 시간이 오래 걸림
  • 따라서, 칼럼의 값과 해당 레코드가 저장된 주소를 키-값의 쌍으로 인덱스를 만들어 둠
  • DBMS의 인덱스는 항상 정렬된 상태를 유지하므로 원하는 값을 탐색하는 경우에는 빠르지만, 새로운 값을 추가하거나, 삭제, 수정하는 경우에는 느림
  • 즉, DBMS에서 인덱스는 데이터의 저장 성능을 희생하여 데이터의 읽기 속도를 높임
  • 너무 많은 컬럼을 인덱스로 생성시 데이터 저장 성능이 떨어지며, 인덱스의 크기가 비대해져 역효과가 생김

Index 자료구조

B+-Tree 인덱스 알고리즘

  • 일반적으로 사용되는 알고리즘
  • 칼럼의 값을 변경하지 않고 원래의 값을 이용해 인덱싱
  • 자세한 내용은 추후 필요시 공부..

Hash 인덱스 알고리즘

  • 칼럼의 값으로 해시 값을 계산하여 인덱싱(매우 빠른 검색)
  • 값의 일부만으로 인덱싱 검색이 불가
  • 메모리 기반의 데이터 베이스에서 사용

index 생성에 b-tree를 사용하는 이유

  • 부등호 연산을 포함한 검색기능의 지원을 위함

Primary Index vs Secondary Index

  • 인덱스에서 클러스터드는 비슷한 것들을 묶어 저장하는 형태인데 주로 비슷한 값을 동시에 조회하는 경우가 많음에 착안한 것임
    • 비슷한 값이란 물리적으로 인접한 장소에 저장된 데이터
  • 클러스터드 인덱스는 테이블의 프라이머리 키에 대해서 적용되는 것으로, 프라이머리 키 값이 비슷한 레코드끼리 묶어서 저장하는 것을 클러스터드 인덱스라 칭함
    • 클러스터드 인덱스에서는 프라이머리 키 값에 의해 레코드의 저장 위치가 결정되며, 프라이머리 키값이 변경되면, 물리적 위치 또현 변경
  • 클러스터드 인덱스는 테이블 당 한 개만 생성이 가능(프라이머리 키에 의해 적용되기 때문)
  • 다만 non 클러스터드 인덱스는 테이블에 여러개 생성 가능

Composite Index

  • 인덱스로 설정하는 필드의 속성이 중요
  • title, author의 순서로 인덱스 설정시, title검색은 index효과를 보지만, author만을 검색하는 경우에는 효과 없음

Index의 성능과 고려사항

  • Index생성 시 Insert, Delete, Update쿼리 실행 시 별도의 과정이 추가로 수행되므로 무분별한 인덱싱이 좋은 것은 아님
  • 컬럼을 이루고 있는 데이터의 형식에 따라 인덱스의 성능이 다르므로 데이터 형식에 따라 선택적으로 인덱싱 필요
    • 이름, 나이, 성별 세 가지 필드를 갖고 있는 테이블에 대해서는
    • 이름에 대해서만 인덱싱 하는 것이 가장 효율 적임
    • 나이와 성별과 같은 값은 range가 적어 의미가 없으며, 필요시에는 bitmap index를 사용


정규화에 대해서

1. 정규화는 어떤 배경에서 생겨났는가?

  • 하나의 릴레이션에 여러 entity의 attribute를 혼합하게되면 정보가 중복 저장되며, 저장 공간을 낭비하게 됨
  • 중복된 정보는 갱신 이상의 상황을 발생 시킴
1-1 갱신이상의 종류
  • 삽입 이상(Insertion anomalies)
    • 원하지 않는 자료의 삽입
    • 삽입 과정에서 자료의 부족 등으로 인해 삽입 되지 않는 문제 등
  • 삭제 이상(deletion anomalies)
    • 하나의 자료만을 삭제하고 싶은 경우에 그 자료가 포함된 튜플 전체가 삭제되어 원하지 않는 정보의 손실 발생
  • 수정 이상(modification anomalies)
    • 정확하지 않은 혹은 전체 수정 정보의 일부만 갱신되어 정보의 일관성이 없어짐

2. 정규화란?

  • 관계형 데이터베이스에서 중복을 최소화하기 위해 데이터를 구조화 하는 작업
  • 불만족스러운 나쁜 릴레이션의 애트리뷰트를 나누어 좋은 작은 릴레이션으로 분해하는 작업
  • 정규화과정을 거치면 정규형을 만족하게 되며, 정규형은 특정 조건을 만족하는 릴레이션의 스키마 형태를 일컫음
    • 제 1정규형, 제 2정규형, 제 3정규형 등이 존재
2-1 나쁜 릴레이션의 파악
  • 엔티티를 구성하는 애트리뷰트 간의 종속성(Functional Dependency)를 판단
  • 판단된 함수적 종속성은 좋은 릴레이션 설계의 정형적 기준으로 사용
    • 각 정규형마다 어떠한 함수적 종속성을 만족하는지에 따라 정규형이 정의
    • 정규형이 만족되지 않는 경우 나쁜 릴레이션으로 간주
2-2 함수의 종속성이란?
  • 애트리뷰트 데이터들의 의미와 애트리뷰트들 간의 상호 관계로부터 유도되는 제약조건의 일종
  • X와 Y를 임의의 애트리뷰트 집합이라고 할 때, X의 값이 Y를 유일하게 결정한다면 X는 Y를 함수적으로 결정
  • 함수적 종속성은 실세계에서 존재하는 애트리뷰트들 사이의 제약조건으로 부터 유도
  • 애트리뷰트들의 관계로부터 추론된 함수적 종속성들을 기반으로 추론 가능한 모든 함수적 종속성들의 집합을 폐포(closure)라함
2-3 각각의 정규형은 어떠한 조건을 만족해야 하는가?
  1. 분해의 대상인 분해 집합 D는 무손실 조인을 보장해야 함
  2. 분해 집합 D는 함수적 종속성을 보존해야 함
제1정규형
  • 애트리뷰트의 도메인이 오직 원자값만을 포함
  • 튜플의 모든 애트리뷰트가 도메인에 속하는 하나의 값을 가져야 함
  • 복합 애트리뷰트, 다중값 애트리뷰트, 중첩 릴레이션 등 비 원자적 애트리뷰트를 허용하지 않는 릴레이션 형태
제2정규형
  • 모든 비주요 애트리뷰트들이 주요 애트리뷰트에 대해 완전 함수적 종속이면 제2정규형을 만족
  • 완전 함수적 종속이란 X->Y라고 가정했을때에 X의 어떠한 애트리뷰트라도 제거하면 더 이상 함수적 종속이 성립되지 않는 경우
  • 키가 아닌 열들이 후보키에 대해 결정되는 릴레이션 형태
제3정규형
  • 어떠한 비주요 애트리뷰트도 기본키에 대해서 이행적으로 종속되지 않으면, 제3정규형을 만족
  • 이행 함수적 종속 : X->Y, Y->Z의 경우에 의해 추론되는 X->Z의 종속관계
  • 비주요 애트리뷰트가 비주요 애트리뷰트에 의해 종속되는 경우가 없는 릴레이션 형태
BCNF(Boyce-Codd) 정규형, 야붕님의 BCNF정리
  • 여러 후보키가 존재하는 릴레이션에 해당하는 정규화 내용
  • 복잡한 식별자 관계에 의해 발생하는 문제의 해결을 위해 제3정규형을 보완하는데 의미가 있음
  • 비주요 애트리뷰트가 후보키의 일부를 결정하는 경우에 대한 분해 과정
각 정규형은 그의 선행 정규형보다 더 엄격한 조건을 가짐
  • 모든 제2정규형 릴레이션은 제1정규형을 가짐
  • 모든 제3정규형 릴레이션은 제2정규형을 가짐
  • 모든 BCNF정규형 릴레이션은 제3정규형을 가짐
  • 수많은 정규형이 있지만 관계 데이터베이스 설계의 목표는 각 릴레이션이 3NF(or BCNF)를 갖게 하는 것

3. 정규화의 장점

  1. 데이터베이스변경 시 이상 현상(Anomaly) 제거
    • 위에서 언급되었던 각종 이상 현상들의 발생 문제점을 해결 할 수 있음
  2. 데이터베이스 구조 확장 시 재 디자인 최소화
    • 정규화된 데이터베이스 구조에서 새로운 데이터 형의 추가로 인한 확장 시, 그 구조를 변경하지 않아도 되거나, 일부만 변경 가능
    • 데이터베이스와 연동된 응용 프로그램에 최소한의 영향만 미치게 되며, 응용프로그램의 생명을 연장
  3. 사용자에게 데이터 모델을 더욱 의미있게 제공
    • 정규화된 테이블들과 정규화된 테이블들간의 관계들은 현실 세계의 개념과 그들간의 관계를 반영

4. 정규화의 단점

  • 릴레이션의 분해로 인해 릴레이션 간의 연산(JOIN)이 빈번해짐
  • 질의에 대한 응답시간이 느려질 수 있음
  • 정규화의 수행은 데이터를 결정하는 결정자에 의해 함수적 종속을 가지고 있는 일본 속성을 의존자로하여 입력/수정/삭제 이상을 제거하는 것
  • 데이터의 중복 속성을 제거하고, 결정자에 의해 동일한 의미의 일반 속성이 하나의 테이블로 집약되므로 한 테이블의 데이터 용량이 최소화 됨
    • 따라서 정규화된 테이블이 반드시 속도의 향상을 가져오는 것은 아님

5. 단점에 관하여, 정규화가 적합한 상황

  • 조회 상황에서 SQL문장의 많은 JOIN으로 인해 성능 저하가 큰 문제가 되는 경우 반정규화를 적용
반정규화(De-normalization, 비정규화)
  • 정규화된 엔티티, 속성, 관계를 시스템의 성능 향상 및 개발과 운영의 단순화를 위해 중복통합, 분리 등을 수행하는 데이터 모델링 기법
  • 디스크 I/O량이 많아서 조회 시 성능이 저하되거나, 테이블끼리의 먼 경로로 인한 조인 성능 저하, 칼럼계산에 따른 성능 저하 등을 줄이기 위해 수행
  • 일반적으로 조회에 대한 처리 성능이 중요한 경우 반정규화를 고려
5-1 반정규화의 대상
  1. 자주 사용되는 테이블에 액세스하는 프로세스의 수가 가장 많으며, 항상 일정 범위만을 조회하는 경우
  2. 테이블에 대량의 데이터가 있고 대량의 범위를 자주 처리하는 경우에 성능상 이슈가 있을 경우
  3. 테이블에 지나치게 조인을 많이 사용하게되어 데이터를 조회하는 것이 기술적으로 어려운 경우
5-2 반정규화 과정에서의 주의 점
  • 반정규화를 과도하게 적용하다보면 데이터의 무결성이 깨질 수 있음


Transaction

트랜잭션(Transaction)이란?

  • 트랜잭션은 작업의 완전성을 보장해주는 것
  • 논리적 작업셋을 모두 완벽하게 처리하거나 혹은 처리하지 못한 경우에 대해 원 상태로 복원하여 데이터의 무결성을 지키는 것
  • 사용자 입장에서 작업의 논리적 단위 / 시스템의 입장에서는 데이터의 접근, 변경하는 프로그램 단위

트랜잭션과 Lock

  • 잠금(Lock)과 트랜잭션은 서로 비슷한 개념으로 착각될 수 있음
    • 잠금 : 동시성을 제어하기 위한 기능
      • 여러 커넥션에서 동시에 동일한 자원을 요청할 경우 순서대로 한 시점에 하나의 커넥션만 변경할 수 있도록 함
    • 트랜잭션 : 데이터의 정합성을 보장하기 위한 기능
      • 트랜잭션은 하나의 논리적 작업 셋 중 하나의 쿼리가 있든 두 개 이상의 쿼리가 있든 관계없이 논리적인 작업 셋 자체가 100% 적용되거나 아예 적용되지 않거나 함을 보장하는 것

트랜잭션의 특성

트랜잭션은 ACID의 4가지 특성을 만족해야 함

원자성(Atomicity)
  • 트랜잭션 중간에 문제가 발생시, 어떠한 작업도 수행되어서는 안되며, 아무런 문제가 발생되지 않았을때에만 적용되어야 함
일관성(Consistency)
  • 트랜잭션이 완료된 다음의 상태에도 트랜잭션이 일어나기 전의 상황과 동일하게 데이터의 일관성을 보장해야 함
    • ex)금액이 integer형이었으면 트랜잭션 완료 후에도 integer형일 것(String타입으로 바뀌면 안 됨)
고립성(Isolation)
  • 각각의 트랜잭션은 서로의 간섭없이 독립적으로 수행되어야 함
지속성(Durability)
  • 트랜잭션의 정상 종료 이후에는 영구적으로 데이터베이스에 작업의 결과가 저장되어야 함

트랜잭션의 상태

Active
  • 트랜잭션의 활동 상태
  • 트랜잭션이 실행중이며 동작 중임
Failed
  • 트랜잭션 실패 상태
  • 트랜잭션이 더 이상 정상적으로 진행 할 수 없는 상태
Partial Committed
  • 트랜잭션의 Commit 명령이 도착한 상태
  • 트랜잭션의 Commit 이전 Sql문이 실행되고 commit만 남은 상태
Committed
  • 트랜잭션 완료 상태, 트랜잭션이 정상적으로 완료된 상태
Aborted
  • 트랜잭션 취소 상태, 트랜잭션이 취소되고 트랜잭션 실행 이전 데이터들로 돌아간 상태
Partial Committed vs Committed
  • Commit요청이 들어오면 -> Partial Committed, 이후 프로그램이 판단하기에 Commit이 문제없이 수행할 수 있으면 -> Committed, 불가능한 경우 Failed
  • Partial Committed는 Commit 요청이 들어온 때이며, Committed는 정상적으로 완료된 상태

트랜잭션 사용시 주의 점

  • 트랜잭션은 꼭 필요한 곳에 최소한으로 사용하는 것이 바람직
  • 일반적인 데이터베이스의 경우 커넥션 수가 제한적이므로 커넥션 소유 시간이 길면 성능에 좋지 못함

교착상태

교착상태란?
  • 복수의 트랜잭션을 사용하는 경우에 발생할 수 있음
  • 두 개 이상의 트랜잭션이 특정 자원의 잠금을 획득한 채로 다른 트랜잭션이 소유하고 있는 잠금을 요구할 경우
교착 상태의 빈도를 줄이는 법
  • 트랜잭션을 자주 커밋
  • 정해진 순서로 테이블에 접근
  • 읽기 잠금 획득의 사용을 피함
  • 한 테이블의 복수 연결하여 순서를 정하지 않고 갱신할 경우 교착에 쉽게 빠짐
    • 테이블 단위 잠금을 획득하여 갱신을 직렬화 해야함


Statement vs PrepareStatement

  • 속도면에서 PreparedStatement가 빠르다고 알려져 있음
    • 쿼리를 수행하기 전에 이미 쿼리가 컴파일 되어있으므로 반복 수행의 경우 프리 컴파일 된 쿼리를 이용하므로
  • PreparedStatement에는 변수를 설정하고 바인딩하는 Static sql이 사용되며, Statement에서는 쿼리 자체에 조건이 들어가는 dynamic sql이 사용 됨
    • PreparedStatment가 파싱타임면에서는 유리하나, Static sql을 사용하므로 함께 고려해야 함
  • 성능 고려시 시간의 가장 큰 비중을 차지하는 부분은 테이블에서 레코드를 가져오는 과정이므로 SQL Injection 등의 문제를 보완하는 preparedStatement를 사용하는 것이 바람직 (이 내용에 대해서는 추후 추가적인 공부가 필요할 듯)


NoSQL

정의

  • 관계형 데이터 모델을 지양
  • 대량의 분산된 데이터를 저장하고 조회하는데에 특화
  • 스키마없이 사용이 가능하거나, 느슨한 스키마를 제공하는 저장소
  • 종류에따라 쓰기/읽기 성능 특화 2차 인덱스 지원 오토 샤딩 지원 등 고유한 특성을 가짐
  • 대량의 데이터를 빠르게 처리하기 위한 메모리이용 등의 방법 사용
  • 동적인 스케일 아웃을 지원하기도 하며, 가용성을 위해 데이터 복제 등의 방법으로 관계형 데이터베이스가 제공하지 못하는 성능과 특징을 제공

CAP이론

1.일관성(Consistency)
  • 동시성, 동일성이라고도 불리우며, 다중 클라이언트에서 같은 시간에 조회하는 데이터는 항상 동일한 데이터임을 보증하는 것을 의미
  • RDBMS에서는 가장 기본적인 기능이지만, NoSQL에서는 데이터의 일관성이 느슨하게 처리되므로 동일한 데이터가 나타나지 않을 수 있음
    • 느슨하게 처리된다라 함은 데이터의 변경을 시간의 흐름에 따라 여러 노드에 전파하는 것을 말함
  • 따라서 NoSQL의 일관성은 최종 일관성, 궁극적 일관성을 지원
  • 각 NoSQL들은 분산 노드 간의 데이터 동기화를 위하여 두 가지 방법을 사용
    • 첫번째, 데이터의 저장 결과를 클라이언트로 응답하기 전에 모든 노드에 전파
      • 속도가 느리지만, 데이터의 정합성을 보장
    • 두번째, 메모리나 임시 파일에 기록하여 클라이언트에 먼저 응답 후 이벤트나 프로세스를 이용하여 노드로 데이터 동기화
      • 빠른 응답시간을 보이지만, 쓰기 노드에 장애 발생시 데이터 손실 가능성 존재
2.가용성(Availability)
  • 가용성은 모든 클라이언트의 읽기/쓰기 요청에 대해 항상 응답이 가능함을 보증하는 것이며 내고장성이라고도 부름
  • 내고장성을 가진 NoSQL은 클러스터 내에서 몇 개의 노드가 망가지더라도 정상적인 서비스 가능
  • 몇몇 NoSQL의 경우 가용성 보장을 위해 데이터 복제(Replication)을 사용
    • 동일한 데이터를 다중 노드에 중복 저장하여 그 중 몇 대의 노드가 고장나도 데이터가 유실되지 않도록 하는 방법
    • 데이터의 중복 저장 방법은 동일한 동일 데이터를 가진 저장소를 복제하는 Master-Slave와 데이터 단위로 중복 저장하는 Peer-to-Peer가 있음
3.네트워크 분할 허용성(Partition tolerance)
  • 지역적으로 분할된 네트워크 환경에서 동작하는 시스템에서 두 지역 간의 네트워크가 단절되거나, 네트워크 데이터의 유실이 일어나더라도 각 지역 내의 시스템은 정상적으로 동작해야 함

저장방식에 따른 분류

  1. Key-Value Model
    • 가장 기본적형태의 NoSQL
    • 키 하나로 데이터 하나를 저장하며, 조회할 수 있는 단일 키-값 구조
    • 단순 저장구조로 인해 복잡한 조회 연산 불가
    • 고속 읽기/쓰기에 최적화
    • 사용자 프로필, 웹 서버 클러스터를 위한 세션 정보, 장바구니 정보, URL단축 정보 등에 사용
    • 하나의 서비스 요청에 다수의 데이터 조회 및 수정 연산이 발생하면 트랜잭션 처리가 불가능하며, 데이터 정합성의 보장이 어렵다
    • Document Model
    • Column Model
    • Graph Model