[데이터베이스] #9. 데이터 저장과 파일

bien·2023년 5월 26일
0

데이터베이스

목록 보기
7/17

1. 물리적 저장장치

물리적 저장장치의 구성

  1. 물리적 저장장치는 데이터 접근 속도, 용량을 기준으로 다양한 장치로 구성

이런 여러개의 저장장치가 동시에 사용되어 서로 교류하면서 저장이 이루어짐. 밑으로 내려갈 수록 저장용룡이 커지고, 위로 올라갈수록 속도가 빨라지고 가격이 비싸짐. 레지스터는 CPU에 붙어있는 아주 소규모, 고속의 장치. 레지스터가 조금 늘어나는것 만으로도 CPU의 가격이 2~30배 뛸 수 있다. 그렇기에 레지스터로 모든 저장을 처리할 수가 없어 접근 속도는 떨어지지만 용량은 크고 가격은 저렴한 아래쪽까지 사용한다.

물리적 저장장치별 특징

  1. 휘발성 (내버려두면 없어진다.)
    • 캐시: 고비용 저장장치로 빠른 접근 속도를 보장
    • 메인 메모리: 실제 프로그램과 데이터 적재 공간
  2. 비휘발성 (속도는 느리나 저장공간이 넓음. 영구적 저장)
    • 플래쉬 메모리: 메인 메모리와 유사하나 비휘발성
    • 자기 디스크: 데이터베이스 전체를 안정적으로 저장
    • 광학 디스크 드라이브: CD, DVD, Blue-ray등
    • 테이프 장치: 용량이 크고 저렴하나 순차 접근 방식으로 접근 속도가 매우 느림.

비휘발성은 저장 장치는 너무 느려 한번 저장하고 간간히 읽는데 사용하는 정도로만 사용한다. 읽고 쓰는데 적합한 저장장치들이 아니다. 그나마 읽고 쓰는데 쓸만한 장치는 플래쉬 메모리, 자기 디스크 정도. 그렇더라도 메인 메모리에 비해 1000배는 느리다. 휘발적이나 캐시, 메인 메모리가 정말 빠르게 작동하고 있음을 알 수 있다.


2. 파일

물리적 저장장치

데이터베이스 구성

하나의 데이터베이스는 큰 하나의 데이터 집합으로 보이나, 데이터 저장을 위해 운영장치가 제공하는 데이터 저장 구조의 가장 낮은 단계인 "파일"단위로 운영된다. DBMS가 운영체제에 맞는 파일구조로 데이터를 가지고 있는 것. 이 파일이 다시 작은 단위로 나뉜게 "블럭". 하나의 파일은 디스크에 저장될 때 여러개의 블럭 단위로 분리되어 저장되며, 하나의 블럭에는 여러개의 "레코드"를 보유한다.

데이터베이스 구성요소

  1. 파일
    • 데이터를 영구적으로 저장하기 위해 사용되는 가장 기초적인 논리적 구조
  2. 블럭
    • 파일을 고정적인 길이로 분할하여 생기는 균등한 크기의 데이터 묶음
    • 일반적으로 메모리와 디스크간 데이터 전송 단위로 결정
  3. 레코드
    • 블럭을 구성하는 요소
    • 더 이상 분리될 수 없는 최소 데이터 저장 단위

고정 길이 레코드

하나의 블럭에 데이터는 어떻게 저장될까? 하나의 릴레이션의 레코드는 모든 레코드의 길이가 동일한게 있고, 레코드별로 길이가 들쭉날쭉한 릴레이션이 있음

  1. 고정적인 바이트 수를 갖는 레코드를 저장하는 기법

INT(4) 다 더하면 42. 모든 레코드는 42정도의 길이를 유지하고 있음.
고정 길이 레코드를 저장하려면 어떻게 하면 될까? 레코드의 길이가 일정하므로 차곡차곡 쌓을 수 있음.
내가 두번째 레코드를 읽고 싶으면 어떻게 하면 될까? 고정 길이이므로, 43~84까지 읽으면 됨.

  1. 데이터 접근
  • 모든 레코드는 42 바이크 크기로 구성
  • i번째 레코드 접근
    - (i-1) * 42 + 1번째 바이트부터 42개의 바이트를 읽어 접근

잔여 고정 길이 레코드 할당

  1. 블럭의 길이가 레코드 길이로 정확히 나눠지지 않아 잔여 공간을 비워두는 방법
    - 블럭 내의 남은 공간 낭비

블럭에 k개 차곡차곡 집어넣고 있다가, 조금 남은거는 어쩌지? 42바이트는 안돼서 레코드 하나 더 못넣음. 그럼 다음레코드부터는 다른 블럭에 넣어야 함. 따라서 모든 블럭에 42바이트보다 작은 잔여공간이 낭비되고 있음. 블럭의 갯수가 많으면 낭비되는 공간이 꽤 됨.

고정길이 레코드 할당

아.. 이거 버려지는거 너무 아깝다. 이거 좀 바꿔보자! 해서 나온 게 이것

  1. 블럭의 길이가 레코드 길이로 정확히 나눠지지 않아 한 레코드를 두 블럭이 나누어 저장하는 방법
    • 레코드 접근 시 두 블럭을 접근

되는데까지 다 채워서 넣고, 남은거 조금 다음거에 넣음. 30남으면, 30까지 넣고 나머지 12를 다음 블럭에 저장. 문제는, 정보를 출력할때 두개의 블럭에 걸쳐있는 레코드를 가져올때, 두개의 블럭을 가져와야 해서 속도가 매우 느려질 수 있다.

고정길이 레코드 할당의 문제

뿐만 아니라 추가적으로 더 많은 문제가 발생 가능. 중간중간 레코드를 삭제하면 다시 레코드 삽입할 때 빈공간에다 레코드 넣으면 좋지 않을까? 그런데 컴퓨터가 빈칸이 어디있는지 어떻게 알지? 삭제 위치를 몰라 뒤에 막 추가하면 삭제된 레코드의 저장공간은 그냥 비워진채로 낭비되게 된다.

  1. 레코드 삭제 시

    • 해당 레코드가 저장된 위치에 빈 공간이 생성
    • 장시간 레코드의 삽입 및 삭제 발생 시, 저장공간에 많은 낭비가 발생
  2. 레코드 삭제 시 대처 방안

    • 마지막 레코드로 공백 대체
    • 삭제 레코드 이후의 레코드를 이동
    • 가용 리스트 관리

레코드 삭제 대처

  1. 마지막 레코드로 공백 대체
  • 빈공간 발생 시 마지막 데이터를 올려 빈공간을 매꿈
  • 레코드의 순서가 초기와 달라져 검색에 더 오랜 시간 소요
  1. 삭제 레코드 이후의 레코드를 이동
    순서 바뀌면 곤란하니까.. 그러지말고, 뒤의 모든 레코드들을 하나씩 올려주자! 레코드 뒤의 순서가 그대로 유지되도록!
  • 삭제 된 데이터 이후의 데이터를 모두 한칸씩 끌어올림
  • 첫번째 데이터가 삭제된 나머지 데이터가 모두 한칸식 당겨져야 하는 등 많은 과정이 요구됨
  1. 가용리스트 관리
    정보를 저정할 수 있는 공간을 더 확보해서 추가 이동을 방지하자!

공백 레코드 포인트가 빈공간의 링크를 가지고 있음. 빈공간이 어디있는지 링크를 따라가면 다 알 수 있음. 새로운 데이터가 추가 되는 경우 링크 순서대로 가용 리스트를 하나씩 따라가며 데이터를 매꿔감.

실제 현장에서도 가용 리스트를 가장 많이 사용한다!

가변 길이 레코드

  1. 블럭에 저장되는 레코드의 길이가 서로 다른(가변적) 레코드를 할당하는 방법
  2. 가변 길이 레코드가 사용되는 상황
    • 한 블럭 내에 저장되는 레코드의 유형이 둘 이상
    • 길이가 고정되지 않은 컬럼의 개수가 하나 이상(ex. VARCHAR)
    • 레코드가 멀티셋을 허용한 컬럼을 가질 때

멀티셋: 레코드의 컬럼값이 여러 개인 컬럼
(컬럼값의 원자성을 확대한 멀티셋을 제공한 DBMS가 종종 있음)

하나의 레코드를 정의하는 방법이 달라짐.

가장 첫번째 들어오는 값: 4byte를 소모하면서, 여기에 가변길이컬럼이 있는데 몇번째 바이트부터 시작하고, 길이는 얼마나 되는지 알려줌.
이후 고정길이 값들이 쭉 들어가고, NULL이 들어감.
NULL의 의미: 여기까지 고정길이 값들이 끝났어, 여기부터는 가변길이 값이야!

27번에서 6byte 크기의 가변데이터가 들어갈거야!
26byte에 NULL이 입력되어 이후 가변길이데이터가 들어감을 알려줌

슬롯페이지 구조

한 블럭에서 이러한 가변길이 레코드를 어떻게 저장해야 할까?
-> "슬롯페이지 구조"를 대표적으로 많이 사용한다.

  • 하나의 블럭 내부에 모든 레코드의 길이가 다 다르다면, 레코드의 시작과 끝을 모두 유지하고 있어야 한다.
  • 블럭헤더에 레크드의 갯수, 위치등을 포함한 레코드 요약 정보를 저장해놓는다. 새로운 가변길이 레코드가 들어오면, 그 링크를 저장해둔다.
  • 블럭 헤더는 그 블럭의 가장 앞에 위치하고, 레코드는 맨 뒤부터 하나씩 차곡차곡 앞으로 쌓아올린다.

파일 구조화 방법

  1. 파일 구조화
    - 파일 수준에서 레코드를 관리(순서 등)하는 기법

파일 구조화 방법의 종류

하나의 릴레이션은 여러개의 블럭으로 나뉘어 저장된다. 만약 해당 릴레이션에 손흥민이라는 새로운 데이터가 추가될 때, 어느 블럭에 추가되면 될까? 마지막 블럭의 마지막 칸에? 기존 데이터가 삭제된 빈칸에? 새로운 신규 데이터가 어느 장소에 저장될지에 대한 기준, 방법이 규정되어야 한다. 이같은 방법에 3가지 종류가 있다.

  • 힙구조: 저장순서 고려 없이 파일 내 임의의 위치에 배치
    근처 아무데나 자리 있으면 무작위로 거기다 넣어줘.
    => 저장속도는 가장 빠름. but 저장위치를 모르므로 사용의 효율은 가장 떨어짐

  • 순차 파일 구조: 레코드들이 탐색키 기준으로 정렬되어 저장
    나 새로은 정보는 사번에 맞춰서 넣을거야. 사번이 제일 늦으니까, 제일 마지막 자리로 들어가.
    => 순서를 고려하므로 저장속도는 느림. but, 이진탐색트리를 통한 사번 검색으로 탐색 속도를 줄일 수 있음.

  • 해시파일구조: 해시 함수를 사용하여 블럭 주소를 계산
    _탐색키가 사번이라면, 사번을 어느 블랙박스에 넣어서 나온 숫자에 넣어둠. 다시 해당 레코드를 찾고 싶으면, 사번을 블랙박스에 넣어서 저장 위치를 알 수 있음. 일종의 번호생성기를 활용.

해쉬파일의 번호사용기의 성능에 따라 속도차가 크므로, 실제로는 순차 파일구조가 가장 빈번히 활용됨.

순차 파일 구조의 예

맨끝에 가용레코드와 유사하게 다음 레코드를 연결해뒀음. 그래서 만약 "안창호"데이터를 보면, 그 다음 데이터를 링크를 통해서 따라갈 수 있게 해놓음. but, 만약 새로운 데이터가 추가되면 이 링크 체인을 유지하기 위해 추가 작업이 필요함.

순차 파일 구조

  1. 레코드가 검색키 순서대로 정렬
  2. 레코드가 파일에 삽입되는 시점에서 키 값이 부여
  3. 장점
    • 검색키에 대한 정렬 연산이 불필요, 키 값들의 순서로 레코드를 판독하는 연산에 효율적
    • 현재 레코드에서 정렬된 키 순서로 다음 레코드를 찾을 때 부가적인 블럭 접근이 불필요
    • 이진 탐색을 사용하면 더 빠르게 레코드를 검색
  4. 단점
    • 레코드를 삽입, 삭제에 많은 비용 소요

오버플로우 블럭

저장 방식을 개선하기 위해 사용한다.
1. 순차 파일 구조에서 레코드의 정렬된 상태 유지를 위해 삽입된 신규 블럭

손흥민 데이터를 순서대로 넣기 위해서는, 안창호 부터 밑으로 쫙 내려서 칸을 만들고 거기에 넣어야함. 이게 너무 많은 과정을 요구하므로, 아예 나철수가 손흥민을 가르키도록 변경함. 순서대로 접근 시 두개의 블럭에 접근해야 하는 단점이 있으나, 저장 속도를 획기적으로 줄여줄 수 있음


3. 저장장치 관리

저장장치 접근

  1. 파일은 논리적 관점에서의 저장 객체
  2. 실제 저장될 때에는 여러 개의 물리적 단위인 블럭으로 저장
    • 블럭은 메모리와 디스크 간 데이터의 전송 단위
    • 일반적으로 2kb~32KB 사용(주로 4KB 사용)
    • 블럭 전송을 최소화 할 수록 입출력 소요 시간이 단축
      • 사용 중인 블럭을 지속적으로 메모리에 적재
      • 한정적 공간으로 인하여 필요에 따라 특정 블럭 할당을 해지
      • 메모리 내부에는 버퍼라는 공간에 블럭을 저장하고, 이를 관리하기 위한 버퍼관리자를 활용

디스크는 느리니까 접근을 최소화하고 한번 읽은 블럭을 여러번 재사용하도록 만드는 것이 컴퓨터 속도 향상에 가장 효과적이다.

디스크에 저장되어있는 영구적 데이터가 존재하고, 소프트웨어는 이 저장공간에 다양한 질문을 하게 된다. 이때 소프트웨어는, 먼저 운영체제위의 DBMS가 관리하는 메모리에서 먼저 답변이 있는지 확인하고 있으면 바로 답변하고, 없으면 디스크로 가서 메모리에 필요한 정보를 적재하고 이 데이터를 통해 답변한다.

필요한 데이터를 가지고 오는 역할, 메모리가 꽉 찼을때 다시 디스크로 내보내고 추가로 가져올 데이터를 가져오는 것을 "버퍼관리자"가 수행한다.

단기기억, 장기기억 느낌이다. 나는... 컴퓨터가 아닐까..?

버퍼 관리자

  1. DBMS상의 소프트웨어는 필요한 블럭이 있을 때 버퍼 관리자에게 해당 블럭을 요청
    • 요청된 블럭이 버퍼에 있다면, 버퍼 관리자는 블럭이 위치한 메모리 주소를 프로그램에게 전달
    • 요청된 블럭이 없는 경우, 버퍼 관리자는 버퍼내의 새로운 공간을 할당하고 해당 블럭을 적재
    • 더 이상 적재할 공간이 없다면, 버퍼에 있는 기존 블럭을 선택하여 할당을 해지하고 해당 블럭을 적재

버퍼 교체 전략

디스크의 하나의 블럭을 가져오는데 빈공간이 없으면 있는걸 내보낸다고 했다. 그럼.. 내보내는 기준이 뭘까?
그냥 아무거나 내보내면 안될까요? 안됩니다. 방금 내보낸 데이터를 또다른 사용자가 또 요구한다면? 방금 내보낸 데이터를 다시 꺼내와야함. 어마어마한 자원적, 시간적 낭비가 일어날 수 있다. 따라서, 가장 안쓰일거 같은 데이터를 내보내야 함.

  1. 버퍼 교체 전략
  • 가용 공간을 확보하기 위해 기존에 적재된 블럭의 할당을 특정 기존에 의하여 해지.
  • 미래에 가장 적게 사용될 블럭을 선택하여 디스크로 내보내는 것이 이상적인 버퍼 교체 전략
  • 버퍼 교체 전략 기법
    • LRU(Least Recently Used): 최근에 가장 적게 참조된 블럭을 교체
      가장 오랫동안 안쓴 블럭을 골라서 앞으로도 안쓰일거야..라는 생각으로 빼버림
    • MFU(Most Frequently Used): 특정 기간동안 가장 여러번 사용된 블럭을 선택하여 교체
      가장 많이 썼으니까, 이제 안쓰지 않을까..?라는 생각으로 가장 많이쓴것을 빼버림.

정답이 없는 문제. 어떤게 가장 적절할지는 개발자가 판단해야

고정 블럭과 블럭 강제 출력

때로는 DBMS의 버퍼관리자를 통하지 않고, 사람이 강제적으로 정보를 넣거나, 넣는것을 막는 기능이 필요할 수 있음.
고정 블럭: 데이터 처리중이라 임시값이 들어가 있거나, 프로그램에 오류에 의해 잘못된 값이 들어가 있는 경우 이 같은 데이터들이 DB에 입력되지 않도록 막아야 함.
블럭 강제 출력: 반대로, 버퍼교체 전략에 의해 선택될거 같지 않지만, 운영체제나 서버, DBMS 등의 오류로 셧다운이 될 수 있음. 이런 경우 중요 기록이 소실되기전 빠르게 영구저장 장치로 저장하는 기능이 필요할 수 있음.

  1. 고정 블럭
  • 장애로 인하여 메모리의 데이터가 손실되어 작어비 중단될 경우, 중단된 작업의 결과물이 디스크에 기록되는 것을 방지
  • 디스크 블럭이 교체되는 것을 제한
  1. 블럭 강제 출력
  • 시스템 로그와 같이 중요한 데이터는 디스크에 영구적으로 기록되어야 함

  • 버퍼 공간이 필요 없어도 강제로 디스크에 기록


    놈놈 재뮛다 ㅎㅎ

profile
Good Luck!

0개의 댓글