테이블 컬럼이 원자값(하나의 값)을 갖도록 테이블을 분리시키는 것이다. (문자열 반점으로 여러개 허용 안함, 전화번호 같이 여러개 값이 있을때는 rows를 분리한다)
제 2정규화
테이블의 모든 컬럼이 완전 함수적으로 종속해야한다. 기본키가 복합키로 묶여 있을떄 하나의 키만으로 다른 컬럼을 결정지을 수 있으면 안된다. (기본키의 부분집합 키가 결정자가 되면 안됨, 오로지 기본키로 모든 컬럼을 결정지을 수 있어야 함.)
제 3정규화
이행적 종속을 없애기 위해 테이블 분리 (이행적 종속 A→ B, B → C,이면 A→C이다, 키 여러개가 결정자가 되는 것을 막기 위해 테이블을 분리하는 것이다.)
데이터베이스 Anomaly(이상)
삽입이상 : 불필요한 데이터를 추가해야지, 삽입할 수 있는 상황
기본키가 {Student ID, Course ID} 인 경우 -> Course를 수강하지 않은 학생은 Course ID가 없는 현상이 발생함. 결국 Course ID를 Null로 할 수밖에 없는데, 기본키는 Null이 될 수 없으므로, Table에 추가될 수 없음. 굳이 삽입하기 위해서는 '미수강'과 같은 Course ID를 만들어야 함.
갱신 이상 : 일부만 변경하여, 데이터가 불일치 하는 모순의 문제
만약 어떤 학생의 전공 (Department) 이 "컴퓨터에서 음악"으로 바뀌는 경우.모든 Department를 "음악"으로 바꾸어야 함. 그러나 일부를 깜빡하고 바꾸지 못하는 경우, 제대로 파악 못함.
삭제 이상 : 튜플 삭제로 인해 꼭 필요한 데이터까지 함께 삭제되는 문제
만약 어떤 학생이 수강을 철회하는 경우, {Student ID, Department, Course ID, Grade}의 정보 중Student ID, Department 와 같은 학생에 대한 정보도 함께 삭제됨.
데이터베이스 안의 레코드를 처음부터 풀스캔하지않고 B+ TREE로 구성된 구조에서 INDEX 검색으로 속도를 향상시킴
디스크와 데이터베이스
디스크 : 섹터(디스크 영역을 파이처럼 나눔)와 트랙(디스크의 깊이)로 나누어져 있음
블럭은 특정 트랙의 섹터 인데 블럭이 512바이트면 1바이트씩 이루어져 있는데 1바이트는 각자의 주소를 가지고 있으며 이를 offset이라고 한다.
디스크의 특정 지점을 읽으려면 섹터, 블록 offset을 알아야함
데이터 플로우 : 메인 메모리에서 프로그램을 돌리려면 디스크로부터 데이터를 가져오고 결과가 나오면 그것을 다시 디스크에 담는다.
메인 메모리 내의 프로그램이 쓰는 데이터 집합을 data structure라고 부르며, 데이터를 디스크에서 효율적으로 조직하는 것을 DBMS라고 부른다.
Database에서 여러 record를 저장할 때 디스크의 하나의 블록으로 저장하기 힘들기 때문에 빠른 검색을 위해 index 탐색을 사용하는데 이는 eid 와 pointer로 구성되어 있으며 pointer는 각각의 eid가 속한 레코드를 가르킨다.
만약 레코드가 엄청나게 많아질 경우 기본 인덱스 탐색으로 어려워진다. 이러면 인덱스를 위한 인덱스를 만드는데 이를 멀티 인덱스라고 한다.
탐색 트리
다원 탐색 트리
트리의 각 노드에 여러개의 데이터를 가질 수 있고 하위 트리 수를 임의로 설정 가능하여 트리의 높이 문제나 균형 비용 문제를 해결할 수 있다.
이진 탐색 트리(Binary tree) : 값이 왼쪽 자식 노드 < 부모 노드 < 오른쪽 자식 노드
트리의 순회 : 트리 자료구조에 포함된 노드를 특정한 방법으로 한번씩 방문하는 방법 의미
전위 순회 : 루트 먼저 방문 (루트 -왼 - 오)
중위 순회 : 왼쪽 자식을 방문한 뒤에 루트를 방문 (왼-루트-오)
후위 순회 : 왼쪽과 오른쪽 자식을 방문한 뒤에 루트를 방문 (왼-오-루트)
이진트리 문제점은 좌우 균형이 맞지 않으면 비효율적이다.
트리의 높이가 성능을 결정하는데 이진트리는 삽입/삭제시 높이가 유지된다. 하지만 b tree의 경우 삽입과 삭제가 필요하면 스스로 균형을 유지한다.
b tree
하나의 노드에 여러 자료가 배치되는 트리구조
한 노드에 M개의 자료가 배치되면 M차 B-tree라고 하는데 M이 짝수냐 홀수냐에 따라 알고리즘이 다르다.
조건
노드의 자료수가 N이면 자식의 수는 N+1이여야한다.
각 노드의 자료수는 정렬된 상태여야 한다.
값의 정렬 순서는 왼쪽 자식 노드 < 부모 노드 < 오른쪽 자식 노드
b+ tree
b tree를 개량한 자료구조
B-Tree와의 가장 큰 차이점은 Inner Node에는 Key만 저장이 되고 Leaf Node에 Key와 Data를 함께 저장한다는 점이다 (자식이 없는 노드를 잎(leaf) 노드라 하고 잎노드가 아닌 노드를 내부(inner) 노드라고 한다)
DB DDL, DML, DCL
DML : 데이터 조작어 : 데이터를 조회하거나 검색 및 변형을 가하기 위한 명령어 (SELECT,INSERT,UPDATE,DELETE)
DDL : 데이터나 테이블의 구조를 정의하는데 사용되는 명령어 (CREATE, ALTER, DROP, RENAME)
DCL : 데이터 제의어로 데이터베이스에 접근하고 객체들을 사용할 수 있도록 권한을 주고 회수하는 것
TCL : 논리적인 작업 단위를 묶어서 DML에 의해 조적된 결과를 작업단위(트랜잭션)별로 제어하는 명령어
데이터베이스 인덱싱 탐색
테이블 생성시 3가지 파일 생성됨
FRM : 테이블 구조 저장 파일
MYD : 실제 데이터 파일
MYI : index 정보 파일
해당 구조의 단점
index 생성시 mdb 파일 크기 증가
한 페이지를 동시에 수정할 수 있는 병생성 줄어든다.
데이터 업데이트, 수정, 삭제시 성능이 떨어진다.
데이터 변경 작업이 자주 일어나는 경우 index를 재작성해야 하므로 성능이 떨어짐
indexing 탐색을 사용하는 상황
좋은 경우 : where, join 외래키가 자주 사용되는 column
나쁜 경우 : data 중복도가 높으며 DML이 자주 일어나는 column
DML이 일어났을 때의 상황
INSERT : 기존 BLOCK에 여유가 없을 때 새로운 DATA가 입력된다.
DELETE : 테이블에서 data가 delete 되는 경우 data가 지워지고 다른 data가 그 공간을 사용 가능함.
UPDATE : 테이블에서 update가 발생하면 index는 업데이트 할 수 없다.
트랜잭션
데이터베이스 상태를 변화시키기 위해 수행하는 작업 단위이다. SQL 쿼리(select,insert,delete,update) 를 사용하여 DB에 접근하는 것이 상태를 변화하는 것이다.
동시성 제어의 기본 단위이며 하나의 작업 처리를 위한 논리적인 단어이다.
작업단위 : 많은 SQL 명령문들을 사람이 정하는 기준에 따라 정하는 것
트랜잭션 설계를 잘 만드는 것이 데이터를 다룰 때 많은 이점을 가져다준다.
트랜잭션 수행 과정
활동 : 트랜잭션이 실행중인 상태
부분 완료 : 실행을 마치고선 데이터 베이스에 결과를 저장하기 직전 상태
완료 : 트랜잭션 변경 내용을 성공적으로 저장한 상태
실패 : 트랜잭션 실행 중 오류가 난 상태
철회 : ROLLBACK 명령어를 통해 트랜잭션 수행 이전 상태로 돌린 상태
트랜잭션 특징
원자성 : 트랜잭션이 DB에 모두 반영되거나 혹은 전혀 반영 되지 않아야 한다.
일관성 : 트랜잭션의 작업 처리 결과는 항상 일관성이 있어야 한다.
독립성 : 둘 이상의 트랜잭션이 동시에 병행 실행되고 있을 때, 어떤 트랜잭션도 다른 트랜잭션 연산에 끼어들 수 없다!
지속성 : 트랜잭션이 성공적으로 완료되었으면, 결과는 영구적으로 반영되어야 한다.
commit
하나의 트랜잭션이 성공적으로 끝났고, DB가 일관성이 있는 상태일 때 이를 알려주기 위해 사용하는 연산
rollback
하나의 트랜잭션 처리가 비정상적으로 종료되어 트랜잭션 원자성이 깨진 경우 이전의 상태로 rollback 할 수 있음.
트랜잭션 스케쥴
여러 트랜잭션이 동시에 실행되는 경우 스케줄링 활용하여 연산들의 실행 순서를 정한다.
직렬 스케줄 : 한 트랜잭션이 끝나고 다음 트랜잭션 실행 하는 방법
비직렬 스케줄 : 인터리브 실행기법으로 각 트랜잭션의 연산들이 번갈아가며 병행 실행 하는 방법
트랜잭션 격리 수준
isolation level : 트랜잭션에서 일관성 없는 데이터를 허용하는 수준
필요성 : 트랜잭션이 독립적으로 수행을 하도록 하는데, Locking을 통해 트랜잭션이 DB를 다루는 동안 다른 트랜잭션이 관여하지 못하도록 막는것이 필요하다. 하지만 무조건적인 Locking은 성능을 떨어지게 하기 때문에 최대한 효율적인 Locking 방법이 필요하다.
Isolation level whdfb
Read Uncommitted ( level 0 )
트랜잭션에 처리중이거나, 아직 Commit 되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용함
이 방법은 데이터베이스 일관성을 유지하는 것이 불가
SELECT 문장이 수행되는 동안 해당 데이터에 Shared Lock이 걸리지 않는 계층
Read committed ( level 1 )
트랜잭션이 수행되는 동안 다른 트랜잭션이 접근할 수 없어 대기함
SELECT 문장이 수행되는 동안 해당 데이터에 Shared Lock이 걸리는 계층
Repeatable Read ( level 2 )
트랜잭션이 범위 내에서 조회한 데이터 내용이 항상 동일함을 보장함
트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 Shared Lock이 걸리는 계층
Seruakuzabke ( level 3 )
완벽한 읽기 일관성 모드를 제공함
다른 사용자는 트랜잭션 영역에 해당되는 데이터에 대한 수정 및 입력 불가능
트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 Shared Lock이 걸리는 계층
저장 프로시저 ( SP )
데이터베이스에서 SQL을 통해 작업을 하다보면 하나의 쿼리문으로 결과를 얻을 수 없을 때가 생긴다. 여러줄의 쿼리문을 한 번의 요청으로 실행할 때 사용하는 방식이 바로 프로시저이다.
프로시저를 만들어두면 어플리케이션에서 여러 상황에 따라 해당 쿼리문이 필요할 때 인자 값만 전달하여 쉽게 원하는 결과물을 받아낼 수 있다.
CREATE OR REPLACE PROCEDURE 프로시저명(변수명1 IN 데이터타입, 변수명2 OUT 데이터타입) -- 인자 값은 필수 아님
IS
[
변수명1 데이터타입;
변수명2 데이터타입;
..
]
BEGIN
필요한 기능; -- 인자값 활용 가능
END;
EXEC 프로시저명; -- 호출
프로시저 장점
최적화 & 캐시
프로시저의 최초 실행 시 최적화 상태로 컴파일이 되며, 그 이후 프로시저 캐시에 저장된다.
유지 보수
작업이 변경될 때 다른 작업을 건드리지 않고 프로시저 내부에서만 수정하면 된다.
트래픽 감소
클라이언트가 직접 SQL문을 작성하지 않고 프로시저명에 매개변수만 담아 전달하면 된다.
보안
프로시저 내에서 참조 중인 테이블의 접근을 막을 수 있다.
프로시저 단점
호환성
구문 규칙이 SQL / PSM 표준과의 호환성이 낮기 때문에 코드 자산으로 재사용성이 나쁘다.
성능
성능이 느리다
디버깅
에러가 났을 때 어디서 잘못됐는지 디버깅하는 것이 힘들 수 있다.
DBA가 있는 경우에는 쓰고 없는 경우에 쓰면 헬이 될 수 있다.는게 조사 결과이다.
DBMS 구조
질의 처리기(Query Processor)
저장 시스템 (Storage System )
SQL VS NOSQL
SQL
정해진 스키마에 따라 테이블이 저장된다.
데이터는 관계를 통해 여러 테이블로 분산된다.
하나의 테이블에서 중복 없이 하나의 테이터만을 관리하기 때문에 다른 테이블에서 부정확한 데이터를 다룰 위험이 없어지는 장점이 있다.
NOSQL
스키마와 관계가 없다.
레코드를 document라고 부르며 다른 구조의 데이터를 같은 Collection에 저장이 가능하다. JSON과 유사하다고 보면 된다.
NOSQL에는 이런 점 떄문에 JOIN이라는 개념이 없다. 따라서 조인을 잘 사용하지 않고 자주 변경되지 않을 데이터일 때 NOSQL을 쓰면 효율적이다.
데이터베이스 확장 개념
수직적 확장 : 단순히 데이터베이스 서버 성능을 향상시키는 것
수평적 확장 : 더 많은 서버가 추가되고 데이터베이스가 전체적으로 분산됨을 의미
데이터베이스 저장방식으로 SQL은 수직적 확장만 제공한다.
장단점
SQL 장단점
장점 : 명확하게 정의된 스키마, 데이터 무결성 보장, 관계는 각 데이터를 중복없이 한번만 저장
단점 : 덜 유연하며 조인문으로 인해 복잡한 쿼리가 만들어 질 수 있다. 대체로 수직적 확장만 가능
사용처 : 관계를 맺고 있는 데이터가 자주 변경되며, 명확한 스키마가 있을 경우
NOSQL
장점 : 스키마 없어 유연하며 저장된 데이터 조정이 가능하고 새로운 필드 추가 가능, 데이터 읽어오는 속도 빨라지며 (쿼리가 필요 없어서) 수직/수평 확장이 모두 가능함
단점 : 유연성으로 인해 데이터 구조 결정을 미루게 될 수 있음, 데이터 중복 업데이트해야함. 데이터 중복시 모든 컬렉션에서 수정 작업을 진행해야함.
사용처 : 정확환 데이터 구조를 알 수 없고 데이터 변경이 자주 없으며 수평적으로 확장해야하는 경우