메인 콘텐츠로 건너뛰기

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples on this page work on VillageSQL. Install Now →
컬럼에 지정하는 데이터 유형은 저장 크기, 인덱스 효율성, 쿼리 동작에 영향을 줍니다. 필요 이상으로 큰 유형을 선택하면 모든 행과 그 컬럼을 포함하는 모든 인덱스에서 공간이 낭비됩니다. 너무 작은 유형을 선택하면 잘림 오류나 조용한 데이터 손실이 발생합니다.

정수 유형

MySQL에는 다섯 가지 정수 유형이 있습니다. 예상 범위에 맞는 가장 작은 것을 고르세요. INT UNSIGNED는 양수 범위를 약 4.3B로 두 배 늘립니다. 항상 양수인 기본 키와 외래 키에는 UNSIGNED를 사용하세요 — 공짜로 얻는 추가 범위입니다. BIGINT는 INT의 두 배 저장 공간을 차지합니다. 모든 ID에 기본으로 사용하지 마세요 — INT는 20억 행 이상을 처리하며, 이는 대부분의 테이블이 도달하지 못하는 규모입니다.

문자열 유형

VARCHAR 대 CHAR

VARCHAR(n)은 문자열이 담은 만큼의 바이트만 저장합니다(길이를 위한 1-2바이트 추가). CHAR(n)은 항상 정확히 n바이트를 저장하며, 더 짧은 문자열은 공백으로 채웁니다. CHAR는 길이 접두사를 파싱할 필요가 없으므로 고정 길이 값에서 약간 더 빠를 수 있습니다. 가변적인 것에는 모두 VARCHAR를 사용하세요.

VARCHAR 대 TEXT

행 크기 제한까지의 VARCHAR 값은 클러스터형 인덱스 페이지에 인라인으로 저장됩니다. TEXT(와 BLOB) 값은 충분히 커지면 오버플로 페이지에 저장됩니다. 이는 다음을 의미합니다:
  • VARCHAR 컬럼은 인덱스에 직접 포함됩니다
  • TEXT 컬럼은 완전히 인덱싱할 수 없습니다 — 접두사 길이가 필요합니다: INDEX (description(100))
수백 자 미만임을 아는 문자열에는 VARCHAR를 사용하세요. 인라인 저장이 적합하지 않은 긴 콘텐츠(기사, 댓글, HTML)에는 TEXT를 사용하세요.

날짜와 시간 유형

DATETIME과 TIMESTAMP의 핵심 차이:
  • TIMESTAMP는 값을 UTC로 저장하고 조회 시 세션의 time_zone으로 변환합니다. 애플리케이션이 여러 시간대에서 동작한다면 TIMESTAMP가 변환을 자동으로 처리합니다.
  • DATETIME은 시간대 변환 없이 리터럴 값을 저장합니다 — 넣은 그대로 나옵니다.
  • TIMESTAMP에는 2038년 제한(Unix 타임스탬프 오버플로)이 있습니다. 2038년 이후의 날짜에는 DATETIME을 사용하세요.
시간대 처리에 대한 전체 논의는 MySQL의 타임스탬프와 시간대를 참조하세요.

십진수와 부동 소수점

FLOAT와 DOUBLE은 십진 소수를 정확히 표현할 수 없는 이진 부동 소수점을 사용합니다. 부동 소수점에서 0.1 + 0.2는 0.30000000000000004입니다. 금액에는 항상 DECIMAL을 사용하세요.

JSON

JSON 컬럼은 검증된 JSON을 저장하고 경로 기반 쿼리 연산자를 제공합니다.
JSON 컬럼은 직접 인덱싱할 수 없습니다. 자주 쿼리하는 JSON 필드를 인덱싱하려면 생성 컬럼을 사용하세요:

자주 묻는 질문

기본 키에 INT와 BIGINT 중 무엇을 사용해야 하나요?

INT는 부호 있는 정수로 21억 행, 부호 없는 정수로 43억 행을 처리합니다. 대부분의 테이블에서는 INT UNSIGNED로 충분합니다. 실제로 그 한계를 넘을 것으로 예상하거나 4바이트에 들어가지 않는 UUID 스타일 ID를 사용한다면 BIGINT를 사용하세요.

고민하지 않으려고 모든 곳에 VARCHAR(255)를 사용해도 되나요?

가능하지만, 더 긴 VARCHAR 선언은 더 넓은 인덱스 키를 만들어 인덱스 메모리 사용량을 늘리고 페이지당 들어가는 인덱스 항목 수를 줄입니다. 현실적인 최대값을 선언하세요 — 이름 필드에는 VARCHAR(255)가 아니라 VARCHAR(100). 실제 저장 비용은 데이터 길이와 같지만, 인덱스 키 길이는 선언된 크기로 고정됩니다.

NULL과 기본값의 실질적인 차이는 무엇인가요?

NULL은 “알 수 없음”을 의미합니다 — 표현식을 통해 전파되고 집계 함수에서 제외됩니다. 0이나 '' 같은 기본값은 “명시적으로 비어 있음으로 설정됨”을 의미합니다. 실제로 없는 데이터에는 NULL을 고르고, 컬럼이 즉시 합리적인 값을 갖기를 원하는 “아직 설정되지 않음” 시나리오에는 기본값을 고르세요. 둘을 섞으면 쿼리에 불일치가 생깁니다.

문제 해결

참고