들어가며
이 포스팅의 내용은 <>에 나오는 내용을 요약한 것이다.
트렌잭션이란
데이터베이스에서 트렌잭션이란, 한 단위의 일을 수행하는 일련의 SQL문이다. 트렌잭션이 만족하기 위해선 몇 가지 조건이 필요한데, 이 조건을 ACID라고 한다.
원자성(Atomicity)
트랜잭션을 구성하는 모든 명령이 실행되거나, 어떠한 명령도 실행되지 않아야 한다. 예를 들면, 은행 계좌에서 10만원을 인출한다고 가정하자. 돈을 인출했을때 10만원을 인출 성공하던지, 돈을 인출하지 못하던지 둘 중 하나의 결과만 있어야 한다.
5만원만 인출된다던지 이런 결과가 나오면 원자성을 만족하지 못하는 것이다.
일관성(Consistency)
트랜잭션이 끝난 후, 데이터베이스는 일관성을 유지해야 한다. 돈을 인출했을 때 트랜잭션이 끝나면 잔고가 맞아야 한다. 예를 들면 5만원씩 두번 인출하게 된다면, 10만원이 내 손에 있던지 다른 계좌로 이동하던지 둘 중 하나가 되어야 한다. 돈이 사라지지는 않는다.
독립성(Isolation)
모든 트랜잭션은 동시에 일어나는 다른 트랜잭션과 상관 없이 발생할 수 있다. 즉, 한번에 하나의 트랜잭션만 발생할 수 있다. 예를 들어 메리의 현금 인출기는 존의 현금 인출기가 트랜잭션을 수행하는 동안은 잔고를 볼 수 없거나, 트랜잭션 진행 중 이라는 메시지를 보게 된다.
지속성(Durablity)
트랜잭션이 끝난 후, 데이터베이스는 데이터를 정확히 저장하고 보호해야 한다. 트랜잭션이 끝난 다음에 트랜잭션이 반영된 데이터는 잘 저장되어야 한다.
테이블 제약조건
자식 테이블의 참조키로는 부모키에 존재하는 키의 값만 넣을 수 있다. 이를 참조 무결성 제약조건이라고 한다.
즉 A라는 테이블이 이름, 나이, 성별과 같은 사람들의 정보가 있는 테이블이라고 가정하자. 한 사람은 여러 개의 취미를 가질 수 있다. 이렇게 되면 테이블의 원자성을 위반하게 되므로, A테이블의 취미 종류를 다른 테이블로 찢어내고 그 테이블을 B테이블이라고 하자.
A와 B는 1:N관계이며 B테이블에는 A테이블의 키가 존재하게 된다. 이 때 B테이블에 존재하는 A 테이블의 키를 외래키라고 한다.
이렇게 될 때 B테이블의 외래키에는 A테이블의 PK에 존재하는 값만 넣을 수 있다. 이를 참조 무결성 제약조건이라고 한다.
다른 제약조건들은 기본키 제약조건(열을 생성할 때 UNIQUE를 사용하는 것)이 있다.
테이블 정규화를 하는 이유?
테이블을 쉽게 유지보수하고, 데이터를 변경하는 지점을 줄이기 위해서이다. DB에 데이터가 많아지면, 컬럼 하나를 새로 추가/삭제하는 것 또한 리소스가 상당히 커진다. 이에 변경될 수 있는 부분을 따로 떼어내어 관리하고, 데이터의 무경성을 보장하는 작업을 해야 하는데 이를 편리하게 하기 위해서 정규화를 진행한다.
1NF
- 각 행의 데이터들은 원자적 값을 가져야 한다.
- 각 행은 유일무일한 식별자인 기본키(Primary key)를 가지고 있어야 한다.
예를 들면, 소개팅 테이블을 만드는데 관심사를 넣는 컬럼이 있다고 생각해 보자. 입력을 세 개까지 받을 수 있어서 컬럼을 이렇게 생성했다.
interest1
interest2
interest3
쇼핑
수영
드라이브
이렇게 생성하면 각 행의 데이터들이 원자적 값이 아니다. 1:N 관계의 테이블을 하나 더 만들어서 작업하는 게 좋다. 이 경우 취미를 네 개까지 받을 수 있게 변경된다고 하더라도 변경 지점이 최소화될 수 있다.
2NF
- 1NF여야 한다.
- 부분적 함수 의존이 없다.
부분적 함수 의존이라 함은, 복합키를 PK로 사용할때 생길 수 있는 문제이다. (A,B)를 PK로 사용한다고 하면, (A, C) 가 C를 정의해야 한다. 즉, A가 바뀌면 C또한 바뀌어야 한다. 그런데 A 또는 C만 변경되어도 C가 바뀌지 않는다면, 이는 부분적 함수 의존이 있는 것이다.
3NF
- 2NF여야 한다.
- 이행적 종속 관계가 없다.
이행적 종속 관계라 함은, 키가 아닌 열들 중 하나가 변경되었을 때 다른 열이 변경되는 것을 의미한다. 테이블에서 키가 아닌 열 C의 값이 변경되었을 때, 이 값에 맞춰서 D가 변경되어야 한다면 이행적 종속 관계가 있는 것이다.