- 데이터베이스 개념을 정리한 것으로 내용은 추가될 예정입니다.
- 전반적인 내용은 다음을 참고해 작성되었습니다.
- 도서 <데이터베이스 배움터>
- 도서 <MySQL로 배우는 데이터베이스 개론과 실습>
- 도서 <면접을 위한 CS 전공지식 노트>
- DBMS
- 데이터베이스 스키마
- DDL, DML, DCL
- 키(Key)
- 무결성 제약조건
- 데이터의 문자 타입
- 조인(join)
- ERD
- 인덱스(Index)
- 정규화
- 트랜잭션
- 커밋과 롤백
- 트랜잭션 고립 수준
DBMS
DBMS(Database Management System, 데이터베이스 관리 시스템)는 사용자와 데이터베이스를 연결시켜주며, 데이터베이스 사용자가 데이터베이스를 생성, 공유, 관리할 수 있도록 지원해주는 총체적인 역할을 하는 소프트웨어이다.
파일 시스템을 이용해 데이터를 관리하면 데이터 중복 저장, 동시성 제어 불가, 검색 어려움 등의 여러 문제가 나타나는데, DBMS를 사용하면 이러한 문제를 해결할 수 있다.
데이터베이스 스키마
데이터베이스 스키마(Database Schema)는 데이터베이스에서 데이터의 구조, 데이터 표현 방법, 데이터 간의 관계를 정의한 구조이다. DBMS는 주어진 설정에 따라 데이터베이스 스키마를 생성한다.
데이터베이스 사용자가 데이터를 저장, 조회, 삭제, 수정할 때 DBMS는 자신이 생성한 데이터베이스 스키마를 참조하여 명령을 수행한다.
(참고)
https://ko.wikipedia.org/wiki/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4_%EC%8A%A4%ED%82%A4%EB%A7%88
DDL, DML, DCL
1. DDL(데이터 정의어)
DDL(Data Definition Language)은 데이터베이스의 구조와 스키마를 정의하거나 수정하기 위해 사용한다. DDL의 주요 목적은 데이터베이스 객체(테이블, 인덱스, 제약조건 등)를 생성, 변경 및 삭제하는 것이다. DDL의 주요 명령어로는 CREATE, ALTER, DROP 등이 있다.
2. DML(데이터 조작어)
DML(Data Manipulation Language)은 데이터베이스에 저장된 데이터를 검색, 삽입, 수정, 삭제하는 작업을 수행하기 위해 사용한다. DML은 데이터베이스의 내용을 조작하는 데 중점을 두고 있다. DML의 주요 명령어로는 SELECT(검색), INSERT(삽입), UPDATE(수정), DELETE(삭제) 등이 있다.
3. DCL(데이터 제어어)
DCL(Data Control Language)은 데이터베이스에 대한 접근 권한과 보안을 관리하기 위해 사용한다. DCL의 주요 명령어로는 GRANT(권한 부여), REVOKE(권한 취소) 등이 있다. DCL은 데이터베이스에 접근하는 사용자의 권한을 제어하여 데이터 무단 액세스 및 손상을 방지한다.
키(Key)
키는 릴레이션(테이블)의 각 튜플을 고유하게 식별할 수 있는 하나 이상의 속성의 모임이다. 다음의 두 가지 특성을 통해 키의 종류가 구분된다.
- 유일성 : 하나의 릴레이션에서 모든 튜플은 서로 다른 키 값을 가져야 한다.
- 최소성 : 꼭 필요한 최소한의 속성들로만 키를 구성해야 한다.
1. 슈퍼 키(Super Key)
슈퍼 키는 한 릴레이션 내의 특정 튜플을 고유하게 식별하는 하나의 속성 또는 속성의 집합이다. 슈퍼 키는 튜플을 고유하게 식별하는데 꼭 필요하지 않은 속성들을 포함할 수 있다. 즉 유일성은 만족하지만 최소성은 만족하지 못한다.
2. 후보 키(Candidate Key)
후보 키는 각 튜플을 고유하게 식별하는 최소한의 속성들의 집합이다. 즉 유일성과 최소성을 모두 만족하며, 후보 키를 구성하는 속성들 중 어느 한 속성이라도 빼면 튜플을 고유하게 식별하는 능력을 상실한다. 두 개 이상의 속성으로 구성된 후보 키는 복합 키(Composite Key)라고도 부른다.
3. 기본 키(Primary Key)
기본 키는 후보 키 중 선정된 키를 가리킨다. 기본 키는 한 릴레이션 내의 모든 튜플을 고유하게 식별할 수 있어야 하므로 널값이나 중복된 값을 가질 수 없다. 릴레이션에서 기본 키를 찾을 수 없는 경우에는 레코드 번호와 같이 인위적인 키 속성을 릴레이션에 추가하여 기본 키로 선정할 수 있다. 이와 같이 인위적으로 만든 기본 키를 대리 키(Surrogate Key)라고도 부른다.
4. 대체 키(Alternate Key)
대체 키는 후보 키 중 기본 키로 선정되지 않은 나머지 키를 가리킨다.
5. 외래 키(Foreign Key)
외래 키는 어떤 릴레이션의 기본 키를 참조하는 속성이다. 외래 키는 관계 데이터베이스에서 릴레이션 간의 관계를 나타내기 위해 사용된다. 외래 키 속성은 부모 릴레이션의 기본 키와 동일한 도메인을 가져야 한다. 이때 자식 릴레이션과 부모 릴레이션은 서로 같은 수 있다. 또한 외래 키는 자신이 속한 릴레이션의 기본 키에 속할 수 있다.
무결성 제약조건
데이터 무결성은 데이터베이스에 저장된 데이터의 일관성과 정확성을 지키는 것을 의미한다. 데이터베이스가 계속해서 무결성을 유지하려면 튜플의 삽입, 삭제, 수정 시 무결성 제약조건을 준수해야 한다.
1. 도메인 무결성 제약조건
모든 튜플은 릴레이션 스키마에 정의된 각 속성의 도메인에 지정된 값만을 가져야 한다.
2. 개체 무결성 제약조건
기본 키는 NULL 값을 가져서는 안 되며, 릴레이션 내에 오직 하나의 값만 존재해야 한다.
3. 참조 무결성 제약조건
자식 릴레이션의 외래 키는 부모 릴레이션의 기본 키와 속성의 도메인이 동일해야 하며, 자식 릴레이션의 값 변경은 부모 릴레이션의 제약을 받는다. 또한 자식 릴레이션에서 참조하고 있는 값을 부모 릴레이션에서 삭제하거나 다른 값으로 변경하려고 하면 거부된다.
데이터의 문자 타입
데이터의 문자 타입으로는 CHAR, VARCHAR, TEXT, BLOB 등이 있다.
1. CHAR과 VARCHAR
CHAR은 테이블을 생성할 때 선언한 길이로 고정되며 길이는 0~255 사이의 값을 가질 수 있다. 레코드를 저장할 때 무조건 선언한 길이의 값으로 고정해서 저장한다.
이와 달리 VARCHAR은 가변 길이의 문자열로 길이는 0~65,535 사이의 값을 가질 수 있다. 테이블을 생성할 때 선언한 길이보다 짧은 문자열을 저장할 때는 용량을 가변시켜 저장한다. 예를 들어 VARCHAR(50) 타입을 가지는 이메일 속성에 10글자의 이메일을 저장할 경우 (10글자에 해당하는 바이트 + 길이기록용 1바이트)로 저장한다.
1.1 CHAR 대신 VARCHAR을 사용하는 이유
CHAR은 문자열을 고정된 길이로 저장하기 때문에, 해당 길이보다 짧은 문자열을 저장할 때는 남은 공간에 공백문자가 들어간게 된다. 그 결과 equals()로 문자열 비교 시 실제와 다른 결과가 나타나거나, trim()으로 공백문자를 제거하는 과정을 추가해야 해서 자원을 더 낭비하게 되는 경우가 많다. 따라서 CHAR 대신 VARCHAR를 사용하는 것이 좋다.
(참고) https://okky.kr/questions/217655
2. TEXT와 BLOB
두 타입 모두 큰 데이터를 저장하기 위한 타입이다. TEXT는 게시판 본문과 같이 큰 문자열을 저장할 때 사용하고, BLOB은 이미지, 동영상과 같은 큰 데이터를 저장할 때 사용한다. 하지만 실제로 개발할 때는 이미지, 동영상 파일은 서버에 저장하고 해당 파일의 경로를 VARCHAR 타입으로 저장하는 방식을 많이 사용한다.
조인(join)
조인은 두 개 이상의 테이블이 가진 공통 속성을 기준으로 속성 값이 같은 튜플을 수평으로 결합하는 연산이다. 즉, 두 개 이상의 테이블을 묶어 하나의 결과물을 만든다.
1. INNER JOIN (내부 조인)
INNER JOIN은 왼쪽 테이블과 오른쪽 테이블에서 기준 속성(k1, k2) 값이 같은 레코드만 보여준다.
SELECT * FROM Table1 t1
INNER JOIN Table2 t2
ON t1.k1 = t2.k2
2. LEFT OUTER JOIN (왼쪽 외부조인)
LEFT OUTER JOIN은 왼쪽 테이블 전체와, 왼쪽 테이블과 기준 속성 값이 같은 오른쪽 테이블의 레코드를 보여준다. 만약 오른쪽 테이블에 왼쪽 테이블과 기준 속성 값이 같은 데이터가 없다면 NULL로 채운다.
SELECT * FROM Table1 t1
LEFT [OUTER] JOIN Table2 t2
ON t1.k1 = t2.k2
3. RIGHT OUTER JOIN (오른쪽 외부조인)
RIGHT OUTER JOIN은 오른쪽 테이블과 기준 속성 값이 같은 왼쪽 테이블의 레코드와 함께 오른쪽 테이블 전체를 보여준다. 만약 왼쪽 테이블에 오른쪽 테이블과 기준 속성 값이 같은 데이터가 없다면 NULL로 채운다.
SELECT * FROM Table1 t1
RIGHT [OUTER] JOIN Table2 t2
ON t1.k1 = t2.k2
4. FULL OUTER JOIN (합집합 조인)
FULL OUTER JOIN은 왼쪽 테이블과 오른쪽 테이블에서 기준 속성 값이 같은 레코드와 함께 각 테이블의 전체 레코드를 보여준다. 만약 기준 속성 값이 같은 데이터가 각 테이블에 없다면 NULL로 채운다.
SELECT * FROM Table1 t1
FULL [OUTER] JOIN Table2 t2
ON t1.k1 = t2.k2
(알아두기)
MongoDB의 조인 연산인 lookup은 관계형 데이터베이스보다 성능이 떨이지기 때문에, 여러 테이블을 조인하는 작업이 많은 경우에는 MongoDB보다 관계형 데이터베이스를 사용하는 것이 좋다.
ERD
ERD란 Entity-Relationship Diagram(개체-관계 다이어그램)의 약자로, 데이터베이스를 설계할 때 사용하는 다이어그램이다. ERD를 사용하면 데이터베이스의 구조를 시각적으로 파악할 수 있으며, 데이터베이스의 모든 개체(Entity), 속성(Attribute) 및 개체 간의 관계(Relationship)를 표현할 수 있다.
ERD에서 개체(Entity)는 데이터베이스에 저장하려는 정보를 나타내며, 보통 사물 또는 개념적인 것으로 표현된다. 예를 들어 고객, 제품, 주문 등이 개체에 속한다. 개체는 다양한 속성(Attribute)으로 구성되는데, 이 속성은 데이터베이스에 저장하려는 정보의 세부 항목을 정의한다. 예를 들어 고객 개체는 이름, 전화번호, 이메일 주소 등의 속성을 가질 수 있다.
ERD에서 관계(Relationship)는 두 개체 간의 상호 작용을 표현한다. 관계에는 일대일, 일대다, 다대다 등 다양한 유형이 있다. 관계의 유형에 따라 다이어그램에 표현되는 방법이 달라진다. 관계는 보통 관련된 개체 간의 조인 조건을 나타내며, 데이터베이스에 저장된 정보를 검색하거나 연결하는 데 사용한다.
ERD는 데이터베이스 설계를 위한 중요한 도구로, 데이터베이스 설계자가 데이터베이스의 구조와 개체 간의 관계를 더욱 명확하게 이해하고 구성할 수 있도록 도와주는 역할을 한다. 또한 데이터베이스에 저장될 데이터의 유형, 크기, 무결성 제약 조건 등을 파악하는데 도움을 준다.
인덱스(Index)
인덱스란 데이터베이스 테이블에서 원하는 데이터를 빨리 찾기 위해 <탐색 키, 탐색 키가 저장된 물리적 위치>를 키와 값의 쌍으로 기록해둔 파일이다. 일반적인 RDBMS의 인덱스는 대부분 B+-tree 구조를 가진다.
B-tree는 데이터를 검색할 때 트리 구조를 이용하기 때문에, 한 번 검색할 때마다 검색 대상이 크게 줄어 조회 시간을 단축시킬 수 있다. 하지만 데이터를 갱신(INSERT, UPDATE, DELETE)하면 B-tree의 모양을 유지하기 위해 인덱스 갱신도 부수적으로 발생하기 때문에 처리 성능이 떨어진다.
1. B-tree와 B+-tree
1.1 B-tree
B-tree(Balanced-tree)는 데이터의 검색 시간을 단축하기 위한 자료구조로, 루트 노드(Root Node), 내부 노드(Internal Node), 리프 노드(Leaf Node)로 구성되며 리프 노드가 모두 같은 레벨에 존재하는 균형 트리이다. B-tree의 각 노드는 탐색 키, 데이터, 포인터를 가지며, 탐색 키는 값에 따라 오름차순으로 정렬되어 있다. 탐색 키 좌우에 있는 포인터는 각각 현재 탐색 키보다 작거나 큰 값을 가진 다음 노드를 가리킨다. 따라서 데이터 검색 시 탐색 키 값을 비교하여 다음 단계의 노드를 쉽게 찾을 수 있다.
B-tree는 탐색 키가 새로 추가되거나 삭제될 경우 동적으로 노드를 분할하거나 통합하여 항상 균형 상태를 유지한다.
1.2 B+-tree
B+-tree는 B-tree와 달리 오직 리프 노드에만 데이터를 저장한다. 그리고 각각의 리프 노드는 연결리스트(Linked List)로 연결되어 있는 구조를 가진다.
B+-tree에서는 데이터가 리프 노드에만 저장되기 때문에 저장 공간이 확보되어 B-tree보다 더 많은 탐색 키를 저장할 수 있다. 또한 테이블을 풀 스캔(Full Scan)하는 경우 리프 노드만 확인하면 되기 때문에, 풀 스캔 시 B-tree에 비해 조회 속도가 빠르다. 하지만 모든 데이터가 리프 노드에 있기 때문에 탐색 키 값이 여러 노드에서 중복될 수 있다.
(참고) https://zorba91.tistory.com/293
2. 인덱스 종류
2.1 클러스터 인덱스(Clustered Index)
클러스터 인덱스는 테이블의 기본 키를 탐색 키로 가지는 인덱스로 기본 인덱스라고도 부른다. 연속된 탐색 키 값을 가진 레코드를 묶어서 같은 블록에 저장하며, 테이블 당 기본 키는 하나이기 때문에 클러스터 인덱스 또한 하나만 생성할 수 있다. 클러스터 인덱스에서는 리프 노드에 페이지의 주소 값 대신 테이블의 레코드 자체가 저장된다. 레코드는 탐색 키 값에 따라 오름차순으로 정렬된 형태로 저장되어 있어, 탐색 키 값에 대한 동등(=) 및 범위(BETWEEN) 검색 모두 유리하다.
MySQL에서는 테이블 생성 시 기본 키(PK)를 지정하면 클러스터 인덱스를 자동으로 생성하고, 기본 키를 지정하지 않으면 맨 처음에 선언한 UNIQUE 속성에 대해 클러스터 인덱스를 생성한다. 만약 기본키와 UNIQUE 속성 모두 없다면 MySQL이 자체 생성한 행 번호(Row ID)를 이용해 클러스터 인덱스를 생성한다.
2.2 보조 인덱스(Secondary Index)
보조 인덱스는 미리 지정한 특정 속성을 탐색 키로 가지는 인덱스로, 보조 인덱스의 리프 노드에는 테이블 내에서의 데이터 위치인 Row ID가 저장된다. Row ID는 <Block 번호-Block 내의 Row 위치>의 형태로 구성되어 있기 때문에, 데이터가 테이블에서 탐색 키를 기준으로 무작위로 저장되어 있더라도 쉽게 찾을 수 있다. 이처럼 보조 인덱스에서는 데이터가 탐색 키를 기준으로 정렬되어 있지 않기 때문에, 동등(=) 검색은 성능을 보장할 수 있으나 범위(BETWEEN) 검색은 빠른 성능을 보장하지 못한다.
보조 인덱스는 클러스터 인덱스와 달리 테이블 당 여러 개를 생성할 수 있으며, 단일 속성을 탐색 키로 가지는 인덱스뿐 아니라 여러 개의 속성을 탐색 키로 가지는 인덱스 또한 만들 수 있다.
3. 인덱스 생성 기준
인덱스는 조회 성능을 향상시켜주는 장점이 있지만, 인덱스를 저장하기 위해 추가적인 저장 공간을 차지하고 갱신 시 성능이 떨어지는 단점이 존재한다. 따라서 인덱스 생성은 이러한 트레이드오프를 고려해가며 실시해야 한다.
3.1 크기가 큰 테이블에만 인덱스를 생성한다.
크기가 작은 테이블은 풀 스캔과 레인지 스캔이 성능상 큰 차이가 없기 때문에, 크기가 큰 테이블에만 인덱스를 생성한다.
3.2 카디널리티가 높은 속성을 탐색 키로 선정한다.
인덱스를 만드는 속성을 결정하는 기준으로 가장 중요한 것은 카디널리티(Cardinality)이다. 카디널리티는 값의 분산도를 나타내는 단어로, 특정 속성에 대해 값의 중복이 적으면 카디널리티가 높고 중복이 많으면 카디널리티가 낮다. 예를 들어 주민등록번호는 사람마다 다르므로 값의 중복이 없어 카디널리티가 매우 높지만, 성별은 남과 여 2가지 값만 존재하므로 중복이 매우 많아 카디널리티가 매우 낮다.
값의 중복이 적을수록 인덱스를 통해 검색 대상을 더 많이 줄일 수 있기 때문에, 조회 성능 개선 효과를 얻으려면 카디널리티가 높은 속성을 탐색 키로 선정해야 한다.
정규화
하나의 릴레이션을 좀 더 단순하고 바람직한 구조를 갖는 두 개 이상의 릴레이션으로 쪼개는 과정을 정규화라고 한다. 정규화는 정규화되지 않은 릴레이션을 보다 좋은 구조를 갖는 릴레이션으로 단계적으로 변환해가는 과정이다.
나쁘게 설계된 릴레이션 또는 정규화되지 않은 릴레이션들은 저장 공간을 낭비하고, 다음의 세 가지 갱신 이상을 유발시킬 수 있다.
- 수정 이상 : 중복된 데이터 중 일부만 수정하여 데이터의 불일치가 발생한다.
- 삽입 이상 : 불필요한 데이터를 함께 저장하지 않으면 어떤 데이터를 저장하는 것이 불가능한 문제가 발생한다.
- 삭제 이상 : 어떤 데이터를 삭제할 때 필요한 데이터도 함께 삭제되는 문제가 발생한다.
정규화는 함수적 종속성과 기본 키를 기반으로 기존의 릴레이션을 분해함으로써, 중복과 갱신 이상을 최소화한다.
1. 함수적 종속성
정규화에서 가장 중요한 작업 중 하나는 함수적 종속성들을 찾아내고 기록하는 것이다. 만일 릴레이션에서 A 속성의 값이 B 속성의 값을 고유하게 결정할 수 있으면, 즉 A 속성이 B 속성의 결정자이면 B가 A에 함수적으로 종속한다고 말한다.
이때 함수적 종속성은 실세계의 의미에 따라 바뀔 수 있다. 어떤 응용 프로그램에서는 A 속성이 B 속성의 결정자이지만, 또 다른 응용 프로그램에서는 A 속성이 B 속성의 결정자가 아닐 수도 있다.
1.1 완전 함수적 종속성
릴레이션에서 B 속성이 A 속성에 함수적으로 종속하면서 A 속성의 어떤 진부분 집합에도 함수적으로 종속하지 않으면, B 속성은 A 속성에 완전하게 함수적으로 종속한다고 말한다.
위 그림에서 <직책> 속성은 <사원번호, 부서번호> 속성에 완전 함수적으로 종속한다.
1.2 이행적 함수적 종속성
B 속성이 A 속성에 함수적으로 종속(A → B)하고, C 속성이 B 속성에 함수적으로 종속(B → C)하면, C 속성은 A 속성에 이행적으로 종속(A → B → C)한다고 말한다.
2. 정규형
정규형에는 제 1정규형, 제 2정규형, 제 3정규형, BCNF 등이 있다. 제 2정규형부터 BCNF까지의 정규형은 함수적 종속성 이론에 기반을 둔다.
2.1 제 1정규형
릴레이션의 모든 속성에 반복 그룹이 나타나지 않고 원자 값만 가지면 제 1정규형을 만족한다.
2.2 제 2정규형
릴레이션이 제 1정규형을 만족하면서, 어떤 후보 키에도 속하지 않는 모든 속성들이 기본 키에 완전하게 함수적으로 종속하면 제 2정규형을 만족한다.
기본 키가 한 개의 속성으로 이루어진 릴레이션이 제 1정규형을 만족하면 동시에 제 2정규형도 만족하게 된다.
2.3 제 3정규형
릴레이션이 제 2정규형을 만족하면서, 키가 아닌 모든 속성이 기본 키에 이행적으로 종속하지 않으면 제 3정규형을 만족한다.
2.4 BCNF (Boyce-Codd 정규형)
릴레이션이 제 3정규형을 만족하면서, 모든 결정자가 후보 키이면 BCNF를 만족한다.
하나의 후보 키만을 가진 릴레이션이 제 3정규형을 만족하면 동시에 BCNF도 만족하게 된다.
3. 역정규화 (반정규화)
성능상의 관점에서만 보면 높은 정규형을 만족하는 릴레이션 스키마가 최적인 것은 아니다. 한 정규형에서 다음 정규형을 진행될 때마다 하나의 릴레이션이 두 개 이상의 릴레이션으로 분해되기 때문에, 같은 정보를 조회할 때 여러 릴레이션에 접근해야 하므로 조인 연산이 증가하게 된다.
역정규화는 빈번하게 수행되는 검색 질의들의 수행 속도를 높이기 위해, 이미 분해된 두 개 이상의 릴레이션들을 다시 합쳐서 하나의 릴레이션으로 만드는 작업이다. 성능상의 요구를 만족시키기 위해 데이터 중복 및 갱신 이상을 대가로 치르면서 보다 낮은 정규형으로 되돌아가기도 한다.
트랜잭션
트랜잭션은 데이터베이스 응용 프로그램에서 하나의 작업을 수행하는 데이터베이스 연산들의 모임이다.
DBMS는 트랜잭션을 관리하기 위해 동시성 제어 모듈과 회복 모듈을 제공한다.
- 동시성 제어 모듈 : 동시에 수행되는 트랜잭션들 간의 간섭(상호작용)을 제어하여 데이터베이스의 일관성을 보장한다.
- 회복 모듈 : 데이터베이스를 갱신하는 도중에 시스템이 고장나도 데이터베이스의 일관성이 유지되도록 한다.
ACID 특성
트랜잭션은 아래의 네 가지 특성을 만족하는데, 각 특성의 앞글자를 따서 ACID 특성이라고 부른다.
1) 원자성(Atomicity)
원자성은 한 트랜잭션 내의 모든 연산들이 완전히 수행되거나 전혀 수행되지 않음(All or Nothing)을 의미한다. 즉, 한 트랜잭션의 모든 연산이 데이터베이스에 완전히 반영되거나 전혀 반영되지 않아야 한다. 시스템이 다운되는 경우 DBMS의 회복 모듈은 부분적으로 데이터베이스를 갱신한 트랜잭션의 영향을 취소함으로써 트랜잭션의 원자성을 보장한다.
2) 일관성(Consistency)
일관성은 트랜잭션이 데이터베이스의 일관된 상태를 유지해야 함을 의미한다. 한 트랜잭션을 정확하게 수행하고 나면 데이터베이스는 하나의 일관된 상태에서 다른 일관된 상태로 바뀐다. DBMS의 동시성 제어 모듈은 다수 사용자의 데이터베이스 접근을 조정함으로써 데이터베이스의 일관성을 보장한다.
3) 고립성(Isolation)
고립성은 여러 트랜잭션이 동시에 실행될 때 각각의 트랜잭션은 다른 트랜잭션에 영향을 주지 않고 독립적으로 실행되어야 함을 의미한다. 한 트랜잭션이 데이터를 갱신하는 동안 다른 트랜잭션이 해당 데이터에 접근하지 못하도록 해야 한다. DBMS의 동시성 제어 모듈은 트랜잭션의 고립성을 보장하며, DBMS에서는 동시성을 효율적으로 제어하기 위해 다양한 고립 수준(격리 수준)을 제공한다.
4) 지속성(Durability)
지속성은 성공적으로 완료된 트랜잭션의 결과가 영구적으로 저장되어야 함을 의미한다. 한 트랜잭션이 완료되면 해당 트랜잭션이 갱신한 데이터는 이후 시스템 고장이 발생하더라도 손실되지 않아야 한다. DBMS의 회복 모듈은 시스템이 다운된 경우에도 트랜잭션의 지속성을 보장한다.
커밋과 롤백
1. 커밋(COMMIT)
커밋은 트랜잭션이 성공적으로 완료되었음을 알리는 연산이다. 트랜잭션이 수행한 갱신을 데이터베이스에 반영해야 함을 DBMS에게 알리는 역할을 한다. COMMIT 연산을 수행하면 데이터베이스는 새로운 일관된 상태를 가지게 된다.
2. 롤백(ROLLBACK)
롤백은 트랜잭션의 일부를 성공적으로 끝내지 못했음을 알리는 연산이다. 트랜잭션이 수행한 갱신이 데이터베이스에 일부 반영되었다면 취소해야 함을 DBMS에게 알리는 역할을 한다.
트랜잭션에서 여러 로직들을 묶을 때는 외부 API를 호출하는 로직이 있으면 안 된다. 만약 있다면 롤백이 일어났을 때 어떻게 처리할 것인지에 대한 해결 방법이 있어야 하고, 트랜잭션 전파를 신경써서 관리해주어야 한다.
트랜잭션 고립 수준
트랜잭션 고립 수준(Isolation Level)은 한 트랜잭션이 다른 트랜잭션과 고립되어야 하는 정도를 나타낸다. 고립 수준이 낮으면 동시성은 높아지지만 데이터의 정확성은 떨어지고, 고립 수준이 높으면 데이터의 정확성은 높아지지만 동시성은 낮아진다. 동시성이 낮으면 동시에 실행되는 트랜잭션 수가 적어져서 시스템의 전체 처리량이 감소할 수 있기 때문에, 응용 프로그램의 성격에 따라 허용 가능한 고립 수준을 적절히 선택해야 한다.
트랜잭션의 고립 수준은 4가지로 구분되는데, 각 고립수준에 따라 DBMS가 사용하는 Locking의 동작 방식이 달라진다. 이때 각 고립 수준은 트랜잭션이 읽을 수 있는 데이터에 대해서만 차이가 있으며, 갱신하려는 데이터에 대해서는 차이가 없다. 4가지 고립 수준 모두 갱신하려는 데이터에 대해서는 독점 Lock을 걸고 해당 트랜잭션이 끝날 때까지 다른 트랜잭션은 접근하지 못하도록 막는다.
1. READ UNCOMMITTED
가장 낮은 고립 수준으로, 트랜잭션 내의 질의들이 공유 Lock을 걸지 않고 데이터를 읽는다. 공유 Lock을 걸지 않았기 때문에, 질의 도중 다른 트랜잭션에서 해당 데이터를 갱신할 수 있다. 따라서 다른 트랜잭션에서 COMMIT 하지 않은 데이터에 접근이 가능하여 오손 데이터 읽기(Dirty Read) 문제가 발생할 수 있다.
2. READ COMMITTED
트랜잭션 내의 질의들이 읽으려는 데이터에 대해 공유 Lock을 걸고, 읽기가 끝나자마자 Lock을 해제한다. 따라서 이후 동일한 데이터를 한 번 더 읽기 위해 공유 Lock을 걸고 데이터를 읽으면, 이전에 읽은 값과 다른 값을 읽는 경우가 발생할 수 있다. 즉, READ COMMITTED 고립 수준에서는 반복할 수 없는 읽기(Unrepeatable Read) 문제가 발생할 수 있다.
3. REPEATABLE READ
트랜잭션 내의 질의들이 읽으려는 데이터에 대해 공유 Lock을 걸고, 트랜잭션이 끝날 때까지 보유한다. 따라서 한 트랜잭션 내에서 동일한 질의를 두 번 이상 수행해도 매번 같은 결과를 얻게 된다. 하지만 REPEATABLE READ 고립 수준에서는 현재 보유중인 Lock을 필요로 하는 다른 트랜잭션의 대기 시간이 길어지고 데드락이 발생할 수 있다.
4. SERIALIZABLE
가장 높은 고립 수준으로, 질의에서 검색되는 튜플들 뿐만 아니라 인덱스에 대해서도 공유 Lock을 걸고 트랜잭션이 끝날 때까지 보유한다. 따라서 SERIALIZABLE 고립 수준에서는 다른 고립 수준에서 나타나는 유령 데이터 읽기(Phantom Read) 문제도 해결된다. 하지만 REPEATABLE READ 고립 수준과 마찬가지로 현재 보유중인 Lock을 필요로 하는 다른 트랜잭션의 대기 시간이 길어지고 데드락이 발생할 수 있다
- 유령 데이터 읽기(Phantom Read) : 일정 범위의 레코드를 두 번 이상 읽을 때, 첫 번재 질의에서 검색되지 않았던 레코드가 두번째 질의에서 검색되는 현상을 유령 데이터 읽기 문제라고 한다.
'컴퓨터공학' 카테고리의 다른 글
[네트워크] 쿠키와 세션 (1) | 2023.05.14 |
---|---|
[컴퓨터공학] 네트워크 (0) | 2023.04.12 |
[컴퓨터공학] JAVA(자바) 2 (0) | 2023.03.30 |
[컴퓨터공학] 운영체제 (0) | 2023.03.14 |
[컴퓨터공학] SPRING(스프링) (0) | 2023.03.12 |
댓글