자료구조 '힙(Heap)'

- 완전 이진 트리의 일종으로 우선순위 큐를 위하여 만들어진 자료구조
- 최댓값, 최솟값을 쉽게 추출할 수 있는 자료구조

- 힙의 종류

  1) 최대 힙 : 부모 노드의 키 값이 자식 노드의 키 값보다 크거나 같은 완전 이진 트리

  2) 최소 힙 : 부모 노드의 키 값이 자식 노드의 키 값보다 작거나 같은 완전 이진 트리

 

 

 

* 완전 이진 트리란?

  - 완전 이진트리는 마지막 레벨을 제외하고 모든 레벨이 완전히 채워져 있어야 함

  - 마지막 레벨은 꽉 차 있지 않아도 되지만, 노드가 왼쪽에서 오른쪽으로 채워져야 함

 

 

 

 

* 우선순위 큐(Priority Queue)란?

  - 큐는 먼저 들어오는 데이터가 먼저 나가는 FIFO(First In First Out) 형식의 자료구조

  - 우선순위 큐는 먼저 들어오는 데이터가 아닌, 우선순위가 높은 데이터가 먼저 나가는 형태의 자료구조

  - 우선순위 큐는 배열, 연결리스트, 힙 등의 자료구조를 통해 구현 가능 → '힙'으로 구현하는 것이 가장 효율적

 

 

 

 

 

 

 

 

 

 

 

 

 

 

힙 정렬

- 힙 자료구조의 특성을 이용한 정렬

- 배열을 힙 자료구조에 넣은 다음에 원소를 하나씩 빼면,

  → 최소힙일 경우는 작은 값부터 큰 값 순서대로 정렬되어서

  → 최대힙일 경우는 큰 값부터 작은 값 순서대로 정렬되어서 나옴

- 내림차순 정렬을 위해서는 최대 힙을 구성하고, 오름차순 정렬을 위해서는 최소 힙을 구성

 

 

 

 

 

 

 

 

 

 

 

 

힙 정렬 과정

  1. 정렬해야 할 N개의 요소들로 최대힙을 구성 → 내림차순 정렬
  2. 그 다음으로 한 번에 하나씩 요소를(최댓값부터) 힙에서 꺼냄
  3. 삭제되는 요소들(최댓값부터 삭제)은 값이 감소되는 순서로 정렬 [최대 힙 삭제 과정]

 

 

* 내림차순 정렬을 위한 최대 힙의 구현

  - 힙(heap)은 1차원 배열로 쉽게 구현될 수 있음
  - 정렬해야 할 N개의 요소들을 1차원 배열에 기억한 후, 최대힙 삽입을 통해 차례대로 삽입

 

 

 

 

* 최대 힙 삽입 과정

  - 힙에 새로운 요소가 들어오면, 일단 새로운 노드를 힙의 마지막 노드에 이어서 삽입
  - 새로운 노드를 부모 노드들과 교환해서 힙의 성질을 만족시킴

 

 

 

 

* 최대 힙 삭제 과정

  - 최대 힙(max heap)에서 삭제 연산은 최댓값을 가진 요소(=루트 노드)를 삭제하는 것
  - 삭제된 루트 노드에는 힙의 마지막 노드를 가져옴
  - 힙을 재구성

 

 

 

 

결론적으로...

힙 정렬이란, 힙(Heap)이라는 자료구조의 성질을 활용하여 정렬을 하는 방법을 의미한다.

먼저 입력되는 배열의 숫자들을 최대힙 또는 최소힙으로 구성시킨 후 (최소힙/최대힙 삽입 과정), 가장 상위 노드부터 출력하여(최소힙/최대힙 삭제 과정) 숫자들을 정렬한다.

 

 

 

 

 

 

 

 

 

 

 

 

힙 정렬 코드

/* 현재 요소의 개수가 heap_size인 힙 h에 item을 삽입한다. */
// 최대 힙(max heap) 삽입 함수
void insert_max_heap(HeapType *h, element item){
  int i;
  i = ++(h->heap_size); // 힙 크기를 하나 증가

  /* 트리를 거슬러 올라가면서 부모 노드와 비교하는 과정 */
  // i가 루트 노트(index: 1)이 아니고, 삽입할 item의 값이 i의 부모 노드(index: i/2)보다 크면
  while((i != 1) && (item.key > h->heap[i/2].key)){
    // i번째 노드와 부모 노드를 교환환다.
    h->heap[i] = h->heap[i/2];
    // 한 레벨 위로 올라단다.
    i /= 2;
  }
  h->heap[i] = item; // 새로운 노드를 삽입
}
// 최대 힙(max heap) 삭제 함수
element delete_max_heap(HeapType *h){
  int parent, child;
  element item, temp;

  item = h->heap[1]; // 루트 노드 값을 반환하기 위해 item에 할당
  temp = h->heap[(h->heap_size)--]; // 마지막 노드를 temp에 할당하고 힙 크기를 하나 감소
  parent = 1;
  child = 2;

  while(child <= h->heap_size){
    // 현재 노드의 자식 노드 중 더 큰 자식 노드를 찾는다. (루트 노드의 왼쪽 자식 노드(index: 2)부터 비교 시작)
    if( (child < h->heap_size) && ((h->heap[child].key) < h->heap[child+1].key) ){
      child++;
    }
    // 더 큰 자식 노드보다 마지막 노드가 크면, while문 중지
    if( temp.key >= h->heap[child].key ){
      break;
    }

    // 더 큰 자식 노드보다 마지막 노드가 작으면, 부모 노드와 더 큰 자식 노드를 교환
    h->heap[parent] = h->heap[child];
    // 한 단계 아래로 이동
    parent = child;
    child *= 2;
  }

  // 마지막 노드를 재구성한 위치에 삽입
  h->heap[parent] = temp;
  // 최댓값(루트 노드 값)을 반환
  return item;
}
// 우선순위 큐인 힙을 이용한 정렬
void heap_sort(element a[], int n){
  int i;
  HeapType h;

  init(&h);

  for(i=0; i<n; i++){
    insert_max_heap(&h, a[i]);
  }

  for(i=(n-1); i>=0; i--){
    a[i] = delete_max_heap(&h);
  }
}

 

 

 

 

 

 

 

힙 정렬 시간복잡도

최선, 평균, 최악 모두 O(nlogn)

 

 

 

 

 

 

 

 

힙 정렬 장단점

1. 장점

- 시간 복잡도가 좋은편 (최악의 경우에도 시간 복잡도인 O(nlogn)을 보장)
- 힙 정렬이 가장 유용한 경우는 전체 자료를 정렬하는 것이 아니라 가장 큰 값 몇 개만 필요할 때

 

2. 단점

- 데이터들의 상태에 따라 같은 O(nlogn) 시간 복잡도 라도 조금 느림
- 데이터의 순서가 바뀌는 불안정 정렬 알고리즘

 

 

 

 

 

 

※ 참고 - Python은 heapq라는 모듈을 통해 최소힙, 최대힙 쉽게 구현 가능

 

'CS > 알고리즘' 카테고리의 다른 글

다익스트라(Dijkstra) 알고리즘  (0) 2022.08.27
BFS & DFS  (0) 2022.08.21
이분탐색(Binary Search)  (0) 2022.08.13
선택 정렬  (0) 2022.07.30

 

 

운영체제는 주기억장치보다 더 큰 용량의 프로그램을 실행하기 위해 프로그램의 일부만 주기억장치에 적재하여 사용한다. 이를 가상메모리 기법이라고 한다.

메모리를 관리하는 운영체제에서 필요한 페이지가 주기억장치에 적재되지 않았을 시(페이지 부재), 어떤 페이지 프레임을 선택하여 교체할 것인지 결정하는 방법을 페이지 교체 알고리즘이라고 한다.

 

 

 

 

페이지 교체 알고리즘 종류

1. OPT - Optimal : 앞으로 가장 오랫동안 사용되지 않을 페이지 교체

 

- 프로세스가 앞으로 사용할 페이지를 미리 알아야 한다는 전제조건이 필요

- 이 전제 조건이 실제 활용에서는 알 수 있는 방법이 없기 때문에 최적 알고리즘은 구현이 불가능한 알고리즘

- 따라서 이는 실제 구현 목적보다 다른 알고리즘과 비교 연구 목적을 위해 주로 사용

 

 

 

 


2. FIFO - First In First Out : 가장 오래된 페이지를 먼저 교체

- 이해가 쉽고, 구현이 간단하다는 장점이 존재

- 그러나 활발하게 사용 중인 페이지를 계속해서 교체한다면 페이지 부재율이 높아지고 실행속도가 떨어질 위험이 있음

 

 

 

 

 

3. LRU - Least Recently Used : 가장 오랫동안 사용되지 않은 페이지 교체

 

- 최적 알고리즘(OPT)은 실제 구현이 불가능하므로, 최적 알고리즘의 방식과 비슷한 효과를 낼 수 있는 방법을 사용한 것이 LRU 알고리즘

 

 

 

 

 

4. LFU - Least Frequently Used : 참조 횟수가 가장 작은 페이지 교체

 

- 교체 대상인 페이지가 여러 개 일 경우, LRU 알고 리즘을 따라 가장 오래 사용되지 않은 페이지로 교체

 

 

 

 

 

5. MFU - Most Frequently used : 참조 횟수가 가장 많은 페이지 교체

 

- LFU 알고리즘과 반대로, 참조 횟수가 가장 많은 페이지를 교체하는 알고리즘

- LFU와 MFU는 실제 사용에 잘 쓰이지 않음

(구현에 상당한 비용이 들고, 최적 페이지 교체 정책을 LRU 만큼 제대로 유사하게 구현해내지 못하기 때문)

 

 

 

 

 

6. NUR - Not Used Recently : 최근에 사용하지 않은 페이지 교체

 

- LRU에서 나타나는 오버헤드를 줄일 수 있음

- 최근 사용 여부를 확인하기 위해 각 페이지마다 두 개의 비트 사용 

  ▷ 참조비트(Reference Bit) : 페이지가 호출되지 않았을 때 0, 호출되었을 때 1

  ▷ 변형비트(Modified Bit) : 페이지 내용이 변경되지 않았을 때 0, 변경 되었을 때 1

'CS > 운영체제' 카테고리의 다른 글

프로세스 vs 스레드  (0) 2022.07.16
파일 시스템  (0) 2022.06.25
페이징(Paging) & 세그멘테이션(Segmentation)  (0) 2022.06.18
세마포어(Semaphore)와 뮤텍스(Mutex)  (0) 2022.06.18
CPU 스케줄링  (0) 2022.06.11

선택 정렬이란?

 

* 데이터 배열에서 가장 작은(또는 가장 큰) 데이터를 선택하여 오름차순(또는 내림차순)으로 정렬할 때 사용

 

* 최소선택정렬 / 최대선택정렬 로 나뉨

 

  - 최소선택정렬 (Min-selection sort) : 매번 가장 작은 데이터를 선택하여 배열을 오름차순으로 변경
  - 최대선택정렬 (Max-selection sort) : 매번 가장 큰 데이터를 선택하여 배열을 내림차순으로 변경

 

 

 

 

 

 

 

 

 

선택 정렬 동작과정

(최소선택정렬 예시)


Step1. 전체 데이터에서 최솟값을 찾아냄
Step2. 찾은 최솟값을 배열의 가장 앞 원소와 교환
Step3. 그 다음으로 작은 데이터를 선택하여, 맨 앞에서 두번째 데이터와 자리 교환
Step4. 위와 같은 방식으로 오름차순 정렬 완료될 때까지 데이터를 선택하고 자리를 교환하는 과정을 반복

 

 

 

 

 

 

 

선택 정렬 알고리즘 구현

1) C

#include <stdio.h>
#include <stdlib.h>

int main() {
	int i, j, min, index, temp;
	int arr[10] = { 1, 9, 4, 6, 11, 10, 3, 15, 2, 13 };
	for (i = 0; i < 10; i++) {
		min = INT_MAX;
		for (j = i; j < 10; j++) {
			if (min > arr[j]) {
				min = arr[j];
				index = j;
			}
		}
		temp = arr[i];
		arr[i] = arr[index];
		arr[index] = temp;
	}
	for (i = 0; i < 10; i++)
		printf("%d ", arr[i]);
	return 0;
}



2) Python

arr = [8, 3, 0, 9, 1, 6, 2, 4, 7, 5]

n = len(arr)
for i in range(n):
    # 가장 작은 데이터의 인덱스
    min_idx = i
    for j in range(i+1, n):
        # 최솟값 찾기
        if (arr[min_idx] > arr[j]):
            min_idx = j
    # 데이터 간의 자리 변경
    arr[i], arr[min_idx] = arr[min_idx], arr[i]

print(arr)

 

 

 

 

 

 

 


선택정렬 시간 복잡도

N개의 데이터가 있을 때 N-1번만큼 가장 작은 데이터를 찾고 맨 앞으로 보내는 과정이 필요

따라서 N + (N-1) + (N-2) + (N-3) + (N-4) + ... + 2 만큼의 연산횟수가 필요

 

이를 근사치로 계산하면 N * (N+1) / 2

빅오 표기법으로는 O(N*N) 으로 표시

'CS > 알고리즘' 카테고리의 다른 글

다익스트라(Dijkstra) 알고리즘  (0) 2022.08.27
BFS & DFS  (0) 2022.08.21
이분탐색(Binary Search)  (0) 2022.08.13
힙(Heap)정렬  (0) 2022.08.06

대칭키 암호 알고리즘 (symmetric-key algorithm)

 

- 암복호화에 사용하는 키가 동일한 암호화 방식

- 공개키 암호화 방식에 비해 속도가 빠르다는 장점이 있지만, 키를 교환해야한다는 문제 (키 배송 문제)가 발생

- 키를 교환하는 중 키가 탈취될 수 있는 문제도 있고 사람이 증가할수록 전부 따로따로 키 교환을 해야하기 때문에 관리해야 할 키가 방대하게 많아짐

- 키 배송 문제를 해결하기 위한 방법으로 키의 사전 공유에 의한 해결, 키 배포센터에 의한 해결, Diffie-Hellman 키 교환에 의한 해결, 공개키 암호에 의한 해결 등이 있음

 

 

 

 

 

 

 

공개키 암호 알고리즘 (public-key cryptography)

 

- 암복호화에 사용하는 키가 서로 다르며 따라서 비대칭키 암호화라고도 함

- 대칭키의 키교환 문제를 해결하기 위해 등장

- 송수신자 모두 한쌍의 키(개인키, 공개키)를 가짐

- 이름 그대로 키가 공개되어있기 때문에 키를 교환할 필요가 없어지며 공개키 모든 사람이 접근 가능한 키이고 개인키 각 사용자만이 가지고 있는 키

- A는 B의 공개키로 암호화한 데이터를 보내고 B는 본인의 개인키로 해당 암호화된 데이터를 복호화해서 보기 때문에 암호화된 데이터는 B의 공개키에 대응되는 개인키를 갖고 있는 B만이 볼 수 있게 되는 것

- 중간 공격자가 B의 공개키를 얻는다고 해도 B의 개인키로만 복호화가 가능하기 때문에 기밀성을 제공하며 개인키를 가지고있는 수신자만이 암호화된 데이터를 복호화할 수 있으므로 일종의 인증기능도 제공한다는 장점 존재 (기밀성/인증/부인방지 기능을 제공)

- 속도가 느리다는 단점이 존재

 

  • B 공개키/개인키 쌍 생성
  • 공개키 공개(등록), 개인키는 본인이 소유
  • A가 B의 공개키를 받아옴
  • A가 B의 공개키를 사용해 데이터를 암호화
  • 암호화된 데이터를 B에게 전송
  • B는 암호화된 데이터를 B의 개인키로 복호화 (개인키는 B만 가지고 있기 때문에 B만 볼 수 있음)

 

 

'CS > 네트워크' 카테고리의 다른 글

HTTP & HTTPS  (0) 2022.08.10
흐름제어 & 혼잡제어  (0) 2022.08.09
TCP 3 & 4 way handshake  (0) 2022.08.09
OSI 7계층  (0) 2022.08.09
UDP (User Datagram Protocol)  (0) 2022.06.25

* 트랜잭션(Transaction)이란?

  • 데이터베이스의 상태를 변화시키기 위해 수행하는 작업 단위
  • 트랜잭션은 원자성(Atomicity), 일관성(Consistency), 격리성(Isolation), 지속성(Durability)을 보장

 

 

 

 

 

 

 

* 트랜잭션 격리 수준이란?

  • 동시에 여러 트랜잭션이 처리될 때, 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있도록 허용할지 말지를 결정하는 것
  • `격리성` 과 연관된 개념
  • 동시에 실행되는 트랜잭션들은 서로에게 영향을 미치지 않도록 격리해야 함 (ex. 동시에 같은 데이터 수정 못하도록)
  • 트랜잭션 간에 격리성을 완벽히 보장하려면 동시에 처리되는 트랜잭션을 차례대로 실행을 해야하는데, 그렇게 하면 처리 성능이 안 좋아진다는 문제점이 발생
  • 이러한 문제로 인해 ANSI 표준은 트랜잭션의 격리 수준을 4단계로 나누어 정의

 

 

 

 

 

 

 

* 격리 수준(Isolation Level) 유형

  • READ UNCOMMITTED(커밋되지 않은 읽기)
  • READ COMMITTED(커밋된 읽기)
  • REPEATABLE READ(반복 가능한 읽기)
  • SERIALIZABLE(직렬화 가능)

 

 

 

1) READ UNCOMMITTED (Level 0)

- 각 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관 없이 다른 트랜잭션이 접근 가능

- 트랜잭션이 처리중이거나, 아직 Commit되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용함

- 예시) 사용자1이 A 데이터를 B 데이터로 변경하는 동안, 사용자2는 아직 완료되지 않은 트랜잭션이지만 B 데이터를 읽을 수 있음

- 트랜잭션에서 처리한 작업이 완료되지 않았음에도 불구하고 다른 트랜잭션에서 볼 수 있게 되는 현상을

더티 리드(Dirty Read)라 하고, 더티 리드가 허용되는 격리 수준이 READ UNCOMMITTED

- READ UNCOMMITTED 격리 수준은 RDBMS 표준에서는 트랜잭션의 격리 수준으로 인정하지 않을 정도로 정합성에 문제가 많은 격리 수준. 따라서 MySQL을 사용한다면 최소 READ COMMITTED 이상의 격리 수준을 사용할 것을 권장

 

 

 

2) READ COMMITTED (Level 1)

- 어떠한 트랜잭션에서 데이터를 변경하더라도 COMMIT이 완료된 데이터만 다른 트랜잭션에서 조회할 수 있음

- 온라인 서비스에서 가장 많이 선택되는 격리 수준. 해당 레벨에서는 더티 리드(Dirty Read)와 같은 현상은 발생하지 않음

- 예시) 사용자1이 A 데이터를 B 데이터로 변경하는 동안, 사용자2는 해당 데이터에 접근이 불가능

- NON-REPEATABLE READ라는 문제가 존재

- 한 트랜잭션에서 같은 쿼리를 두 번 수행할 때 그 사이에 다른 트랜잭션이 값을 수정 또는 삭제하면서 쿼리의 결과가 상이하게 나타나는 일관성이 깨진 현상

 

 

 

3) REPEATABLE READ (Level 2)

트랜잭션 내에서 한 번 조회한 데이터를 반복해서 조회해도 결과는 동일

다른 사용자는 트랜잭션 영역에 해당되는 데이터에 대해 수정이 불가능함

- MySQL의 InnoDB 스토리지 엔진에서 기본적으로 사용되는 격리 수준

- PHANTOM READ (PHANTOM ROW) 문제 발생 가능

- 한 트랜잭션내에서 동일한 쿼리를 두 번 수행했는데, 첫 번째 쿼리에서 존재하지 않던 유령(Phantom) 레코드가 두 번째 쿼리에서 나타나는 현상

 

 

 

4) SERIALIZABLE (Level 3)

- 가장 단순한 격리 수준이면서 가장 엄격한 격리 수준

- 동시 처리 성능도 다른 트랜잭션 격리 수준보다 현저히 떨어짐

- 한 트랜잭션에서 읽고 쓰는 레코드를 다른 트랜잭션에서는 절대 접근할 수 없음

 

 

 

 

레벨을 높게 조정할 수록 발생하는 비용이 증가

※ 격리 수준이 높아질수록 MySQL 서버의 처리 성능이 많이 떨어지는 것은 아님

※ READ UNCOMMITTED는 일반적인 데이터베이스에서는 거의 사용하지 않고, SERIALIZABLE 역시 동시성이 중요한 데이터베이스에서는 거의 사용되지 않음

'CS > 데이터베이스' 카테고리의 다른 글

트랜잭션 (Transaction)  (0) 2022.08.06
정규화 (Normalization)  (0) 2022.07.16
이상 현상 (Anomaly)  (0) 2022.07.16
조인(Join)  (0) 2022.07.09
키 (Key)  (0) 2022.07.09

프로세스(Process)란?

 

  • 프로그램의 인스턴스
  • 운영체제로부터 자원을 할당받는 작업의 단위
  • 메모리에 적재되어 실행되고 있는 프로그램

 

 

 

 

 

프로세스 메모리 구조

 

 

  • Code(text) 영역 : 실행할 프로그램 코드
  • Data 영역 : 전역 변수, 정적 변수, 배열 등이 담기는 영역
  • Heap 영역 : 런타임시 동적으로 메모리 할당받는 영역 (new(), malloc() 등)
  • Stack 영역 : 지역 변수, 매개변수, 리턴 값 등의 임시적인 데이터들 담기는 영역

 

 

 

 

 

 

 

 

프로세스 특징

 

 

  • 프로세스마다 최소 1개의 스레드를 가지고 있음
  • 각 프로세스는 별도의 주소 공간에서 실행되며, 한 프로세스는 다른 프로세스의 변수에 접근 불가능

 

 

 

 

 

 

 

 

 

스레드(Thread)란?

 

  • 프로세스 내에서 실행되는 여러 흐름의 단위
  • 프로세스가 할당받은 자원을 이용하는 실행의 단위
  • 프로세스의 특정한 수행 경로
    • ex: 햄버거를 만드는 프로세스에서는 패티를 굽는 스레드가 진행되는 동안, 빵에 야채를 얹고 소스를 뿌리는 등의 스레드도 동시에 진행될 수 있음

 

 

 

 

 

 

 

스레드의 특징

 

  • 스레드는 프로세스 내에서 Stack만 따로 할당받고 Code, Data, Heap 영역은 공유 (프로세스는 Code, Data, Stack, Heap으로 구성)
  • 한 스레드가 프로세스 자원을 변경하면, 다른 이웃 스레드(sibling thread)도 그 변경 결과를 즉시 볼 수 있음

 

 

 

※ 스레드마다 독립적인 Stack을 갖는 이유

스택은 함수 호출시 전달되는 인자, 되돌아갈 주소값 및 함수 내에서 선언하는 변수 등을 저장하기 위해 사용되는 메모리 공간이므로 스택 메모리 공간이 독립적이라는 것은 독립적인 함수 호출이 가능하다는 것이고 이는 독립적인 실행 흐름이 추가되는 것이다. 따라서 스레드 정의에 따라 독립적인 실행 흐름을 추가하기 위한 최소 조건으로 독립된 스택을 할당한다.

 

→ 각 스레드별로 수행하는 업무가 다를 것이기 때문에, 최소한의 독립 조건으로 스레드마다 독립된 Stack을 할당해 주는 것 (구분을 위해)

 

 

 

 

 

정리하자면...

프로세스는 컴퓨터의 자원을 분할해서 쓰지만, 스레드는 프로세스마다 주어진 전체 자원을 함께 사용한다.

≒ 프로세스는 각자의 고유 공간을 할당받아 사용하지만, 스레드는 프로세스 내에서 다른 스레드와 공간과 자원을 함께 사용한다.

 

 

 

 

 

 

 

 

 

 

참고사이트

https://hyolls100.tistory.com/5?category=1027491 

'CS > 운영체제' 카테고리의 다른 글

페이지 교체 알고리즘  (0) 2022.07.30
파일 시스템  (0) 2022.06.25
페이징(Paging) & 세그멘테이션(Segmentation)  (0) 2022.06.18
세마포어(Semaphore)와 뮤텍스(Mutex)  (0) 2022.06.18
CPU 스케줄링  (0) 2022.06.11

정규화(Normalization)란?

 

관계형 데이터베이스(RDBMS)의 설계에서 데이터의 중복을 줄이고, 무결성을 향상시키는 기법을 정규화라고 한다.

 

정규화된 결과를 정규형이라고 하며, 정규형은 기본 정규형과 고급 정규형으로 나뉜다.

 

  • 기본 정규형 : 제1정규형, 제2정규형, 제3정규형, BCNF(보이스/코드 정규형)
  • 고급 정규형 : 제4정규형, 제5정규형

 

 

 

 

 

 

 

 

정규화의 목적

  1. 데이터의 중복을 없애며, 불필요한 데이터를 최소화시킴
  2. 무결성을 지키고, 이상 현상을 방지
  3. 테이블 구성을 논리적이고 직관적으로 할 수 있음
  4. 데이터베이스 구조 확장에 용이해짐

 

* 이상현상이란?

https://ynsseon.tistory.com/11

 

이상 현상 (Anomaly)

이상 현상(Anomaly)이란? 데이터베이스 정규화를 수행하지 않아, 테이블 간의 중복 데이터가 발생하며 데이터 무결성이 저하되는 현상 * 데이터 무결성이란, 데이터가 항상 정확한 값을 유지하려

ynsseon.tistory.com

 

 

 

 

 

 

 

 

 

 

 

정규화 유형

 

1) 제 1정규화 (1NF)

  - 테이블의 컬럼이 원자값(하나의 값)을 갖도록 테이블을 분리시킨 형태

 

 

 

 

 

 

 

 

 

2) 제 2정규화 (2NF)

  - 제 1정규화를 진행한 테이블에서 완전 함수 종속을 만족하도록 테이블을 분리시킨 형태

  - 완전 함수 종속이란, 기본키의 부분집합이 결정자가 되어선 안된단 것을 의미

 

* 결정자란, 다른 속성을 고유하게 결정하는 하나 이상의 속성을 의미

 

 

▶ 해당 테이블의 기본키는 (환자번호, 진료과) 복합키

▶ (환자번호, 진료과) 는 진료비를 결정

▶ 동시에 기본키인 (환자번호, 진료과)의 부분집합인 `진료과` 가 진료실을 결정하는 결정자

 

 

따라서, 테이블을 두개로 분해하여 제 2정규형을 만족시킬 수 있음

 

 

 

 

 

 

 

 

 

3) 제 3정규화 (3NF)

  - 제 2정규화를 진행한 테이블에 대해 이행적 종속을 없애도록 테이블을 분리시킨 형태

  - 이행정 종속이란, A → B 이고 B → C 이면 A → C를 만족한다는 것을 의미

 

 

▶ 위와 같은 테이블의 경우는 환자번호 → 진료과 → 진료실의 형태이기 때문에 (환자번호, 진료과) 와 (진료과, 진료실) 형태의 두 개의 테이블로 분리해야 함

 

 

이행적 종속을 제거하는 이유 : 환자번호 1001의 진료과가 피부과로 바뀔 경우 진료실 정보도 변경되어야 하며 데이터 불일치가 발생할 수 있음. 진료실 컬럼의 데이터를 직접 수정해 줄 수도 있지만, 이러한 번거로움을 없애기 위해 제 3정규화를 하는 것

 

 

 

 

 

 

 

 

4) BCNF (보이스/코드 정규형)

  - 제 3정규화를 완료한 테이블에서 모든 결정자가 후보키가 되도록 테이블을 분리한 형태

 

 

▶ 위의 테이블에서 기본키는 (환자번호, 진료과)이고, 이는 담당자를 결정함

▶ 동시에 담당자는 진료과를 결정함

▶ 담당자는 진료과를 결정하는 결정자이지만, 후보키가 아님 (후보키는 튜플을 유일하게 식별할 수 있는 컬럼이어야 함)

 

 

따라서 다음과 같은 테이블 분해를 통해 BCNF를 만족할 수 있음

 

 

 

 

 

 

 

 

5) 제 4정규화 (4NF)

  - BCNF를 만족하면서 다치 종속을 제거한 형태

 

* 하나의 테이블 내의 컬럼 A, B, C가 존재한다고 했을 때 B C 서로 독립적이고, A B C 각각 다중 결정하는 것을 다치 종속이라고 함

 

 

▶ 개발자마다 자격증 값들이 존재하고, 개발자마다 여러 언어 값들이 존재할 경우 이를 다치 종속 관계라고 함

 

 

따라서, 다음과 같은 테이블 분리를 통해 제 4정규형을 만족할 수 있음

 

 

 

 

 

 

 

 

6) 제 5정규화 (5NF)

  - 제4정규형을 만족하면서 조인 종속을 제거한 형태

  - 필요한 데이터가 사라지지 않는 무손실 분해가 되고, 필요 없는 데이터가 생기지 않는 비부가적 분해가 된 릴레이션(테이블)은 제 5정규형을 만족함

 

  • 무손실 조인(↔ 무손실 분해) : 하나의 릴레이션을 여러개의 릴레이션으로 분해한 후, 공통 속성으로 다시 조인했을때 데이터 손실 없이 원래의 릴레이션 그대로 복원할 수 있는 경우
  • 비부가적 조인(↔ 비부가적 분해) : 조인한 결과에 원본 릴레이션에 없던 데이터가 존재하지 않는 경우

 

 

 

 

 

 

 

 

※ 제 5정규형을 만족하게 하면 엔터티가 늘어나 비용이 증가하기 때문에 실제로 적용하는 경우는 드물다

일반적으로 제 3정규형이나 BCNF에 속하도록 릴레이션(테이블)을 분해하여 데이터 중복을 줄이고 이상 현상이 발생하는 문제를 해결한다고 한다

'CS > 데이터베이스' 카테고리의 다른 글

트랜잭션 (Transaction)  (0) 2022.08.06
트랜잭션 격리 수준 (Transaction Isolation Level)  (0) 2022.07.23
이상 현상 (Anomaly)  (0) 2022.07.16
조인(Join)  (0) 2022.07.09
키 (Key)  (0) 2022.07.09

이상 현상(Anomaly)이란?

데이터베이스 정규화를 수행하지 않아, 테이블 간의 중복 데이터가 발생하며 데이터 무결성이 저하되는 현상

 

* 데이터 무결성이란, 데이터가 항상 정확한 값을 유지하려는 성질 (데이터의 정확성, 일관성, 유효성이 유지되는 것)

 

 

 

 

 

이상현상 유형

 

1) 삽입 이상 (Insertion Anomaly)

  - 특정 데이터가 존재하지 않아, 테이블에 데이터를 삽입할 수 없는 경우

 

 

▷ 가정의학과라는 새로운 데이터를 추가하고 싶은데, 관련 환자정보가 없을 경우 테이블에 데이터를 삽입할 수가 없음

▷ 이러한 현상을 삽입 이상이라고 함

 

 

 

 

 

2) 삭제 이상 (Deletion Anomaly)

  - 특정 데이터를 지우고 싶을 때, 원하지 않는 데이터까지 함께 삭제해야 하는 경우

 

 

▷ 고길동이라는 환자정보를 삭제하고 싶은데 진료과/진료과코드/진료담당자 등을 다른 테이블에 저장하지 않았을 경우, 해당 정보들도 함께 삭제됨

▷ 이러한 현상을 삭제 이상이라고 함

 

 

 

 

 

3) 갱신 이상 (Modification Anomaly)

  - 테이블 내의 특정 데이터를 갱신할 때, 정상적으로 변경되지 않아 데이터의 불일치가 발생하는 경우

 

 

▷ 피부과의 진료담당자 이교수의 이름을 변경하고 싶을 경우, 10000개가 훨씬 넘는 데이터들 중 해당 값을 찾아서 변경해야 함

▷ 데이터 갱신이 제대로 이루어지지 않아 데이터간의 불일치가 발생할 수 있음

▷ 이러한 현상을 갱신 이상이라고 함

'CS > 데이터베이스' 카테고리의 다른 글

트랜잭션 (Transaction)  (0) 2022.08.06
트랜잭션 격리 수준 (Transaction Isolation Level)  (0) 2022.07.23
정규화 (Normalization)  (0) 2022.07.16
조인(Join)  (0) 2022.07.09
키 (Key)  (0) 2022.07.09

 

조인(Join)이란?

 

- 한 데이터베이스 내의 여러 테이블의 레코드를 조합하여 하나의 열로 표현한 것

- 두 개 이상의 테이블이나 데이터베이스를 연결하여 데이터를 검색하는 방법

 

* 두 개 이상의 테이블을 조인하기 위해서는 적어도 하나 이상의 외래키가 필요함

 

 

 

 

 

 

조인의 필요성

 

→ 서로 관계 있는 데이터가 여러 테이블로 나뉘어 저장되므로, 각 테이블에 저장된 데이터를 효과적으로 검색하기 위해 조인이 필요

 

 

 

 

 

 

조인의 종류

 

1) 내부조인 (INNER JOIN)

- 여러 애플리케이션에서 사용되는 가장 흔한 결합 방식이며, 기본 조인 형식으로 간주

- 명시적 조인 표현(explicit)과 암시적 조인 표현(implicit) 존재

 

  → 명시적

JOIN 키워드를 사용하며, ON 키워드를 조인에 대한 구문을 지정하는데 사용

SELECT * FROM employee INNER JOIN department ON employee.DepartmentID = department.DepartmentID;

 

→ 암시적

SELECT 구문의 FROM 절에서 콤마를 사용해 단순히 조인을 위한 여러 테이블을 나열

SELECT * FROM employee, department WHERE employee.DepartmentID = department.DepartmentID;

 

 

 

2) 동등조인 (EQUI JOIN)

- 비교자 기반의 조인이며, 조인 구문에서 동등비교만을 사용

- 조인조건에 '=' 연산자가 사용된 조인

 

 

 

3) 자연조인 (NATURAL JOIN)

- INNER JOIN에 속함

- 반드시 두 테이블 간의 동일한 이름, 타입을 가진 컬럼이 필요

- 조인에 이용되는 컬럼은 명시하지 않아도 자동으로 조인에 사용 → 테이블에서 동일한 컬럼명을 갖는 컬럼은 모두 조인이 됨

- 두 테이블이 동시에 가지고 있는 컬럼의 값이 전부 같은 것만 골라냄

 

 

 

4) 교차조인 (CROSS JOIN)

- 조인되는 두 테이블에서 곱집합을 반환

- Catesian product, Cross product 라고도 함

- 명시적, 암시적 조인 표현 존재

 

  → 명시적

SELECT * FROM employee CROSS JOIN department;

 

  → 암시적

SELECT * FROM employee, department;

 

 

 

5) 외부조인 (OUTER JOIN)

* LEFT OUTER JOIN

- 왼쪽 테이블을 기준으로 조인

- 왼쪽 테이블의 데이터 모두 출력 → 오른쪽 테이블의 컬럼값에 NULL 발생 가능

 

 

* RIGHT OUTER JOIN

- 오른쪽 테이블을 기준으로 조인

- 오른쪽 테이블의 데이터 모두 출력 → 왼쪽 테이블의 컬럼값에 NULL 발생 가능

 

 

* FULL OUTER JOIN

- 조인을 하는 테이블들의 모든 데이터를 출력

- 합집합

 

※ MySQL에서는 FULL OUTER JOIN을 지원하지 않으므로, LEFT OUTER JOIN 결과와 RIGHT OUTER JOIN 결과를 UNION 하여 사용

 

 

6) 셀프조인 (SELF JOIN)

- 자기자신을 조인하는 것

- 자신이 갖고 있는 칼럼을 다양하게 변형시켜 활용할 때 자주 사용

 

 

 

'CS > 데이터베이스' 카테고리의 다른 글

트랜잭션 (Transaction)  (0) 2022.08.06
트랜잭션 격리 수준 (Transaction Isolation Level)  (0) 2022.07.23
정규화 (Normalization)  (0) 2022.07.16
이상 현상 (Anomaly)  (0) 2022.07.16
키 (Key)  (0) 2022.07.09

 

 

키(Key)란?

데이터베이스에서 키 (Key) 는 조건에 만족하는 튜플을 찾거나, 순서대로 정렬할 때 다른 튜플들과 구별할 수 있는 기준이 되는 속성

 

* 튜플이란, 테이블의 행을 의미

 

 

 

 

 

 

 

유일성과 최소성

 

유일성 : 하나의 키값으로 하나의 튜플만을 유일하게 식별할 수 있어야 함

→ 문자 그대로 유일해야 한다는 특징

 

최소성 : 키를 구성하는 속성 하나를 제거하면 유일하게 식별할 수 없도록 꼭 필요한 최소의 속성으로 구성되어야 함

→ 키를 구성하는 속성의 갯수가 최소여야 한다는 특징

 

 

 

 

 

 

 

키의 종류

 

* 기본키

- 특정 튜플을 유일하게 구별할 수 있는 속성

- 후보키 중에서도 특별히 선정된 주키(Main Key)

- 유일성 O, 최소성 O

- 중복값 가질 수 없음 (기본키 주요 특징)

- NULL값 가질 수 없음 (기본키 주요 특징)

 

 

* 대체키

- 기본키를 제외한 나머지 후보키

- 보조키라고도 함

 

 

* 후보키

- 테이블을 구성하는 속성들 중에서 튜플을 유일하게 식별하기 위해 사용되는 속성들의 부분집합

- 유일성 O, 최소성 O

 

 

* 슈퍼키

- 유일성의 특성을 만족하는 속성 또는 속성들의 집합

- 최소성은 만족 X

- EX : 환자ID는 고유하기 때문에 슈퍼키가 될 수 있음. 나이, 직업 등은 중복된 값이 존재하기 때문에 슈퍼키가 될 수 없음.

→ (환자ID, 나이, 직업)은 환자ID가 각 튜플을 구별할 수 있기에 슈퍼키가 될 수 있음. 이때 유일성은 만족하지만, 최소성은 만족하지 못함.

 

 

* 외래키

- 다른 릴레이션(테이블)의 기본키를 그대로 참조하는 속성의 집합

 

※ 외래키가 필요한 이유?

for 데이터 무결성

→ 데이터 무결성이란, 데이터가 항상 정확한 값을 유지하려는 성질을 의미한다.

예를 들어 환자 테이블의 환자ID가 변경이 되었는데, 진단기록 테이블의 환자ID가 변경이 되지 않는다면 두 값은 서로 같은 값이어야 하는데 다른 값이 되어버린다. 이를 무결성이 깨졌다고 표현한다.

 

 

 

'CS > 데이터베이스' 카테고리의 다른 글

트랜잭션 (Transaction)  (0) 2022.08.06
트랜잭션 격리 수준 (Transaction Isolation Level)  (0) 2022.07.23
정규화 (Normalization)  (0) 2022.07.16
이상 현상 (Anomaly)  (0) 2022.07.16
조인(Join)  (0) 2022.07.09

+ Recent posts