HOWTO · MySQL

MySQL에서 VARCHAR와 TEXT의 차이점

이 튜토리얼은 MySQL 데이터베이스에서 VARCHAR와 TEXT의 차이점을 보여줍니다.

이 페이지의 내용

값에 유용한 최대 길이를 선언할 수 있고 일반적인 열 조회에 자주 사용된다면 VARCHAR를 선택하세요. 내용이 더 길거나 실제 크기를 예측하기 어렵다면 TEXT가 적합할 수 있습니다. 적절한 유형은 예상 데이터, 애플리케이션에서 적용할 제한, 해당 열을 쿼리에서 사용하는 방식에 따라 달라집니다. 어느 한 유형이 항상 더 빠르거나 더 나은 것은 아닙니다.

VARCHAR와 TEXT에 저장되는 데이터

MySQL에서 VARCHAR와 TEXT는 모두 문자 데이터를 저장하지만, 스키마에서 기대하는 값의 형태는 다릅니다. VARCHAR(n)은 열의 길이를 선언하므로 표시 이름이나 짧은 레이블처럼 최대 길이를 아는 값에 적합합니다. 짧은 선언 길이로 특성을 나타내기 어려운 사용자 댓글이나 문서 본문처럼 더 긴 텍스트에는 TEXT 열을 사용할 수 있습니다.

이러한 유형 이름만으로 애플리케이션의 유효성 검사 정책이 정해지지는 않습니다. 삽입 전에 허용할 값을 정하고 그 정책이 열 유형에 반영되도록 하세요. 예를 들어 전화번호는 짧더라도 반드시 숫자로 저장해야 하는 것은 아닙니다. 텍스트로 취급한다면 애플리케이션에서 정한 적절한 길이 제한을 둔 VARCHAR로 표현할 수 있습니다.

길이 제한과 저장 공간

VARCHAR(n)의 숫자는 선언된 문자 길이 제한이며, 실제 저장 값은 그보다 짧을 수 있습니다. 실제 저장 공간과 허용되는 크기는 스키마와 MySQL에 적용되는 제한에 따라 달라집니다. 문자 집합과 행 정의도 영향을 줍니다. 이러한 세부 사항은 MySQL 버전, 문자 집합, 테이블 정의에 따라 달라지므로, 모든 경우에 적용되는 단일 바이트 비용이나 최대 크기 계산에 의존하지 말고 실제 배포 환경의 문서를 확인하세요.

한 유형이 언제나 공간을 덜 차지한다는 주장만으로 유형을 선택하지 마세요. 예상 값의 길이, 선언된 제한, 테이블의 전체 설계를 함께 고려해야 합니다. TEXT는 긴 콘텐츠를 위한 유형이고, VARCHAR는 제한된 값이라는 점을 스키마에 직접 나타냅니다.

인덱스와 쿼리 고려 사항

인덱스 필요성도 설계에 포함해야 합니다. 애플리케이션이 어떤 열을 필터링하거나 정렬하거나 조인하는지 살펴보고, 배포할 MySQL 버전과 스키마에 맞는 인덱스 정의를 확인하세요. TEXT에는 인덱스를 만들 수 없다고 단정할 수는 없지만, 인덱싱 옵션과 제약은 세부 조건에 따라 달라질 수 있습니다. 어느 유형이든 특정 쿼리 속도를 보장한다고 가정하지 마세요. 성능이 중요하다면 실제 환경을 대표하는 쿼리로 측정하세요.

데이터에 맞는 유형 선택하기

먼저 값의 의미와 예상 범위를 생각해 보세요. 유용한 길이 제한을 정할 수 있다면 길이가 제한된 레이블, 이메일 주소, 표시 이름에는 VARCHAR가 적합한 경우가 많습니다. 더 긴 사용자 댓글이나 문서 콘텐츠에는 TEXT를 사용할 수 있습니다. 이는 예시일 뿐 정해진 규칙은 아닙니다. 애플리케이션마다 제한과 쿼리 패턴이 다를 수 있습니다.

그다음 열이 어떻게 사용되는지 고려하세요. 자주 검색하거나 정렬하는 열이라면 그런 사용 방식을 스키마와 인덱스 검토에 반영하세요. 제품에서 값의 길이 제한을 명확히 정했다면 삽입 전에 애플리케이션에서 검증하고, 열 설계에도 그 제한을 반영하세요. 이렇게 하면 길이를 초과한 입력을 서버가 어떻게 처리할지 명시되지 않은 동작에 의존하지 않고 의도한 동작을 분명히 할 수 있습니다.

스키마 예시와 길이 처리

간단한 프로필 테이블에서는 길이가 제한된 필드에 VARCHAR를, 선택 입력인 자기소개에 TEXT를 사용할 수 있습니다. 인라인 스키마 CREATE TABLE profile (display_name VARCHAR(80), phone VARCHAR(32), biography TEXT);는 각 유형의 용도를 보여 줍니다. 요구사항에 맞는 제한을 선택하고 배포 환경에 적합한 인덱스인지 확인하세요.

애플리케이션에서 필드 길이를 관리한다면 데이터베이스에 전달하기 전에 값을 검증하세요. 이 Python 예시는 설정된 문자 수 정책에 따라 각 값이 제한 이내인지 결과를 출력합니다. 애플리케이션은 False 결과를 바탕으로 값을 거부하도록 구현할 수 있지만, 예시 자체는 결과만 출력하며 입력을 직접 거부하지 않습니다. 또한 MySQL의 삽입 동작을 보여 주거나 서버 측 제약 조건을 대신하지 않습니다. 첫 번째 값은 12자로 80자 제한 이내이고, 두 번째 값은 81자로 제한을 넘습니다. 출력의 True와 False는 바이트가 보존된 코드에서 영어 표기 그대로 표시됩니다.

이 예시를 실행하세요:

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

values = ["Ada Lovelace", "x" * 81]
max_characters = 80
for value in values:
    print(len(value) <= max_characters)
True
False