문자와 대용량 데이터 타입
CHAR, VARCHAR2 비교와 LONG, CLOB 저장 조건을 구분하며 CLOB CTAS 실습 결과는 확인 불가
#핵심 요약
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 섞어 쓰기
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;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
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만 행에 있다는 설명은 적용할 수 없음