VARCHAR VS TEXT
공통점
- 문자열 속성 값 저장
- 최대 65,535Bytes 까지 저장 가능
차이점
- VARCHAR 타입 컬럼에는 지정된 글자 수 만큼 데이터 저장 가능
- VARCHAR(10) -> 10글자 이하만 저장 가능
- TEXT 타입 컬럼은 인덱스 생성 시 반드시 Prefix 길이 지정 필요
- CREATE INDEX ix_text_column ON table (text_column(100));
- TEXT 타입 컬럼은 표현식으로만 디폴트 값 지정 가능
- CREATE TABLE tb1(col TEXT DEFALUT 'abc) 에러 발생
- CREATE TABLE tb1(col1 TEXT DEFAULT ('abc')) 생성가능
일반적인 사용 형태
-
길이가 짧으면 VARCHAR 타입 , 길이가 길면 TEXT 타입
-
그렇다면 VARCHAR(5000) vs TEXT?
- VARCHAR 타입은 어떤 테이블에 저장된 데이터 읽을시 메모리에 이를 위한
- 메모리 버퍼 공간을 미리 할당해두며 유지하며 재활용 가능
- 이 버퍼 공간은 테이블 레코드의 최대 사이즈로 메모리에 할당 되는대 이때
- varchar 경우 버퍼 공간에 포함되서 메모리 공간을 재사용 가능
- TEXT 타입은 그때 그때 필요할 때마다 할당 & 해제
- 컬럼 사용이 빈번하고 메모리 용량이 충분하면 VARCHAR 타입 추천 (오버헤드 줄임)
- VACHAR(5000)과 같이 길이가 긴 컬럼들을 자주 추가하는 경우
- Row 사이즈 제한 (65,535) 에 도달할 수 있으므로 적절하게 TEXT 타입과 같이 사용하는걸 권장
-
VARCHAR(30) vs VARCHAR(255) ?
- 실제 최대 사용하는 길이만큼 명시해야 메모리 사용 효율 증가
- 디스크 공간 효율 차이도 미미하게 존재 (1Byte vs 2Bytes)
궁금한거 정리
-
VARCHAR의 특성
-
테이블 행(row) 구조에서의 VARCHAR 처리에 대해서 밑에 설명 부분
-
VARCHAR 컬럼은 테이블의 고정 길이 부분에 포함
- 무슨말? VARCHAR 컬럼의 메타데이터(길이 정보와 데이터의 위치를 가리키는 포인터)가 고정 길이 부분에 저장
- 실제 VARCHAR 데이터는 가변 길이 부분에 저장
- 데이터의 빠른 접근: 고정 길이 부분을 통해 데이터의 위치를 빠르게 찾을 수 있
- 공간 효율성: 실제 데이터는 필요한 만큼만 가변 길이 부분에 저장
- 메모리 효율성: 고정 길이 부분이 메모리 버퍼에 로드되면, VARCHAR 데이터의 위치 정보도 함께 로드되어 빠른 접근
책장 (테이블) - 예시
각 책꽂이는 하나의 행(row)입니다.
책꽂이의 구조 (행의 구조)
앞부분: 고정된 크기의 공간 (고정 길이 부분)
뒷부분: 크기가 변할 수 있는 공간 (가변 길이 부분)
VARCHAR의 저장 방식
책의 제목과 페이지 번호를 적은 카드를 앞부분에 둡니다. (메타데이터)
실제 책(데이터)은 뒷부분에 둡니다.
TEXT의 저장 방식
책의 제목과 "별도 보관" 표시를 앞부분에 둡니다.
실제 책은 책장 밖 별도의 장소에 보관합니다.
메모리 사용의 차이
VARCHAR: 책의 위치를 빨리 찾을 수 있고, 자주 보는 책은 책장 가까이에 둡니다.
TEXT: 책을 볼 때마다 별도 보관 장소에 가서 가져와야 합니다.
- 따라서 VARCHAR 데이터는 테이블의 다른 컬럼들과 함께 같은 페이지에 저장
- 메모리 재사용 -> 한 번 버퍼 풀에 로드된 페이지는 자주 접근되는 한 메모리에 계속 유지
- 같은 데이터에 다시 접근할 때, 디스크 I/O 없이 메모리에서 바로 읽을 수 있다
- TEXT - > TEXT 데이터는 별도의 페이지에 저장되고, 필요할 때마다 추가로 로드
- 이로 인해 TEXT는 VARCHAR에 비해 메모리 사용이 덜 효율적
ex: VARCHAR(1000) 컬럼이 있는 테이블에서 데이터를 읽으면, 해당 컬럼을 포함한 전체 행이 메모리 버퍼에 로드
- 이후 같은 데이터에 다시 접근할 때, 이미 메모리에 있는 정보를 재사용
- 이해한거 실제 varchar에 접근할 때 메타데이터 부분을 통해 접근하고 메타데이터는
- 실제 데이터가 저장된 공간 길이정보+ 문자 를 가르 킨다.
주의 사항
- varchar 와 text 저장된 사이즈가 크면 off-page 형태로 저장될 수 있음
- mysql innoDB 스토리지 엔진은 하나의 레코드 크기가 데이터 페이지의 절반 크기보다 크다?
- 레코드에서 외부로 저장할 가변 길이 컬럼 선택함
- 그렇게 선택된 컬럼은 별도 외부 페이지의 데이터가 저장됨
- 실제 다른 컬럼들이 저장되어 있는 본래의 데이터 페이지에는 이 외부 페이지를 가르키는
- 20 바이트 포인터 값만 저장 됨.
- ExternerPage Or Off-page 라고 함
- 또한 테이블에 설정된 InnoDB 로우 포맷에 따라 외부 페이지로 컬럼 값을 저장 할 때
- 본래의 데이터 페이지에 저장해 두는 값의 사이즈가 다름
- 최신 Mysql에서의 기본값인 Dynamic Row 포맷 기준해서 20바이트 포인터 값이 저장 됨
정리
- VARCHAR와 TEXT 컬럼의 데이터가 큰 경우, 별도의 페이지에 저장
- InnoDB의 레코드 크기 제한:
하나의 레코드 크기가 데이터 페이지 크기의 절반을 초과하면, 일부 컬럼을 외부로 저장합니다.
- 선택된 가변 길이 컬럼은 별도의 외부 페이지에 저장
- 원래 데이터 페이지에는 20바이트 포인터만 저장
-
데이터가 오프페이지로 저장된 경우 쿼리에서 오프페이지로 저장된 컬럼을
-
참조하고있는지에 따라 쿼리 처리 성능이 매우 달라 짐
-
이는 실제 레코드 읽을때 기존 데이터 페이지뿐만 아니라 해당 컬럼에 대해
-
추가적인 데이터페이지를 읽어야 되기 때문
-
extra_info 에 큰 데이터가 있따면?
-
쿼리 작성시 이와 같은 부분 주의
-
where 절에서 이런 대형 컬럼 조건 참조하는 경우 드뭄
-
대부분 셀렉트 절에서 참조 또한 관성적으로 테이블의 모든 컬럼들을 조회하는 경우 많음
-
오프페이지로 저장된 큰 사이즈 컬럼 데이터 조회시 성능 저하
-
DB 서버 자원도 비효율적으로 사용됨 필요 없는 경우 해당 컬럼 제외해야됨
정리
-
상대적으로 저장되는 데이터 사이즈가 많이 크지 않고 컬럼 사용이 빈번하며
-
DB 서버 메모리 용량 충분하면 varchar 타입 권장
-
저장되는 데이터 사이즈가 큰 편이고 컬럼을 자주 사용하지 않으며 테이블에서 다른 문자열 컬럼들이 많이 사용되고 있는경우 TEXT 타입 권장
-
VARCHAR 타입을 사용하는 경우 길이는 실제 사용되는 만큼만 지정
-
쿼리의 SELECT 절에는 가능하면 필요한 컬럼들만 명시하는 것이 좋다
-
안그러면 테이블에 대형 데이터 저장 컬럼 존재 시 쿼리 처리 성능 하락
-
필요한 컬럼 명시시 커버링 인덱스 방식으로 처리될 가능성 높다