데이터 베이스 존재하기 이전에는 파일 시스템을 이용하여 데이터를 관리하였다. 데이터를 각각의 파일 단위로 저정하며 이러한 일들을 처리하기 위한 독립적인 애플리케이션과 상호 연동이 되어야 한다. 이 때의 문제점은 데이터의 종속성(상호 의존관계 맺음)과 중복성(여러 파일에 데이터 중복 저장)이다.
관계형 데이터 베이스는 가장 많이 사용되고 있는 데이터베이스 중 하나로, 테이블로 이루어져있으며 key-value값으로 관계를 나타낸다. 즉, 형과 열로 이루어진 각각의 테이블을 고유값을 참조하여 서로 연결하는 것을 표현한다.
1) 후보키 (Candidate Key)
2) 기본키 (Primary Key)
3) 대체키 (Alternate Key)
4) 슈퍼키 (Super Key)
5) 외래키 (Foreign Key)
장점
1. 범용적이고 안정적이며 데이터의 일관성을 보장한다.
2. 복잡한 형태의 쿼리가 가능해서 원하는 데이터를 추출할 수 있다. (join)
단점
1. 테이블간의 관계를 맺는 과정이 굉장히 복잡하다.
2. 대량의 데이터 입력, 조회시 성능 저하
3. 테이블 구조의 변경 -> 많은 패널티
NoSQL은 NotOnlySQL의 약자로 단순히 SQL뿐만 아니라 부가적인 기능을 지원한다는 의를 가진다.
RDB와 달리 관계가 없는 비관계형 데이터베이스이다. RDBMS가 처리하지 못하는 비정형 데이터를 처리하고 용량의 한계를 뛰어넘기 위해서 나타났다.
기본적으로 NoSql은 최초 테이블 생성시 테이블간의 관계를 정의하지 않는다. 따라서 빠른 속도의 설계가 가능하지만, 이로 인해 RDB처럼 join연산과 같은 복잡한 쿼리가 불가능해 특정 데이터를 추출하는데 어려움이 있다. 대표적으로 MongoDB, Redis가 있다.
1) 데이터 정의어 (DDL : Data Definition Language)
2) 데이터 조작어 (DML : Data Manipulation Language)
3) 데이터 제어 언어(DCL : Data Control Language)
분리되어 있는 데이터를 연결하여 하나의 결과 데이터 셋으로 출력할때 사용한다.
Inner join은 교집합( A ∩ B ) 연산과 같다.
Left outer join은 교집합 연산 결과와 차집합 연산 결과를 합친 것( (A ∩ B) ∪ (A - B) )과 같다.
Right outer join도 교집합 연산 결과와 차집합 연산 결과를 합친 것( (A ∩ B) ∪ (A - B) )과 같습니다. 차집합의 기준 집합이 Left outer join과 반대일 뿐입니다.
Full outer join은 합집합 연산 결과와 같습니다.
함수 종속성 이론을 통해 데이터의 중복성을 최소화하고 일관성 등을 보장하여 데이터 베이스 품질과 성능을 향상시키는 과정. 정규화 수준이 높을수록 유연한 데이터 구축이 가능하고 정확성이 높아짐. 단점으로 접근이나 조인 조회 성능 저하
한 릴레이션에 여러 엔티티 속성을 혼합하면 중복 저장, 공간 낭비, 갱신 이상
제 3 정규형
제 2 정규형이면서, 기본키가 아닌 모든 속성이 기본키에 대해 이행적 함수적 종속을 만족하지 않는 정규형
[주문번호 -> 고객번호]이고 [고객번호 -> 주소]이므로
[주문번호 -> 주소]는 이행적 함수적 종속
BCNF(Boyce-Codd 정규형)
결정자가 모두 후보키인 정규형이다.(후보키가 아닌 결정자를 제거하는 정규형이다)
(학번, 과목명) –> 담당교수
(학번, 담당교수) –> 과목명
(담당교수 –> 과목명) 을 만족하고 있다.
‘수강 교수’ 테이블의 후보키는 (학번, 과목명)과 (학번, 담당교수)이다.
함수적 종속 [담당교수 –> 과목명]이 존재하는데
담당교수가 ‘수강 교수’ 테이블에서 후보키가 아니기 때문에 ‘수강 교수’ 테이블은 BCNF가 아니다.
후보키 : 테이블에서 각 행을 유일하게 식별할 수 있는 최소한의 속성들의 집합
다치 종속 : 속성 A -> (속성 B, 속성 C) 일때, A->B를 만족하고, **B와 C가 무관**할때 B는 A에 다치종속 관계라고 하며, A->>B 라고 한다.
다치종속을 제거하지 않으면 A->>B 상황에서 C값이 중복될수 있다.
예를들어,
(회원번호)-> (이름, 주문번호) 인 테이블에서
(회원번호 ->> 주문번호) 일때,
흐쟈미란 고객이 책을 두번 주문하면 흐쟈미 이름이 불필요하게 두번 중복된다.
이를 해결하기 위해서는 (회원번호->이름), (회원번호->주문번호)로 쪼개주는것이 제 4정규형이다.
한 테이블을 분해했다가 분해된 결과들을 다시 조인하면 당연히 원래의 테이블로 복원된다고 기대하지만 그렇지 못한 경우가 있다.
다시 조인하면 예상하지 못했던 튜플들이 생성되는 경우가 발생한다.
조인 종속 : 테이블을 분해한 결과를 다시 조인했을 때 원래의 테이블과 동일하게 복원되는 제약조건이다.
시스템의 성능 향상, 개발 및 운영의 편의성 등을 위해 정규화된 데이터 모델을 통합, 중복, 분리하는 과정으로 의도적으로 정규화 원칙을 위배하는 행위
테이블 통합
두 개의 테이블이 조인되는 경우가 많아 하나의 테이블로 합쳐 사용하는 것이 성능 향상에 도움이 될 경우 수행한다. 두 개의 테이블에서 발생하는 프로세스가 동일하게 자주 처리되는 경우, 두 개의 테이블을 이용하여 항상 조회를 수행하는 경우 테이블 통합을 고려한다.
테이블 분할
테이블을 수직 또는 수펑으로 분할
인덱스는 색인으로 추가적인 쓰기 작업과 저장 공간을 활용하여 데이터베이스 테이블의 검색 속도를 향상시키기 위한 자료구조이다. -> 데이터 베이스에서는 데이터가 책의 내용이라면 데이터가 저장된 레코드의 주소가 인덱스 목록에 있는 페이지 번호이다.
DBMS의 인덱스는 항상 정렬되어 있어 저장성능은 낮지만 데이터를 읽는 속도는 빠르다.
DBMS는 인덱스를 어떻게 관리하고 있는지 살펴보자.
해시 테이블
(key, value)로 데이터를 저장하는 자료구조 중 하나로 빠른 데이터 검색이 필요할 때 유용하다. O(1)로 빠른 검색을 지원하지만 해시가 등호(=)연산에만 특화되었기 때문에 해시 테이블을 사용하는 경우가 매우 제한적이다. -> select 연산에서는 부등호(<,>)연산이 자주 사용되기 때문에 해시 테이블은 적합하지 않다.
B+-Tree 인덱스 알고리즘
일반적으로 사용되는 인덱스 알고리즘이다. B-tree는 밸런스 잡힌 트리로 데이터 검색에 효율적이지만 모든 노드를 방문해야 하는 비효율적인 단점이 있어 이를 개선시킨 B+Tree 인덱스를 사용한다.
B+Tree는 오직 leaf node에만 데이터를 저장하고 리프 노드가 아닌 node에서는 자식 포인터만 저장한다. 그리고 리프 노드 끼리는 Linked list로 연결되어 있다.
index의 성능과 고려해야할 사항
조회 쿼리는 향상시키지만 insert update delete 쿼리문에 별도의 추가 비용이 생긴다. 따라서 필요한 경우에만 index를 생성하는게 좋다. (중복이 없고 여러 데이터가 들어간 경우 (이름 주민번호))트랜잭션
데이터베이스 상태를 변화시키기 위해 수행되는 작업의 논리적 단위로 작업의 완전성을 보장해준다.
트랜잭션은 다음 4가지 특성을 만족한다.
트랜잭션 - 데이터의 정합성을 보장하기 위한 기능 - 하나의 논리적인 작업 셋 자체가 모두 적용되거나 적용되지 않음을 보장해주는 역할
lock - 동시성 제어 -> 여러 커넥션에서 동시에 동일한 자원을 요청할 경우 순서대로 한 시점에는 하나의 커넥션만 변경할 수 있게 해주는 역할
트랜잭션 격리수준(isolation level)이란 동시에 여러 트랜잭션이 처리될 때, 트랜잭션끼리 얼마나 서로 고립되어 있는지를 나타내는 것이다.
즉, 간단하게 말해 특정 트랜잭션이 다른 트랜잭션에 변경한 데이터를 볼 수 있도록 허용할지 말지를 결정하는 것이다.
아래로 내려갈수록 고립 정도가 높아지며, 성능이 떨어진다.
READ UNCOMMITTED : 어떤 트랜잭션의 변경내용이 commit이나 rollback과 상관없이 다른 트랜잭션에 보여진다.
A 트랜잭션 10번 사원 나이 27 -> 28변경 커밋은 x
B 트랜잭션 10번 사원 나이 조회 -> 28 더티 리디 발생
A 트랜잭션 rollback
READ COMMITTED : 변경 내용이 commit 되어야한 다른 트랜잭션에서 조회 가능, 가장 기본적인 격리수준
B 트랜잭션에서 10번 사원의 나이를 조회 -> 27살
A 트랜잭션에서 10번 사원의 나이를 27살->28살로 바꾸고 커밋
B 트랜잭션에서 10번 사원의 나이를 다시 조회(변경되지 않은 이름이 조회됨)
28살이 조회됨
Non-repeatable Read Problem 발생
REPEATABLE READ : 트랜잭션이 시작되기 전에 커밋된 내용에 대해서만 조회 가능 Mysql의 기본
10번 트랜잭션이 5번 사원을 조회
12번 트랜잭션이 5번 사원의 이름을 변경하고 커밋
10번 트랜잭션이 5번 사원을 다시 조회
언두 영역에 백업된 데이터 반환
자신의 트랜잭션 번호보다 낮은 트랜잭션 번호에서 변경된것만 보게 되는 것
트랜잭션의 시작된 시점의 데이터를 일관되게 보여줌을 보장
트랜잭션은 범위를 최소화하여 적용하는것이 좋다. 일반적으로 데이터베이스 커넥션의 개수가 제한적이기 때문에 해당 커넥션의 소유 시간이 길어지면 커넥션을 기다려야 하는 시간이 발생할 수도 있다.
https://sparkdia.tistory.com/17
https://goodgid.github.io/DB-Normalization(2)/
https://github.com/Seogeurim/CS-study/tree/main/contents/database
https://medium.com/@duddk1551/db-rdb-관계형데이터베이스-와-nosql-adbd21f6f9f1
https://velog.io/@simonyun97/데이터베이스의-개념과-구성요소
https://github.com/JaeYeopHan/Interview_Question_for_Beginner/tree/master/Database#데이터베이스
https://joont92.github.io/db/트랜잭션-격리-수준-isolation-level/