1. 인덱스로 고속 액세스 실현하기
선형 검색은 시간 검색 알고리즘 중에 가장 비효율적이다.
따라서 인덱스 구조를 도입한다.
인덱스는 책의 색인과 같은 것으로 키 값과 그 키 값이 파일의 몇 번째 바이트에서 시작되는지를 관리하는 맵핑표이다.
인덱스는 본체의 데이터와 별도로 관리하므로 데이터 업데이트 비용은 증가한다.
B+Tree 인덱스를 사용하면 등호 검색은 물론 부등호나 전방 일치 검색 등의 범위 검색도 리프 블록을 스캔하는 것만으로 완결할 수 있다.
MySQL 같은 InnoDB는 시퀀셜 라이트를 사용해서 업데이트 된 정보를 메모리나 전용 파일에 일시적으로 기록한 뒤 한꺼번에 리프 블록을 갱신한다.
2. 데이블 설계와 릴레이션
예를 들어,
사원 정보 테이블에서 부서 이름과 부서 전화번호가 있으면 부서 이름이 같으면 보통 부서 전화번호가 같으므로 이를 다른 테이블로 분리한다.
맵핑 테이블이 아니라면 인덱스는 잘 변하지 않는 값으로 정해야 하기 때문에 새 테이블은 부서명이 아닌 ID를 도입하고 이를 기본키로 설정한다.
참조 무결성 제약이란 데이터베이스에서 자동으로 존재하는 외래키에 대해서만 추가 작업을 해주거나 연관 데이터가 있으면 삭제가 안되도록 방지하는 것이다.
겸직이 생겼다.
이 때 사원 테이블에 열을 추가하는 방식은 너무 비효율적이다.
이 때 사용하는 것이 1:N의 매핑 테이블을 만드는 것이다.
이 때는 레코드 수가 많아지는 게 정상이며 테이블을 분할하여 복수의 시스템에서 접근하도록 할 수 있다.
테이블에 중복, 반복, 복합값이 있는 테이블을 제1정규형이 아닌 테이블이라 한다. 카피앤페이스트를 한 느낌의 테이블..
기본 키가 여러 열에 의해 형성된 경우는 제 2정규형이 아닌 테이블이다.
기본 키에 의해 하나로 결정되지 않는 경우는 제3정규형이 아닌 테이블이다.
그 이후 정규형에 대해서는 매핑 테이블을 만드는 등으로 해결한다.
3. SQL 문의 특징과 이를 잘 다루는 법
매핑 테이블에서는 기본 키가 매핑하는 두 컬럼이 된다.
검색 조건으로 사용할 가능성이 높은 컬럼에 인덱스를 부여한다.
조인을 사용하는 편이 좋다. 왜냐하면 원격 액세스를 줄일 수 있기 때문이다.
쿼리 앞에 EXPLAIN을 사용하면 실행 방식이 적절한지 알 수 있는데 ROWS 값이 적을 수록 좋다.
ROWS는 실제로 데이터베이스 레코드에 액세스 되는 횟수이다. (단, 추정치)
저장 프로시저는 특정하게 한정된 로직에서만 사용하는 것이 좋다.
4. 가용성과 데이터 복제
데이터 손실을 방지하기 위해선 디스크 이중화를 해야 한다.
하나의 서버에 여러 개의 HDD를 탑재하고 동일한 데이터를 두 개 이상의 HDD에 분산시키는 기술을 RAID라고 한다.
용량 여유가 있으면 RAID1을, 없으면 RAID5를 사용한다.
RAID1은 두 대의 HDD에 동일 데이터를 작성하는 방식이다. 이용 가능한 용량은 디스크 수의 절반이다.
RAID5는 오류 정정 부호인 패리티 데이터와 함께 분산하여 기록하는 방식으로 이용 가능 용량은 N-1개이다.
서버는 두 대 이상 필요하다.
MySQL의 표준 복제 방식은 단방향/비동기 방식이다.
마스터이서 실행한 갱신계의 SQL문이 바이너리 로그라는 전용 로그 파일로 기록된다.
이 로그 파일이 슬레이브로 전송되어 저장되면, 슬레이브는 이를 순차적으로 실행한다.
이후 생략....
5. 트랜잭션과 무결성, 무정지성
트랜잭션은 데이터 무결성과 데이터 무정지성을 요구하는 애플리케이션에서 필수적이다.
트랜잭션이란 여러 개의 SQL실행을 하나의 단위로 묶어서 전부 실행했으면 커밋을, 중간에 하나라도 실패하면 롤백을 하는 구조이다.
이를 트랜잭션의 원자성이라고도 한다.
웹 어플리케이션에서는 하나의 http 요청에 대해 하나의 트랜잭션을 수행해야 한다.
트랜잭션 기능의 대표적인 두 번째 이점은 무정지성의 향상이다.
REDO로그를 사용하여 무정지성을 보장한다.
MyISAM은 테이블 단위 잠금을 적용하고 InnoDB는 레코드 단위로 적용한다.
잠금은 트랜잭션의 종료시까지 유지한다.
이하 생략...