08. DDL(CREATE)
데이터 딕셔너리
- 자원을 효율적으로 관리하기 위한 다양한 정보를 저장하는 시스템 테이블.
- 데이터 딕셔너리는 사용자가 테이블을 생성하거나 사용자를 변경하는 등의 작업을 할 때 데이터베이스 서버에 의해 자동으로 갱신되는 테이블
DDL(CREATE)
- 데이터 정의 언어
- 객체(OBJECT)를 만들고(CREATE), 수정(ALTER), 삭제(DROP) 등 데이터의 전체 구조를 정의하는 언어로 주로 DB관리자, 설계자가 사용함
- 오라클에서 객체 : 테이블(TABLE), 뷰(VIEW), 시퀀스(SEQUENCE), 인덱스(INDEX), 패키지(PACKAGE), 트리거(TRIGGER), 프로시져(PROCEDURE), 함수(FUNCTION), 동의어(SYNOMYM), 사용자(USER)
1) CREATE
- 테이블이나 인덱스, 뷰 등 다양한 데이터베이스 객체를 생성하는 구문
- 테이블로 생성된 객체는 DROP 구문을 통해 제거할 수 있음
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-- < 테이블 생성하기 >
-- ✔ 테이블이란? 행과 열로 구성되는 가장 기본적인 데이터베이스 객체
-- ✔ 데이터베이스 내에서 모든 데이터는 테이블을 통해서 저장된다
[ `표현식` ]
CREATE TABLE `테이블명`(
`컬럼명 자료형`(`크기`),
`컬럼명 자료형`(`크기`),
...
);
CREATE TABLE MEMBER(
MEMEBER_ID VARCHAR2(20),
MEMBER_PWD VARCHAR2(20),
MEMBER_NAME VARCHAR2(30),
MEMBER_SSN CHAR(14),
ENROLL_DATE DEFAULT SYSDATE
);
1
2
3
4
5
6
7
8
9
10
11
12
13
< `자료형` >
NUMBER : `숫자형`(`정수, 실수`)
CHAR(`크기`) : `고정길이 문자형`(2000BYTE)
➡ CHAR(10) `컬럼에 'ABC' 3BYTE 문자열만 저장해도 10BYTE 저장공간을 모두 사용`
VARCHAR2(`크기`) : `가변길이 문자형`(4000BYTE)
➡ VARCHAR2(10) `컬럼에 'ABC' 3BYTE 문자열만 저장하면 나머지 7BYTE를 반환`
DATE : `날짜 타입`
BLOB : `대용량 이진 데이터`(4GB)
CLOB : `대용량 문자 데이터`(4GB)
2) 컬럼에 주석 달기
1
2
3
4
5
6
7
8
[ `표현식` ]
COMMENT ON COLUMN `테이블명`.`컬럼명` IS '주석내용';
COMMENT ON COLUMN MEMBER.MEMBER_ID IS '회원 아이디';
COMMENT ON COLUMN MEMBER.MEMBER_PWD IS '회원 비밀번호';
COMMENT ON COLUMN MEMBER.MEMBER_NAME IS '회원 이름';
COMMENT ON COLUMN MEMBER.MEBER_SSN IS '회원 주민번호';
COMMENT ON COLUMN MEMBER.ENROLL_DATE IS '회원 가입일';
1
2
USER_TABLES : `사용자가 작성한 테이블을 확인 하는 뷰, 데이터 딕셔너리에 정의되어 있음`
SELECT * FROM USER_TABLES;
1
2
3
4
5
6
7
INSERT INTO `테이블명` VALUES(`값1`, `값2`, ...);
INSERT INTO MEMEBER VALUES('MEM01', '12345ABC', '홍길동', '991213-1234567', DEFAULT);
-- INSERT / UPDATE 시 컬럼값으로 DEFAULT를 작성하면 해당 컬럼에 DEFAULT 값 입력
INSERT INTO MEMEBER(MEMBER_ID, MEMBER_PWD, MEMBER_NAME)
VALUES('MEM04', 'PW04', '이지연');
-- INSERT 시 미작성 하는 경우, 컬럼에 DEFAULT 값이 정해져 있으면 DEFAULT 값이 반영된다
1
2
3
4
5
6
7
NUMBER `사용시 문제점`
INSERT INTO MEMBER VALUES('MEM03', 'PW03', '아무개', 7712341234);
INSERT INTO MEMBER VALUES('MEM04', 'PW04', '개똥이', 01012341234);
➡ NUMBER `타입 컬럼에 데이터 삽입시`
-- ✔ 제일 앞에 0이 있으면 자동으로 제거함
-- ✔ 주민번호 또는 전화번호 같이 '-' 있으면 연산함
-- ✔ 숫자 표현시 자리수에 맞춰 ',' 발생
3) CONSTRAINTS(제약조건)
- 사용자가 원하는 조건의 데이터만 유지하기 위해서 특정 컬럼에 설정하는 제약
- 데이터 무결성 보장을 목적으로 함 ➡️ 중복 데이터가 없다
- 입력 데이터에 문제가 없는지 자동으로 검사하는 목적
- 데이터의 수정/삭제 가능 여부 검사등을 목적으로 한다 ➡️ 제약조건을 위배하는 DML 구문은 수행할 수 없음
- PRIMARY KEY, UNIQUE, NOT NULL, FOREIGN KEY, CHECK
USER_CONSTRAINTS : 사용자가 작성한 제약조건을 확인하는 딕셔너리 뷰
- (1) NOT NULL
- 해당 컬럼에 반드시 값이 기록되어야하는 경우 사용
- 삽입/수정 시 NULL 값을 허용하지 않도록 컬럼레벨에서 제한
- 컬럼레벨? 테이블 생성 시 컬럼을 정의하는 부분에서 작성하는 것
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
CREATE TABLE USER_USED_NN( USER_NO NUMBER NOT NULL, USER_ID VARCHAR2(20), USER_PWD VARCHAR2(20), USER_NAME VARCHAR2(30), GENDER VARCHAR2(10), PHONE VARCHAR2(30), EMAIL VARCHAR2(50) ); INSERT INTO USER_USED_NN VALUES(1, 'USER01', 'PASS01', '홍길동', '남', '010-1234-1234', 'Hong@kh.or.kr'); INSERT INTO USER_USED_NN VALUES(NULL, NULL, NULL, NULL, '남', '010-1234-1234', 'Hong@kh.or.kr'); -- ORA-01400: NULL을 ("KH"."USER_USED_NN"."USER_NO") 안에 삽입할 수 -- 없습니다 ➡️ NOT NULL 제약조건에 위배되어 오류 발생
- (2) UNIQUE
- 컬럼에 입력값에 대해서 중복을 제한하는 제약조건
- 컬럼레벨과 테이블 레벨에서 설정 가능
- 단, UNIQUE 제약조건이 설정된 컬럼에 NULL 값은 중복 삽입 가능
- 테이블 레벨 : 테이블 생성시 컬럼 정의가 끝난 후 마지막에 작성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
-- < 컬럼레벨 : [CONSTRAINT 제약조건명] 제약조건 > -- < 테이블레벨 : [CONSTRAINT 제약조건명] 제약조건(컬럼명) > CREATE TABLE USER_USED_UQ( USER_NO NUMBER, USER_ID VARCHAR2(20) UNIQUE, USER_PWD VARCHAR2(20) /* 테이블 레벨 */ -- CONSTARINT USER_ID_UQ UNIQUE(USER_ID) ); INSERT INT USER_USED_UQ VALUES(1, 'USER01', 'PW01'); INSERT INT USER_USED_UQ VALUES(2, 'USER01', 'PW02'); -- ORA-00001: 무결성 제약 조건(KH.SYS_C008405)에 위배됩니다 INSERT INTO USER_USED_UQ VALUES(1, NULL, 'PW01'); -- 아이디에 NULL 값 입력 가능. NULL은 중복 가능
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
-- < UNIQUE 복합키 > -- 두개 이상의 컬럼을 묶어서 하나의 UNIQUE 제약 조건을 설정함 -- 복합키 지정은 테이블 레벨에서만 가능하다 -- 복합키는 지정된 모든 컬럼의 값이 같을 때 위배된다 CREATE TABLE USER_USED_UQ2( USER_NO NUMBER, USER-ID VARCHAR2(20), USER_PWD VARCHAR2(20) NOT NULL, USER NAME VARCHAR2(30), CONSTRAINT USER_ID_NAME_UQ UNIQUE(USER_ID, USER_NAME) ); INSERT INTO USER_USED_UQ2 VALUES(1, 'USER01', 'PW01', '홍길동'); -- ID가 다르다 NSERT INTO USER_USED_UQ2 VALUES(2, 'USER02', 'PW01', '홍길동'); -- NAME이 다르다 INSERT INTO USER_USED_UQ2 VALUES(1, 'USER01', 'PW01', '고길동'); -- ID와 NAME이 같다 INSERT INTO USER_USED_UQ2 VALUES(1, 'USER01', 'PW01', '고길동'); -- SQL Error [1] [23000]: ORA-00001: 무결성 제약 조건 -- (KH.USER_ID_NAME_U)에 위배됩니다
- (3) PRIMARY KEY
- 테이블에서 한 행의 정보를 찾기 위해 사용할 컬럼을 의미
- 테이블에 대한 식별자 역할을 한다
- 한테이블당 한개만 설정 할 수 있다
- 컬럼레벨, 테이블레벨 둘다 설정 가능
- NOT NULL + UNIQUE 제약조건의 의미 ➡️ 중복되지 않는 값이 필수로 존재해야 한다
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
CREATE TABLE USER_USED_PK( USER_NO NUMBER CONSTRAINT USER_NO_PK PRIMARY KEY, USER_ID VARCHAR2(20) UNIQUE, USER_PWD VARCHAR2(20) NOT NULL, USER_NAME VARCHAR2(30) -- 테이블 레벨 -- CONSTRAINT USER_NO_PK PRIMARY KEY(USER_NO) ); INSERT INTO USER_USED_PK VALUE(1, 'USER01', 'PW01', '홍길동'); INSERT INTO USER-USED_PK VALUES(1,'USER02', 'PW02', '고길동'); --> ORA-00001: 무결성 제약 조건(KH.USER_NO_PK)에 위배됩니다 INSERT INTO USER-USED_PK VALUES(NULL,'USER02', 'PW02', '고길동'); --> ORA-01400: NULL을 ("KH"."USER_USED_PK2"."USER_NO") -- 안에 삽입할 수 없습니다
- (4) FOREIGN KEY
- 참조된 다른 테이블의 컬럼이 제공하는 값만 사용할 수 있음
- FOREIGN KEY 제약조건에 의해서 테이블간에 관계가 형성됨
- 제공되는 값 외에는 NULL을 사용할 수 있음
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
-- < 컬럼 레벨 > `컬럼명 자료형`(`크기`) [CONSTRAINT `이름`] REFERENCES `참조할테이블명` [(`참조할컬럼`)][`삭제룰`] -- < 테이블 레벨 > [CONSTRAINT `이름`] FOREIGN KEY(`적용할 컬럼명`) REFERENCES `참조할테이블명` [(`참조할 컬럼명`)] [`삭제룰`] CREATE TABLE USER_GRADE( GRADE_CODE NUMBER PRIMARY KEY, GRADE_NAME VARCHAR2(30) NOT NULL ); INSERT INTO USER_GRADE VALUES(10, '일반회원'); INSERT INTO USER_GRADE VALUES(20, '우수회원'); INSERT INTO USER_GRADE VALUES(30, '특별회원'); CREATE TABLE USER_USED_FK( USER_NO NUMBER PRIMARY KEY, USER_ID VARCHAR2(20) UNIQUE, USER_PWD VARCHAR2(30) NOT NULL, GRADE_CODE NUMBER CONSTRAINT GRADE_CODE_FK REFERENCES USER_GRADE -- 컬럼명 미작성시 USER_GRADE 테이블의 PK를 자동 참조 ); INSERT INTO USER_USED_FK VALUES(1, 'USER01', 'PW01', 10); INSERT INTO USER_USED_FK VALUES(2, 'USER02', 'PW02', 20); INSERT INTO USER_USED_FK VALUES(3, 'USER03', 'PW03', 30); INSERT INTO USER_USED_FK VALUES(4, 'USER04', 'PW04', NULL); INSERT INTO USER_USED_FK VALUES(5, 'USER05', 'PW05', 50); -- ORA-02291:무결성 제약조건(KH.GRADE_CODE_FK)이 위배되었습니다 - 부모 키 -- 가 없습니다 --> 50이라는 값은 USER_GRADE 테이블의 GRADE_CODE 컬럼에서 제공하는 -- 값이 아니므로 외래키 제약 조건에 위배되어 오류 발생
1 2
< FROEIGN KEY 삭제 옵션 > 부모 테이블의 데이터 삭제 시 자식 테이블의 데이터를 어떤식으로 처리할지에 대한 내용을 설정할 수 있다
1 2 3 4 5 6 7 8 9
1) ON DELETE RESTPICTED(`삭제 제한`)`로기본 지정되어 있음` -- FOREIGN KEY로 지정된 컬럼에서 사용되고 있는 값일 경우 -- 제공하는 컬럼의 값은 삭제하지 못한다 UPDATE USER_USED_FK SET GRADE_CODE = 30 WHERE GRADE_CODE = 20; -- GRADE_CODE 중 20은 외래키로 참조되고 있지 않으므로 삭제 가능함 DELETE FROM USER_GRADE WHERE GRADE_CODE = 20;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
2) ON DELETE SET NULL : `부모키 삭제 시 자식키를 NULL로 변경하는 옵션` CREATE TABLE USER_GRADE2( GRADE_CODE NUMBER PRIMARY KEY, GRADE_NAME VARCHAR2(30) NOT NULL ); CREATE TABLE USER_USED_FK2( USER_NO NUMBER PRIMARY KEY, USER_ID VARCHAR2(20) UNIQUE, USER_PWD VARCHAR2(30) NOT NULL, GRADE_CODE NUMBER CONSTRAINT GRADE_CODE_FK REFERENCES USER_GRADE ON DELETE SET NULL ); INSERT INTO USER_USED_FK2 VALUES(1, 'USER01' 'PW01', 10); INSERT INTO USER_USED_FK2 VALUES(2, 'USER02' 'PW02', 10); INSERT INTO USER_USED_FK2 VALUES(3, 'USER03' 'PW03', 30); INSERT INTO USER_USED_FK2 VALUES(4, 'USER04' 'PW04', NULL); DELETE FROM USER_GRADE2 WHERE GRADE_CODE = 10;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
3) ON DELETE CASCADE : `부모키 삭제시 자식키도 함께 삭제됨` -- 부모키 삭제시 값을 사용하는 자식 테이블의 컬럼에 해당하는 삭제됨 CREATE TABLE USER_GRADE3( GRADE_CODE NUMBER PRIMARY KEY, GRADE_NAME VARCHAR2(30) NOT NULL ); INSERT INTO USER_GRADE3 VALUES(10, '일반회원'); INSERT INTO USER_GRADE3 VALUES(20, '우수회원'); INSERT INTO USER_GRADE3 VALUES(30, '특별회원'); CREATE TABLE USER_USED_FK3( USER_NO NUMBER PRIMARY KEY, USER_ID VARCHAR2(20) UNIQUE, USER_PWD VARCHAR2(20) NOT NULL, GRADE_CODE NUMBER CONSTRAINT GRADE_CODE_FK3 FOREIGN KEY(GRADE_CODE) REFERENCES USER_GRADE3 (GRADE_CODE) ON DELETE CASCADE ); INSERT INTO USER_USED_FK3 VALUES(1, 'USER01' 'PW01', 10); INSERT INTO USER_USED_FK3 VALUES(2, 'USER02' 'PW02', 10); INSERT INTO USER_USED_FK3 VALUES(3, 'USER03' 'PW03', 30); INSERT INTO USER_USED_FK3 VALUES(4, 'USER04' PW04', NULL); DELETE FROM USER_GRADE3 WHERE GRADE_CODE = 10;
- (5) CHECK
- 컬럼에 기록되는 값에 조건을 설정할 수 있음
- CHECK(컬럼명 비교연산자 비교값)
- 주의할 점 : 비교값은 리터럴만 사용할 수 있다. 변하는 값 or 함수 사용 못함
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
CREATE TABLE USER_USED_CHECK( USER_NO NUMBER PRIMARY KEY, USER_ID VARCHAR2(20) UNIQUE, USER_PWD VARCHAR2(20) NOT NULL, USER_NAME VARCHAR2(30), GENDER VARCHAR2(10) CONSTRAINT GENDER_CHECK CHECK ( GENDER IN ('남', '여') ) ); INSERT INTO USER_USED_CHECK VALUES(1, 'USER01', 'PW01', '홍길동', '남'); INSERT INTO USER_USED_CHECK VALUES(2, 'USER02', 'PW02', '고길동', '남자'); -- ORA-02290: 체크 제약조건(KH.GENDER_CHECK)이 위배되었습니다 -- CHECK 조건에 의해 GENDER에 남, 여만 기록 가능
- (6) SUBQUERY를 이용한 테이블 생성법
- 컬럼명, 데이터 타입, 값이 복사되고, 제약조건은 NOT NULL만 복사된다
1 2 3 4 5 6 7 8 9 10 11 12 13
1) `테이블 전체 복사` CREATE TABLE EMP_COPY AS SELECT * FROM EMPLOYEE; 2) JOIN `후 원하는 컬럼만 테이블로 복사` CREATE TABLE EMP_COPY AS SELECT EMP_ID, EMP_NAME, DEPT_TITLE, JOB_NAME FROM EMPLOYEE LEFT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID) JOIN JOB USING (JOB_CODE); --> 서브쿼리로 테이블 생성시 -- 테이블의 형태(컬럼명, 데이터 타입) + NOT NULL 제약조건만 복사 -- 다른 제약조건, COMMENT는 복사되지 않는다.