데이터베이스 연구실.log

문자와 대용량 데이터 타입

CHAR, VARCHAR2 비교와 LONG, CLOB 저장 조건을 구분하며 CLOB CTAS 실습 결과는 확인 불가

CHARVARCHAR2LONGCLOB고정 길이가변 길이행 이주

#핵심 요약

CHAR는 고정 길임
값이 짧아도 정해진 크기를 다 차지함
VARCHAR2는 가변 길이로 값 크기에 맞춰 저장함

실무에서는 90% 이상 VARCHAR2를 쓰고, CHAR는 주민등록번호, 자릿수가 고정된 사번, 통화 코드, Y/N 플래그처럼 길이가 변하지 않는 값에만 씀

CHAR와 VARCHAR2를 어중간하게 섞으면 조인 결과가 안 나오는 문제가 생김

LONG은 하위 호환용 구형 타입이고 CLOB이 표준임
LONG 컬럼이 있는 테이블은 CREATE TABLE ... AS SELECT로 복사할 수 없었음

#개념과 동작 원리

비교 LONG(구형) CLOB(표준)
권장 상태 사용 중단 권고, 하위 호환용 현재 표준(Character Large Object)
최대 크기 2GB 4GB
테이블당 개수 1개만 여러 개
SQL 조작 WHERE, GROUP BY, ORDER BY 사용 불가 대부분의 SQL 함수와 조작 가능
저장 방식 행에 직접 저장(조회 속도 저하) 별도 공간에 저장하고 행에는 주소(locator)만

위 표는 실습에서 제시한 비교임
CLOB의 크기, 저장 방식, SQL 범위에는 아래 보완 조건을 적용함

설명(행 이주): VARCHAR2 값이 처음보다 크게 갱신되면 행이 원래 블록에 들어가지 못해 다른 블록으로 옮겨지는 row migration이 생기고, 조회 때 여러 블록을 읽게 됨
그래서 크게 갱신될 컬럼을 처음부터 CHAR로 만드는 방법도 있지만, 현업에서는 보통 신경 쓰지 않고 VARCHAR2로 만들며, 행 이주는 재구성(reorg) 작업으로 해결함
행 이주는 행 체이닝과 행 이주에 있음

#주요 용어와 구성 요소

구문 의미
길이 의미 BYTE는 바이트 수, CHAR는 문자 수이며 다중 바이트 문자에서 같은 수치가 같은 저장 길이를 뜻하지 않음
공백 채움 비교 두 값이 CHAR, NCHAR, 문자 리터럴 등인 경우 짧은 쪽에 공백을 채워 비교함
공백 미채움 비교 한쪽이라도 VARCHAR2, NVARCHAR2이면 끝 공백도 비교에 영향을 줌

#필수 명령어 또는 SQL

항목 실행 조건
작업 대상 emp700, dept700의 문자 비교와 self_intro의 LONG 복사
필요 권한 자기 스키마 CREATE TABLE, 저장 공간 할당 조건, 입력, 조회 대상 권한
바꿀 입력값 테이블, 문자 길이, 길이 의미, <NAME>, 자기소개 문장
결과 해석 CHAR 비교 결과와 LONG 오류는 본문 참조
CLOB CTAS 결과는 확인 불가

#CHAR와 VARCHAR2 섞어 쓰기

SQL Developer 또는 SQL*Plus객체 또는 설정을 변경함
CREATE TABLE emp700
( ename  VARCHAR2(20),
  sal    VARCHAR2(20),
  deptno VARCHAR2(10) );
INSERT INTO emp700 VALUES ('scott', 3000, '10');
INSERT INTO emp700 VALUES ('allen', 2500, '20');

CREATE TABLE dept700
( deptno CHAR(10),
  loc    VARCHAR2(10) );
INSERT INTO dept700 VALUES ('10', 'chicago');
INSERT INTO dept700 VALUES ('20', 'dallas');
COMMIT;
SQL Developer 또는 SQL*Plus조회만 함
SELECT * FROM dept700 WHERE deptno = '10';
SELECT * FROM emp700  WHERE deptno = '10';

SELECT e.ename, d.loc
  FROM emp700 e, dept700 d
 WHERE e.deptno = d.deptno;

결과 해석: 첫 두 문장은 검색됨
CHAR(10) 컬럼과 비교할 때 Oracle이 '10'에 공백을 채워 주기 때문임
세 번째 조인은 조회되지 않음
CHAR(10)에 저장된 '10' 뒤의 공백 8칸과 VARCHAR2의 '10'이 같지 않다고 비교된 결과로 보임
비교에 VARCHAR2가 포함되면 공백을 채우지 않는 비교가 적용됨

실습 결론: 테이블 설계 때 CHAR와 VARCHAR2를 섞지 말고 웬만하면 모두 VARCHAR2로 하고, 주민번호 같은 컬럼만 CHAR로 함

#LONG과 CLOB

SQL Developer 또는 SQL*Plus객체 또는 설정을 변경함
CREATE TABLE self_intro
( i_id    NUMBER(10),
  i_name  VARCHAR2(20),
  i_intro LONG );

INSERT INTO self_intro VALUES (1, '<NAME>', '<자기소개 문장>');

CREATE TABLE new_db_self_intro
AS
SELECT * FROM self_intro;

결과 해석: 주석은 "에러가 발생합니다"임
실습에서는 i_intro를 CLOB으로 바꿔 다시 만들고 같은 CREATE TABLE ... AS SELECT가 되는지 확인하게 했는데, 그 문장의 주석도 "에러가 발생합니다"로 똑같이 적혀 있음
복사해 붙인 주석으로 보이며 CLOB 쪽 결과는 수업 자료에서 확인할 수 없음

#구문과 옵션 설명

CLOB을 최대 4GB로 고정하는 설명은 적용할 수 없음
표준 블록 크기와 기본 CHUNK를 쓰는 조건에서 상한은 (4GB − 1) × 데이터베이스 블록 크기임
LOB은 설정과 값의 크기에 따라 행 안에도 저장될 수 있어 언제나 locator만 행에 있다는 설명은 적용할 수 없음

#사용 조건과 주의사항

SEO_HKabsumveritas@gmail.comBuilt with Claude Code & Codex

마지막 갱신 개인 학습 기록이며 운영 환경 적용 전 공식 문서 확인 필요

두 글자 이상 입력, 위아래 화살표로 이동하고 Enter로 열기