2. 트랜잭션이란?
• DBMS에서 데이터를 다루는 논리적인 단위
• 데이터 장애 발생 시 복구하는 작업 단위
• 여러 작업이 동시에 같은 데이터를 다룰 때 이 작업을 서로 분리
• All or Nothing!! - 전부 수행이 되거나 그게 아니면 수행되면 안 됨!
3. 트랜잭션 특성
ACID
• A (Atomicity) - 원자성, 작업은 전부 수행되거나 수행되지 않는다.
1. 잔액 20,000
3. 잔액 10,000
2. 송금 10,000 잔액 30,000
4. 잔액 40,000
4. 트랜잭션 특성
ACID
• A (Atomicity) - 원자성, 작업은 전부 수행되거나 수행되지 않는다.
1. 잔액 20,000
3. 잔액 10,000
2. 송금 10,000 잔액 30,000
4. 잔액 40,000
하나라도 실패하면 트랜잭션이 반영되면 안됨! -> ROLLBACK
모두 성공하면 DB에 반영 -> COMMIT
5. 트랜잭션 특성
ACID
• C (Consitstency) - 일관성, DB 내의 계층 관계, 컬럼 속성은 일관되게 유지
1. 잔액 20,000
3. 잔액 10,000
잔액 30,000
4. 잔액 40,000
잔액의 속성이 INT에서 FLOAT로 바뀌면 TRIGGER를 통해 모든 DB에 변경
2. 송금 10,000
6. 트랜잭션 특성
ACID
• I (Isolation) - 독립성, 다른 트랜잭션이 끼어들어 변경중인 값 훼손 방지
송금 10,000 송금 10,000
잔액의 속성이 INT에서 FLOAT로 바뀌면 TRIGGER를 통해 모든 DB에 변경
???
🍶
7. 트랜잭션 특성
ACID
• D (Durability) - 지속성, 수행이 성공적으로 완료시 데이터 영구 반영
1. 잔액 20,000
3. 잔액 10,000
잔액 30,000
4. 잔액 40,000
수행된 트랜잭션은 로그로 남겨져 장애 발생시 항시 대기할 수 있게 한다.
2. 송금 10,000
8. 트랜잭션 동작 과정
실행 쿼리
BEGIN TRAN
UPDATE accounts SET balance = balance - 10000 WHERE user=“정민주”;
UPDATE accounts SET balance = balance + 10000 WHERE user=“안석환”;
COMMIT TRAN
9. 트랜잭션 동작 과정
UPDATE accounts SET … 쿼리 요청
쿼리 처리기
데이터 캐시 로그 캐시
데이터
파일
로그
파일
10. 트랜잭션 동작 과정
UPDATE accounts SET … 쿼리 요청
쿼리 처리기
데이터 캐시 로그 캐시
데이터
파일
로그
파일
UPDATE accounts SET balance = balance - 10000 WHERE user=“정민주”;
데이터 캐시 상태
user balance
정민주 20,000
ReDo 로그
변경 후의 값을 기록
UnDo 로그
변경 전의 값을 기록
트랜잭션_1 START
트랜잭션_1 UPDATE accounts.balance 정민주 10000
로그_1 accounts.balance 정민주 20000
user balance
정민주 10,000
11. 트랜잭션 동작 과정
UPDATE accounts SET … 쿼리 요청
쿼리 처리기
데이터 캐시 로그 캐시
데이터
파일
로그
파일
UPDATE accounts SET balance = balance + 10000 WHERE user=“안석환”;
데이터 캐시 상태
user balance
정민주 10,000
안석환 30,000
ReDo 로그
변경 후의 값을 기록
UnDo 로그
변경 전의 값을 기록
트랜잭션_1 START
트랜잭션_1 UPDATE accounts.balance 정민주 10000
트랜잭션_1 UPDATE accounts.balance 안석환 40000
트랜잭션_1 COMMIT
로그_1 accounts.balance 정민주 20000
로그_2 accounts.balance 안석환 30000
user balance
정민주 10000
안석환 40000
12. 트랜잭션 동작 과정
ROLLBACK 실행
쿼리 처리기
데이터 캐시 로그 캐시
데이터
파일
로그
파일
UnDo 로그를 역순으로 복구!
데이터 캐시 상태
user balance
정민주 10,000
안석환 30,000
ReDo 로그
변경 후의 값을 기록
UnDo 로그
변경 전의 값을 기록
트랜잭션_1 START
트랜잭션_1 UPDATE accounts.balance 정민주 10000
트랜잭션_1 UPDATE accounts.balance 안석환 40000
트랜잭션_1 COMMIT
로그_1 accounts.balance 정민주 20000
로그_2 accounts.balance 안석환 30000
user balance
정민주 10000
안석환 40000
13. 동시 요청이 들어온 경우
한명에겐 송금 한명에겐 입금
석환 Transaction 민주 Transaction
START
START
석환에게 10,000원 송금
석주에게 10,000원 입금
석주 잔고 20,000원
석주 잔고 30,000원
????
14. 동시 요청이 들어온 경우
락 걸기
석환 Transaction 민주 Transaction
START
START
석환에게 10,000원 송금
석주에게 10,000원 입금
석주 잔고 20,000원
석주 잔고 20,000원 아쉽지만.. GOOD!
트랜잭션이 시작되면 이용하고 있는 (ROW, TABLE)은 트랜잭션이 끝날 때 까지 점유!
16. 인덱스란
• 추가적인 쓰기 작업과 저장 공간을 활용하여 데이터베이스 테이블의 검색 속도
를 향상시키는 자료구조
SELECT
UPDATE
DELETE
성능 향상 기대
17. 인덱스의 관리
장점과 단점
• 인덱스를 항상 최신 정렬로 유지해야 원하는 값을 빠르게 탐색할 수 있다.
• 인덱스가 적용된 컬럼에 INSERT, UPDATE, DELETE가 수행되면 아래와 같
은 연산 필요
✓ INSERT: 새로운 데이터에 대한 인덱스 추가
✓ DELETE: 삭제하는 데이터의 인덱스를 사용하지 않음 처리
✓ UPDATE: 기존의 인덱스를 사용하지 않음 처리 후, 갱신된 데이터를 인덱스에 추가
주의!!
위 연산이 자주 수행 되는 컬럼에 인덱스를 걸면 오히려 성능 저하를 초래할 수 있기 에 주의!
18. 인덱스 설정
카디널리티가 가장 높은 것
인덱스로 최대한 효율을 뽑아내려면, 해당 인덱스로 많은 부분을 걸러내야함
• 카디널리티(Cardinality)란 해당 컬럼의 중복된 수치
• 성별, 학년 등은 카디널리티가 낮음
• 주민번호, 계좌번호는 카디널리티가 높음
19. 인덱스 설정
카디널리티가 가장 높은 것
CREATE TABLE `salaries` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
`is_bonus` tinyint(1) unsigned zerofill DEFAULT NULL,
`group_no` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
21. 인덱스 설정
인덱스 생성
CREATE INDEX IDX_SALARIES_INCREASE ON salaries (is_bonus, from_date, group_no);
CREATE INDEX IDX_SALARIES_DECREASE ON salaries (group_no, from_date, is_bonus);
22. 인덱스 설정
각 인덱스로 조회
select SQL_NO_CACHE *
from salaries
use index (IDX_SALARIES_INCREASE)
where from_date = '1998-03-30'
and group_no in ('abcdefghijklmn10494','abcdefghijklmn3968', 'abcdefghijklmn11322',
'abcdefghijklmn13902', 'abcdefghijklmn100', 'abcdefghijklmn10406')
and is_bonus = true;
select SQL_NO_CACHE *
from salaries
use index (IDX_SALARIES_DECREASE)
where from_date = '1998-03-30'
and group_no in ('abcdefghijklmn10494','abcdefghijklmn3968', 'abcdefghijklmn11322',
'abcdefghijklmn13902', 'abcdefghijklmn100', 'abcdefghijklmn10406')
and is_bonus = true;