데이터베이스 설계할 때 문자열 데이터를 저장하는 컬럼 타입을 정하는 건 생각보다 복잡하다. 특히 VARCHAR와 TEXT 중에서 고민하는 경우가 많은데, 각각의 특성을 제대로 알고 써야 나중에 성능 문제로 고생하지 않는다.
VARCHAR 타입이란?
VARCHAR는 Variable Character의 줄임말로, 가변 길이 문자열을 저장하는 타입이다. MySQL에서는 VARCHAR(길이)처럼 최대 길이를 지정해야 한다.
VARCHAR(50)으로 설정하면 최대 50자까지 저장할 수 있고, 실제 데이터가 10자면 10자만큼의 공간만 사용한다. 즉, 지정한 최대 길이보다 적은 데이터를 저장해도 남는 공간을 낭비하지 않는다.
MySQL 5.0.3 이후부터는 VARCHAR의 최대 길이가 65,535바이트까지 가능하다. UTF-8 인코딩에서는 한 글자당 최대 3바이트를 사용하므로, 실제로는 21,845자 정도까지 저장할 수 있다.
TEXT 타입이란?
TEXT는 긴 문자열 데이터를 저장하기 위한 타입이다. VARCHAR와 달리 길이를 지정하지 않으며, 훨씬 많은 양의 텍스트를 저장할 수 있다.
TEXT는 사실 여러 종류가 있다. TINYTEXT(255바이트), TEXT(65,535바이트), MEDIUMTEXT(16MB), LONGTEXT(4GB)로 나뉜다. 보통 TEXT라고 하면 일반적인 TEXT 타입을 의미한다.
TEXT 타입의 데이터는 별도의 공간에 저장되고, 실제 테이블에는 포인터만 저장된다. 그래서 TEXT 컬럼이 많은 테이블은 조회 성능이 떨어질 수 있다.
공통점
두 타입 모두 가변 길이 문자열을 저장한다는 점에서 동일하다. 실제 저장된 데이터의 길이만큼만 공간을 사용하므로, 짧은 문자열을 저장해도 공간 낭비가 발생하지 않는다.
또한 둘 다 인덱스 생성이 가능하다. 다만 TEXT의 경우 전체 컬럼에 인덱스를 걸 수 없고, 앞의 일정 길이만 인덱스로 설정할 수 있다.
문자 집합과 정렬 규칙도 동일하게 적용된다. utf8mb4나 latin1 등의 문자 집합을 설정할 수 있고, 대소문자 구분 여부도 설정 가능하다.
차이점
가장 큰 차이는 저장 방식이다. VARCHAR는 행과 함께 저장되지만, TEXT는 별도 공간에 저장된다. 이로 인해 성능 차이가 발생한다.
VARCHAR는 최대 길이 제한이 있지만, TEXT는 사실상 무제한이다. VARCHAR(65535)까지 가능하지만, TEXT는 그보다 훨씬 큰 데이터를 저장할 수 있다.
DEFAULT 값 설정에서도 차이가 있다. VARCHAR는 기본값을 설정할 수 있지만, TEXT는 불가능하다. NULL만 기본값으로 설정할 수 있다.
인덱스 생성 방식도 다르다. VARCHAR는 전체 컬럼에 인덱스를 걸 수 있지만, TEXT는 앞의 몇 글자만 인덱스로 설정해야 한다.
메모리 사용량에서도 차이가 난다. VARCHAR는 최대 길이에 따라 임시 테이블에서의 메모리 사용량이 결정되지만, TEXT는 실제 데이터 크기만큼만 사용한다.
성능 비교
조회 성능에서는 VARCHAR가 압도적으로 유리하다. VARCHAR 데이터는 행과 함께 저장되어 한 번의 디스크 읽기로 가져올 수 있지만, TEXT는 추가적인 디스크 접근이 필요하다.
정렬이나 그룹핑 작업에서도 VARCHAR가 빠르다. TEXT는 임시 테이블을 디스크에 생성해야 할 가능성이 높아서 성능이 떨어진다.
하지만 매우 긴 문자열을 저장할 때는 TEXT가 더 효율적일 수 있다. VARCHAR로 긴 문자열을 저장하면 행 크기가 커져서 전체적인 성능이 저하될 수 있다.
VARCHAR
사용자 이름, 이메일, 전화번호처럼 길이가 어느 정도 예측 가능한 데이터에는 VARCHAR를 사용하자. 이런 데이터는 보통 255자를 넘지 않으므로 VARCHAR(255)면 충분하다.
상품명, 카테고리명, 태그 같은 데이터도 VARCHAR가 적합하다. 검색이나 정렬 작업이 빈번하게 발생하는 컬럼이라면 더욱 VARCHAR를 선택해야 한다.
URL이나 파일 경로도 VARCHAR로 저장하는 게 좋다. 보통 2000자 이내로 제한되는 경우가 많아서 VARCHAR(2000) 정도면 적당하다.
JSON 데이터를 저장할 때도 크기가 작다면 VARCHAR를 고려해볼 수 있다. MySQL 5.7부터는 JSON 타입이 있지만, 단순한 JSON이라면 VARCHAR도 나쁘지 않다.
TEXT
게시글 내용, 댓글, 상품 설명처럼 길이를 예측하기 어려운 텍스트 데이터, 사용자가 입력하는 긴 글이라면 TEXT가 안전하다.
로그 데이터나 에러 메시지 같은 시스템 데이터도 TEXT가 적합하다. 이런 데이터는 길이를 예측하기 어렵고, 보통 조회보다는 저장이 우선이다. HTML 콘텐츠나 마크다운 텍스트처럼 마크업이 포함된 데이터도 TEXT로 저장하는 게 좋다. 마크업 태그 때문에 실제 내용보다 저장 공간이 많이 필요할 수 있다. 설정 파일이나 큰 JSON 데이터도 TEXT 타입이 적합하다. 이런 데이터는 크기가 가변적이고, 전체 내용을 한 번에 가져오는 경우가 많다.
주의사항
VARCHAR의 길이를 너무 크게 설정하면 메모리 사용량이 늘어난다. 정렬이나 그룹핑 작업에서 임시 테이블이 메모리에 올라갈 때, VARCHAR의 최대 길이만큼 메모리를 할당하기 때문이다.
TEXT 컬럼이 많은 테이블은 조회 성능이 떨어질 수 있다. 꼭 필요한 경우가 아니라면 TEXT 컬럼 수를 제한하는 게 좋다.
인덱스를 걸 때도 주의해야 한다. VARCHAR는 전체 컬럼에 인덱스를 걸 수 있지만, 길이가 길면 인덱스 크기가 커져서 성능에 영향을 줄 수 있다. TEXT는 앞의 몇 글자만 인덱스로 설정해야 하므로, 검색 패턴을 고려해서 설정해야 한다.
문자 집합도 중요하다. UTF-8을 사용한다면 한 글자당 최대 3바이트, UTF8MB4를 사용한다면 4바이트까지 사용할 수 있다. 이모지를 저장해야 한다면 UTF8MB4를 사용해야 한다.
VARCHAR와 TEXT 중 어떤 것을 선택할지는 데이터의 특성과 사용 패턴을 고려해서 결정해야 한다. 길이가 예측 가능하고 검색이나 정렬이 빈번한 데이터라면 VARCHAR를, 길이를 예측하기 어렵고 저장이 우선인 데이터라면 TEXT를 선택하자.
성능이 중요한 시스템이라면 가능한 한 VARCHAR를 사용하고, TEXT 컬럼은 별도 테이블로 분리하는 것도 고려해볼 만하다. 데이터베이스 설계는 한 번 정하면 바꾸기 어려우므로, 충분히 고민해서 결정하는 게 좋다.
'DB' 카테고리의 다른 글
Querydsl에서 columnDefinition으로 인한 cast 에러 해결 경험 (0) | 2025.09.20 |
---|