DB 컬럼을 255로 잡는 진짜 이유, 관습이 아닙니다

⚡️ 핵심 요약

1. 1바이트 경계의 삼형제

DB 스키마에 자주 보이는 255와, 누군가의 스키마에 보이는 85·63은 모두 InnoDB 길이 프리픽스를 1바이트(0~255 표현)로 유지하는 한계값이다. 문자셋의 '글자당 최대 바이트'로 255를 나눈 결과라 숫자가 달라질 뿐, 뿌리는 같다.

2. 256바이트의 비용

utf8mb4에서 VARCHAR 64부터는 64×4=256바이트라 프리픽스가 2바이트로 늘어난다. 행 수만큼 저장이 늘 뿐 아니라, 인덱스 키에도 프리픽스가 포함돼 B-tree 페이지당 키 수가 줄고 페이지 스플릿이 잦아진다.

3. 관습 아닌 도메인

VARCHAR 255는 latin1 시절 1바이트 프리픽스의 최댓값이었을 뿐이다. utf8mb4가 기본인 시대의 컬럼 길이는 관습이 아니라 실제 데이터 도메인이 결정해야 한다.

목차

1. 길이 프리픽스와 1바이트 경계

MySQL InnoDB는 VARCHAR 데이터 앞에 실제 길이를 적는 **길이 프리픽스(length prefix)**를 붙인다. 이 프리픽스가 1바이트면 0~255까지 표현할 수 있고, 256 이상을 표현해야 하는 순간 2바이트로 확장된다. 그래서 255는 '1바이트 프리픽스로 표현 가능한 최대 길이'라는 물리적 경계에서 나온 숫자다. 스키마에서 보이는 255·85·63 같은 어정쩡한 값들이 모두 이 1바이트 한계의 변주다.

⚠️ 프리픽스가 1바이트면 0~255까지 표현 가능 — 딱 한 바이트만 넘어가도(256번째) 프리픽스가 2바이트로 확장되는 경계가 핵심이다.
▶️ 관련 스크립트

2. VARCHAR(n)의 n은 문자 수다

핵심 함정은 VARCHAR(n)n이 바이트 수가 아니라 문자 수라는 점이다. 그래서 실제 바이트는 '문자셋의 글자당 최대 바이트'에 좌우되고, 1바이트 프리픽스를 유지하는 정답도 문자셋에 따라 달라진다.

문자셋 글자당 최대 byte 1바이트 프리픽스 한계
latin1 1 255
utf8mb3 (보충) 3 85
utf8mb4 4 63

utf8mb4 기준 VARCHAR 64는 64×4=256바이트라 경계를 넘어 프리픽스가 2바이트가 되고, 63까지가 1바이트로 안전하다.

⚠️ VARCHAR(n)n은 바이트가 아니라 문자 수다. 따라서 같은 n이라도 문자셋의 '글자당 최대 바이트'에 따라 실제 차지하는 바이트와 프리픽스 크기가 달라진다.
📝 적용 예시

1바이트 프리픽스를 유지하는 조건: (글자당 최대 byte) × (문자 수) ≤ 255

  • latin1(1 byte/글자): 255 ÷ 1 = 255 → VARCHAR 255
  • (보충) utf8mb3(3 byte/글자): 255 ÷ 3 = 85 → VARCHAR 85
  • utf8mb4(4 byte/글자): 64×4 = 256 > 255라 64는 탈락, 63×4 = 252 ≤ 255 → VARCHAR 63 → 같은 '1바이트 한계'라도 문자셋이 바뀌면 255·85·63으로 답이 갈린다. ※ 85에 대응하는 문자셋이 utf8mb3라는 점은 영상에서 명시하지 않아 (보충)으로 채움.
▶️ 관련 스크립트

3. 256바이트를 넘으면 드는 비용

프리픽스가 2바이트로 늘면 두 종류의 비용이 발생한다. 첫째는 저장 비용: 행마다 1바이트가 더 붙어 1억 행이면 단순 계산으로 100MB가 그냥 추가된다. 둘째는 인덱스 비용: 인덱스 키에도 프리픽스가 포함되므로 B-tree 페이지 하나에 들어가는 키 수가 줄고, 그만큼 페이지 스플릿(page split)이 더 자주 일어난다. 즉 단순 디스크 증가를 넘어 인덱스 구조의 효율까지 떨어뜨리는 2차 효과가 있다.

⚠️ 화자는 두 비용을 구분한다 — 프리픽스 2바이트화는 행당 1바이트라는 단순 저장 증가뿐 아니라, 인덱스 B-tree 페이지당 키 수 감소 → 페이지 스플릿 증가라는 2차 비용을 부른다.
📝 적용 예시

행 1억 개 × 프리픽스 +1바이트 = 약 100MB 추가 (단순 계산). 여기에 인덱스 키에도 프리픽스가 포함돼 페이지당 키 수가 줄어드는 비용이 더해진다.

▶️ 관련 스크립트

4. MySQL 한정: PostgreSQL은 다르다

이 255바이트 경계 이야기는 모든 DB에 통하는 보편 법칙이 아니라 MySQL InnoDB의 길이 프리픽스 구조에서 나온 것이다. PostgreSQL은 가변 길이를 다루는 varlena 구조를 써서 MySQL 같은 255바이트 경계 자체가 없다. 그래서 PostgreSQL에서는 255든 256이든 저장 비용 차이가 없다. 같은 원리(가변 길이 저장)라도 엔진 구현에 따라 비용 경계가 달라진다는 점을 인지해야 무지성 최적화를 피할 수 있다.

⚠️ 이 255바이트 경계는 MySQL InnoDB에 한정된 이야기다. PostgreSQL의 varlena 구조엔 그런 경계가 없어 255든 256이든 저장 비용 차이가 없다 — 최적화가 엔진 종속적임을 구분해야 한다.
▶️ 관련 스크립트

5. 결론: 길이는 데이터가 정한다

화자의 마무리 정리다. utf8mb4가 기본인 시대에 무지성으로 VARCHAR 255를 박는 것은 사실상 '내 컬럼은 길이 프리픽스가 2바이트입니다'라고 선언하는 셈이다. 진짜 1바이트 프리픽스를 노렸다면 VARCHAR 63이 정확한 답이다. 그러나 80자짜리 데이터를 63으로 잘라 넣는 것은 본말 전도다. 결국 VARCHAR 255는 latin1 시절의 최댓값이었을 뿐, utf8mb4 시대의 정답은 관습이 아니라 데이터 도메인이 결정한다.

⚠️ VARCHAR 63은 '1바이트 프리픽스를 노릴 때의 상한 정답'일 뿐이다. 데이터가 더 길면 63으로 자르는 건 본말 전도 — 프리픽스 최적화가 실제 도메인 요구를 이기게 해서는 안 된다.
▶️ 관련 스크립트

개발 가이드라인