핵심 인사이트
- InnoDB와 MyISAM의 핵심 차이는 "트랜잭션 + 외래키 지원 여부" — InnoDB는 ACID 트랜잭션·외래키·행 단위 잠금을 지원하는 반면, MyISAM은 이 모두를 지원하지 않는 대신 단순한 구조로 읽기 전용 환경에서 빠른 성능을 보인다.
- InnoDB의 클러스터드 인덱스(Clustered Index)가 핵심 설계 원리 — InnoDB는 PK를 기준으로 데이터를 B+ 트리에 정렬 저장(클러스터드)하여 PK 기반 조회가 매우 빠르지만, MyISAM은 데이터 파일과 인덱스 파일을 분리해 더 유연하다.
- MySQL 5.5 이후 InnoDB가 기본 엔진으로 설정되었으나, 특수 목적(전문 검색·지리 데이터·로그 테이블)에는 MyISAM 또는 Aria·Memory·CSV·Blackhole 등 다른 엔진이 여전히 선택된다.
Ⅰ. 스토리지 엔진 개요
스토리지 엔진 (Storage Engine):
MySQL/MariaDB의 데이터 저장·검색 담당 컴포넌트
테이블 단위로 엔진 선택 가능
MySQL 아키텍처:
클라이언트
↓
SQL 파서 / 옵티마이저 (공통)
↓
스토리지 엔진 API (공통 인터페이스)
↓
InnoDB | MyISAM | Memory | CSV | ...
주요 스토리지 엔진:
InnoDB: 기본값, OLTP 범용
MyISAM: 레거시, 읽기 전용
Memory (Heap): 메모리 테이블, 임시
CSV: CSV 파일 연동
Blackhole: 데이터 버림 (로그 중계)
Archive: 압축 저장, 대용량 로그
Spider: 분산 DB 파티셔닝
TokuDB/RocksDB: 고압축 + 쓰기 최적화
테이블별 엔진 지정:
CREATE TABLE orders (
id INT PRIMARY KEY,
...
) ENGINE=InnoDB;
CREATE TABLE access_log (
...
) ENGINE=MyISAM;
📢 섹션 요약 비유: 스토리지 엔진 = 창고 관리 방식 — MySQL은 SQL 접수 데스크(파서/옵티마이저). 실제 창고 운영은 엔진마다 다름. InnoDB(정확한 ACID 창고), MyISAM(빠른 읽기 전용 창고)!
Ⅱ. InnoDB
InnoDB 핵심 특성:
1. ACID 트랜잭션:
BEGIN / COMMIT / ROLLBACK 지원
애플리케이션 오류 시 자동 롤백
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT; -- 둘 다 성공 또는 둘 다 실패
2. 외래 키 (Foreign Key):
참조 무결성 강제
CASCADE, SET NULL, RESTRICT 옵션
3. 행 단위 잠금 (Row-Level Locking):
UPDATE 시 해당 행만 잠금
동시성 높음 (MyISAM: 테이블 전체 잠금)
4. MVCC (Multi-Version Concurrency Control):
읽기-쓰기 동시성 향상
트랜잭션별 스냅샷 제공
→ 읽기가 쓰기를 블로킹하지 않음
5. 클러스터드 인덱스 (Clustered Index):
PK 순서로 데이터 물리 저장
구조:
PK B+ 트리: 리프 노드에 실제 데이터
세컨더리 인덱스: PK 값을 포인터로 사용
장점: PK 범위 검색 고속
단점: 무작위 PK(UUID) 삽입 시 페이지 분할
6. 버퍼 풀 (Buffer Pool):
디스크 페이지를 메모리에 캐시
innodb_buffer_pool_size: 메모리 70~80% 권장
LRU 알고리즘으로 관리
📢 섹션 요약 비유: InnoDB = 은행 창고 — 거래 장부(트랜잭션), 담보 연결(외래키), 개인 금고(행 잠금), 스냅샷 열람(MVCC). 안전하고 정확하지만 체계가 복잡!
Ⅲ. MyISAM
MyISAM 핵심 특성:
구조 (3파일):
tablename.frm: 테이블 정의
tablename.MYD: 실제 데이터 (MYData)
tablename.MYI: 인덱스 (MYIndex)
특성:
1. 트랜잭션 없음:
COMMIT/ROLLBACK 미지원
중간 오류 시 부분 적용 상태 유지
(크래시 후 수동 repair 필요)
2. 테이블 단위 잠금:
INSERT/UPDATE/DELETE 시 테이블 전체 잠금
→ 쓰기 중 읽기 불가 (반대도 가능)
→ 동시 쓰기 성능 낮음
3. 비클러스터드 인덱스:
인덱스 파일(MYI)과 데이터 파일(MYD) 분리
인덱스 → 데이터 파일 포인터
장점: 유연한 인덱스 관리
4. 전문 검색 (Full-Text Search):
FULLTEXT 인덱스 (MyISAM 전통 강점)
(InnoDB도 5.6부터 지원)
5. 빠른 COUNT(*):
테이블 전체 행 수를 메타데이터에 저장
SELECT COUNT(*): O(1) (InnoDB: O(N) 스캔)
6. 키 캐시 (Key Cache):
인덱스 블록만 캐시 (데이터는 OS 캐시)
key_buffer_size 설정
적합 사용 사례:
읽기 전용 테이블 (참고 데이터)
로그 테이블 (쓰기만, 트랜잭션 불필요)
전문 검색 (레거시 시스템)
📢 섹션 요약 비유: MyISAM = 도서관 창고 — 책(데이터)과 카드 목록(인덱스) 분리. 빠른 책 찾기(읽기). 하지만 책 수정 중엔 도서관 전체 입장 금지(테이블 잠금). 트랜잭션 없음!
Ⅳ. 상세 비교
InnoDB vs MyISAM 비교:
항목 InnoDB MyISAM
트랜잭션 지원 (ACID) 미지원
외래 키 지원 미지원
잠금 단위 행 (Row) 테이블
MVCC 지원 미지원
클러스터드 인덱스 O (PK 기준) X (별도 파일)
COUNT(*) O(N) 스캔 O(1) 메타
풀텍스트 검색 5.6부터 지원 전통 지원
크래시 복구 자동 (Redo Log) 수동 (myisamchk)
저장 파일 .ibd (단일) .frm+.MYD+.MYI
외부 키 지원 미지원
Buffer Pool 지원 Key Cache만
적합 워크로드 OLTP, 일반 읽기 전용, 레거시
MySQL 버전별 기본 엔진:
MySQL 5.1 이하: MyISAM
MySQL 5.5+: InnoDB (기본값 변경)
성능 비교:
읽기 전용(단순 SELECT): MyISAM ≥ InnoDB
OLTP(혼합 읽기/쓰기): InnoDB >>>
COUNT(*): MyISAM >> InnoDB (대규모)
동시 쓰기: InnoDB >> MyISAM (행 잠금)
언제 MyISAM?
레거시 코드 유지
읽기 전용 참조 테이블
MyISAM 전용 기능 (압축 테이블 등)
📢 섹션 요약 비유: InnoDB vs MyISAM = 스마트폰 vs 피처폰 — 스마트폰(InnoDB): 다기능, 안전, 동시 작업. 피처폰(MyISAM): 단순, 읽기 빠름, 구형 기기 호환. 새 프로젝트는 무조건 InnoDB!
Ⅴ. 실무 시나리오 — 마이그레이션 및 최적화
MyISAM → InnoDB 마이그레이션:
배경:
레거시 MySQL 5.1 시스템
MyISAM 테이블 150개
빈번한 "Table is marked as crashed" 오류
동시 접속 증가로 테이블 잠금 경합 심화
마이그레이션 절차:
1. 사전 조사:
SELECT TABLE_NAME, ENGINE, TABLE_ROWS
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'mydb' AND ENGINE = 'MyISAM';
2. 외래 키 제약 검증:
자식 테이블에 없는 부모 행 확인
(InnoDB 전환 시 외래키 오류 방지)
3. ALTER TABLE:
ALTER TABLE orders ENGINE=InnoDB;
대규모 테이블:
pt-online-schema-change (Percona Toolkit)
→ 무중단 변환 (쓰기 허용하며 복사)
4. innodb_buffer_pool 조정:
SET GLOBAL innodb_buffer_pool_size = 8G;
결과:
Table crash: 0건 (자동 Redo Log 복구)
동시 쓰기 성능: +340% (테이블 → 행 잠금)
응답시간 P99: 120ms → 35ms
InnoDB 추가 최적화:
innodb_buffer_pool_instances = 8 (≥8GB일 때)
innodb_log_file_size = 1G
innodb_flush_log_at_trx_commit = 2 (성능↑, 내구성↓)
innodb_io_capacity = 2000 (SSD 기준)
PK 설계:
UUID 대신 AUTO_INCREMENT → 순차 삽입
UUID 필요 시: UUID_TO_BIN() 또는 ULIDv7
📢 섹션 요약 비유: MyISAM→InnoDB 마이그레이션 = 구형 수동 금고→디지털 금고 교체 — 수동(MyISAM): 열쇠 분실 시 망가짐(크래시). 디지털(InnoDB): 자동 복구, 동시 사용 가능. 마이그레이션 후 성능 3배+!
📌 관련 개념 맵
스토리지 엔진 (Storage Engine)
+-- InnoDB
| +-- ACID 트랜잭션
| +-- 행 단위 잠금
| +-- MVCC
| +-- 클러스터드 인덱스
| +-- 자동 크래시 복구
+-- MyISAM
| +-- 트랜잭션 없음
| +-- 테이블 잠금
| +-- 빠른 COUNT(*)
| +-- 전문 검색 전통
+-- 선택 기준
+-- OLTP → InnoDB
+-- 읽기 전용 → MyISAM (레거시)
📈 관련 키워드 및 발전 흐름도
[MySQL 초기 (1995)]
MyISAM 기본 엔진
단순, 빠른 읽기
|
v
[InnoDB 통합 (2001)]
Innobase Oy 인수
ACID 트랜잭션 지원
|
v
[MySQL 5.5 (2010)]
InnoDB 기본 엔진으로 변경
MyISAM 퇴조
|
v
[MariaDB Aria (2010s)]
MyISAM 발전 버전
크래시 안전성 개선
|
v
[현재: InnoDB + RocksDB]
InnoDB: OLTP 표준
RocksDB: 대용량 쓰기 최적화
👶 어린이를 위한 3줄 비유 설명
- InnoDB = 은행 금고 — 거래(트랜잭션) 안전하게. 개인 칸막이(행 잠금). 사고 나도 자동 복구. 새 프로젝트 필수!
- MyISAM = 도서관 열람실 — 책(데이터)과 카드 목록(인덱스) 분리. 읽기 빠르고 COUNT 빠름. 수정 중엔 전체 입장 금지!
- 마이그레이션 = 구형→디지털 금고 교체 — ALTER TABLE ENGINE=InnoDB. 대규모는 pt-osc로 무중단. 성능 3배 향상!