오늘의 두번째 TIL DDL...
USER_TABLES : 자신의 계정이 소유한 객체 등에 관한 정보를 조회할 수 있는 딕셔너리 뷰
DDL을 보기 전 지금까지 배운 것 정리
DQL (Data Query Language) : 데이터 질의(조회) 언어
DML (Data Manipulation Language) : 데이터 조작 언어
테이블에 데이터 삽입, 수정, 삭제
TCL (Transation Control Language) : 트랜잭션 제어 언어
DML 수행 내용을 Commit, Rollback 하는 언어
DDL ( Data Definition Laguage ) : 데이터 정의 언어
객체(OBJECT)를 만들고(CREATE), 수정(ALTER), 삭제(DROP) 등 데이터의 전체 구조를 정의하는 언어로 주로 DB 관리자, 설계자가 사용한다.
테이블이나 인덱스, 뷰 등 다양한 데이터베이스 객체를 생성하는 구문으로 테이블로 생성된 객체는 DROP 구문을 통해 제거할 수 있다.
테이블이란?
행(ROW)과 열(COLUMN)으로 구성되는 가장 기본적인 데이터베이스 객체로 데이터베이스 내에서 모든 데이터는 테이블을 통해서 저장된다.
[표현식]
CREATE TABLE 테이블명 (
컬럼명 자료형 (크기),
컬럼명 자료형 (크기),
컬럼명 자료형 (크기),
...
);
CREATE TABLE "MEMBER" (
MEMBER_ID VARCHAR2(20),
MEMBER_PWD VARCHAR2(20),
MEMBER_NAME VARCHAR2(30),
MEMBER_SSN CHAR(14),
ENROLL_DATE DATE DEFAULT SYSDATE
);
참고!
SQL 작성법 : 대문자 작성권장, 연결된 단어 사이는 "_" (언더바) 사용
문자인코딩 UTF-8 : 영어, 숫자 1BYTE, 한글 3BYTE 취급
[표현식]
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.MEMBER_SSN IS '회원 주민 등록 번호';
COMMENT ON COLUMN MEMBER.ENROLL_DATE IS '회원 가입일';
INSERT INTO 테이블명 VALUES (값1, 값2, ...)
INSERT INTO MEMBER VALUES ('MEM01', '123ABC', '홍길동', '991213-1234567', DEFAULT);
INSERT / UPDATE 시 컬럼값으로 DEFAULT 를 작성하면 테이블 생성 시 해당 컬럼에 지정된 DEFAULT 값으로 삽입이 된다.
INSERT INTO MEMBER VALUES ('MEM02', '456QWE', '김영희', '940223-1124557', DEFAULT);
INSERT INTO MEMBER VALUES ('MEM03', '789ASD', '박철수', '951001-1253467', SYSDATE);
INSERT INTO MEMBER (MEMBER_ID, MEMBER_PWD, MEMBER_NAME)
VALUES ('MEM04', 'TDS1213', '이지연');
INSERT INTO MEMBER VALUES('MEM05', 'GFK593', '김길동', '931111-1653464',
TO_DATE('2022-09-13 17:33:27', 'YYYY-MM-DD HH24:MI:SS'));
사용자가 원하는 조건의 데이터만 유지하기 위해서 특정 컬럼에 설정하는 제약으로 데이터 무결성 보장을 목적으로 한다. --> 중복 테이터 X
추가로 입력 데이터에 문제가 없는지 자동으로 검사하는 목적 , 데이터의 수정/삭제 가능 여부 검사등을 목적으로 함 --> 제약조건을 위배하는 DML 구문은 수행할 수 없다!
제약 조건 종류
해당 컬럼에 반드시 값이 기록되어야 하는 경우에 사용하며 삽입/수정시 NULL값을 허용하지 않도록 컬럼레벨에서 제한한다.
CREATE TABLE USER_USED_NN (
USER_NO NUMBER NOT NULL, -- 사용자 번호 (모든 사용자는 사용자 번호가 있어야한다.)
--> 컬럼레벨 제약조건 설정
USER_ID VARCHAR2(20),
USER_PWD VARCHAR2(30),
USER_NAME VARCHAR2(30),
GENDER VARCHAR2(10),
PHONE VARCHAR2(30),
EMAIL VARCHAR2(50)
);
INSERT INTO USER_USED_NN
VALUES(1, 'USER01', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr');
INSERT INTO USER_USED_NN
VALUES(NULL, NULL, NULL, NULL, NULL, '010-1234-5678', 'hong1234@kh.or.kr');
--> NOT NULL 제약조건에 위배되어 오류 발생
-- ORA-01400: NULL을 ("KH"."USER_USED_NN"."USER_NO") 안에 삽입할 수 없습니다
컬럼에 입력값에 대해서 중복을 제한하는 제약조건으로 컬럼레벨에서 설정 가능, 테이블 레벨에서 설정 가능하다. 단, UNIQUE 제약조건이 설정된 컬럼에 NULL 값은 중복 삽입 가능
테이블레벨 : 테이블 생성 시 컬럼 정의가 끝난 후 마지막에 작성
제약조건 지정 방법
1) 컬럼 레벨 : [CONSTRAINT 제약조건명] 제약조건
2) 테이블 레벨 : [CONSTRAINT 제약조건명] 제약조건(컬럼명)
CREATE TABLE USER_USED_UK (
USER_NO NUMBER,
-- USER_ID VARCHAR2(20) UNIQUE, -- 컬럼레벨 (제약조건명 미지정)
-- USER_ID VARCHAR2(20) CONSTRAINT USER_ID_U UNIQUE, -- 컬럼레벨 (제약조건명 지정)
USER_ID VARCHAR2(20),
USER_PWD VARCHAR2(30),
USER_NAME VARCHAR2(30),
GENDER VARCHAR2(10),
PHONE VARCHAR2(30),
EMAIL VARCHAR2(50),
/* 테이블 레벨 */
-- UNIQUE(USER_ID) -- 테이블레벨 (제약조건명 미지정)
CONSTRAINT USER_ID_U UNIQUE(USER_ID) -- 테이블레벨 (제약조건명 지정)
);
INSERT INTO USER_USED_UK
VALUES(1, 'USER01', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr');
INSERT INTO USER_USED_UN
VALUES(1, 'USER01', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr');
-- ORA-00942: 테이블 또는 뷰가 존재하지 않습니다
-- 같은 아이디인 데이터가 이미 테이블에 있으므로 UNIQUE 제약조건에 위배되어 오류발생
INSERT INTO USER_USED_UK
VALUES(1, NULL, 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr');
--> 아이디에 NULL 값 삽입 가능.
INSERT INTO USER_USED_UK
VALUES(1, NULL, 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr');
--> 아이디에 NULL 값 중복 삽입 가능
두 개 이상의 컬럼을 묶어서 하나의 UNIQUE 제약조건을 설정한다.
CREATE TABLE USER_USED_UK2 (
USER_NO NUMBER,
USER_ID VARCHAR2(20),
USER_PWD VARCHAR2(30),
USER_NAME VARCHAR2(30),
GENDER VARCHAR2(10),
PHONE VARCHAR2(30),
EMAIL VARCHAR2(50),
CONSTRAINT USER_ID_NAME_U UNIQUE(USER_ID, USER_NAME)
);
INSERT INTO USER_USED_UK2
VALUES(1, 'USER01', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr');
INSERT INTO USER_USED_UK2
VALUES(1, 'USER02', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr');
INSERT INTO USER_USED_UK2
VALUES(1, 'USER01', 'PASS01', '고길동', '남', '010-1234-5678', 'hong1234@kh.or.kr');
INSERT INTO USER_USED_UK2
VALUES(1, 'USER01', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr');
-- ORA-00001: 무결성 제약 조건(KH.USER_ID_NAME_U)에 위배됩니다
테이블에서 한 행의 정보를 찾기 위해 사용할 컬럼을 의미하고 테이블에 대한 식별자(학번, 사번, 회원번호) 역할을 한다.
NOT NULL + UNIQUE 제약조건의 의미 --> 중복되지 않는 값이 필수로 존재해야 함.
CREATE TABLE USER_USED_PK (
USER_NO NUMBER CONSTRAINT USER_NO_PK PRIMARY KEY, -- 컬럼레벨
USER_ID VARCHAR2(20),
USER_PWD VARCHAR2(30),
USER_NAME VARCHAR2(30),
GENDER VARCHAR2(10),
PHONE VARCHAR2(30),
EMAIL VARCHAR2(50)
-- CONSTRAINT USER_ID_PK PRIMARY KEY(USER_ID) -- 테이블 레벨
);
INSERT INTO USER_USED_PK
VALUES(1, 'USER01', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr');
INSERT INTO USER_USED_PK
VALUES(1, 'USER02', 'PASS02', '이순신', '남', '010-5678-9999', 'LEE1234@kh.or.kr');
-- ORA-00001: 무결성 제약 조건(KH.USER_NO_PK)에 위배됩니다
--> 기본키 중복으로 오류
INSERT INTO USER_USED_PK
VALUES(NULL, 'USER02', 'PASS02', '이순신', '남', '010-5678-9999', 'LEE1234@kh.or.kr');
--ORA-01400: NULL을 ("KH"."USER_USED_PK"."USER_NO") 안에 삽입할 수 없습니다
--> 기본키가 NULL 이므로 오류
테이블 레벨만 가능
CREATE TABLE USER_USED_PK2 (
USER_NO NUMBER, -- 컬럼레벨
USER_ID VARCHAR2(20),
USER_PWD VARCHAR2(30),
USER_NAME VARCHAR2(30),
GENDER VARCHAR2(10),
PHONE VARCHAR2(30),
EMAIL VARCHAR2(50),
CONSTRAINT USER_ID_PK PRIMARY KEY(USER_ID, USER_NO) -- 테이블 레벨
);
INSERT INTO USER_USED_PK2
VALUES(1, 'USER01', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr');
INSERT INTO USER_USED_PK2
VALUES(1, 'USER02', 'PASS02', '이순신', '남', '010-5678-9999', 'LEE1234@kh.or.kr');
INSERT INTO USER_USED_PK2
VALUES(2, 'USER01', 'PASS02', '이순신', '남', '010-5678-9999', 'LEE1234@kh.or.kr');
INSERT INTO USER_USED_PK2
VALUES(1, 'USER01', 'PASS02', '이순신', '남', '010-5678-9999', 'LEE1234@kh.or.kr');
-- ORA-00001: 무결성 제약 조건(KH.USER_ID_PK)에 위배됩니다
--> 회원 번호와 아이디 둘다 중복되었을 때만 제약조건 위배 에러
INSERT INTO USER_USED_PK2
VALUES(NULL, 'USER01', 'PASS02', '이순신', '남', '010-5678-9999', 'LEE1234@kh.or.kr');
--ORA-01400: NULL을 ("KH"."USER_USED_PK2"."USER_NO") 안에 삽입할 수 없습니다
--> PRIMAEY KEY는 NULL이 들어갈 수 없다.
참조된 다른 테이블의 컬럼이 제공하는 값만 사용할 수 있고 FOREIGN KEY 제약조건에 의해서 테이블간 관계가 형성된다.
제공하는 값 외에는 NULL(참조하는 값 없음) 을 사용할 수 있음.
컬럼레벨일 경우
컬럼명 자료형 (크기) [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, '특별회원');
SELECT * FROM USER_GRADE;
CREATE TABLE USER_USED_FK (
USER_NO NUMBER PRIMARY KEY,
USER_ID VARCHAR2(20) UNIQUE,
USER_PWD VARCHAR2(30) NOT NULL,
USER_NAME VARCHAR2(30),
GENDER VARCHAR2(10),
PHONE VARCHAR2(30),
EMAIL VARCHAR2(50),
GRADE_CODE NUMBER CONSTRAINT GRADE_CODE_FK REFERENCES USER_GRADE /*(GRADE_CODE)*/ -- 컬럼레벨
-- 컬럼명 미작성 USER_GRADE 테이블의 PK자동참조
-- 테이블레벨
-- CONSTRAINT GRADE_CODE_FK FOREIGN KEY(GRADE_CODE) REFERENCES USER_GRADE
--> FOREIGN KEY 라는 단어는 테이블 레벨에서만 사용!
);
COMMIT;
INSERT INTO USER_USED_FK
VALUES(1, 'USER01', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr', 10);
INSERT INTO USER_USED_FK
VALUES(2, 'USER02', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr', 10);
INSERT INTO USER_USED_FK
VALUES(3, 'USER03', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr', 30);
INSERT INTO USER_USED_FK
VALUES(4, 'USER04', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr', NULL);
--> NULL 사용 가능
INSERT INTO USER_USED_FK
VALUES(5, 'USER05', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr', 50);
-- ORA-02291: 무결성 제약조건(KH.GRADE_CODE_FK)이 위배되었습니다- 부모 키가 없습니다
--> 50 이라는 값은 USER_GRADE 테이블 GRADE_CODE 컬럼에서 제공하는 값이 아니므로
-- 외래키 제약조건에 위배되어 오류 발생.
부모테이블의 데이터 삭제 시 자식 테이블의 데이터를 어떤식으로 처리할 지에 대한 내용을 설정 할 수 있다.
1) ON DELETE RESRTICTED(삭제 제한)로 기본 지정되어 있음
외래키로 지정된 컬럼에서 사용되고 있는 값일 경우 제공하는 컬럼의 값을 삭제하지 못함
DELETE FROM USER_GRADE WHERE GRADE_CODE = 30;
-- ORA-02292: 무결성 제약조건(KH.GRADE_CODE_FK)이 위배되었습니다- 자식 레코드가 발견되었습니다
GRADE_CODE 중 20은 외래키로 참조되고 있지 않았으므로 삭제가 가능함.
DELETE FROM USER_GRADE WHERE GRADE_CODE = 20;
2) ON DELETE SET NULL : 부모키 삭제시 자식키를 NULL로 변경하는 옵션
CREATE TABLE USER_GRADE2(
GRADE_CODE NUMBER PRIMARY KEY,
GRADE_NAME VARCHAR2(30) NOT NULL
);
INSERT INTO USER_GRADE2 VALUES (10, '일반회원');
INSERT INTO USER_GRADE2 VALUES (20, '우수회원');
INSERT INTO USER_GRADE2 VALUES (30, '특별회원');
SELECT * FROM USER_GRADE2;
-- ON DELETE SET NULL 삭제 옵션이 적용된 테이블 생성
CREATE TABLE USER_USED_FK2 (
USER_NO NUMBER PRIMARY KEY,
USER_ID VARCHAR2(20) UNIQUE,
USER_PWD VARCHAR2(30) NOT NULL,
USER_NAME VARCHAR2(30),
GENDER VARCHAR2(10),
PHONE VARCHAR2(30),
EMAIL VARCHAR2(50),
GRADE_CODE NUMBER CONSTRAINT GRADE_CODE_FK2 REFERENCES USER_GRADE2 ON DELETE SET NULL
);
INSERT INTO USER_USED_FK2
VALUES(1, 'USER01', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr', 10);
INSERT INTO USER_USED_FK2
VALUES(2, 'USER02', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr', 10);
INSERT INTO USER_USED_FK2
VALUES(3, 'USER03', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr', 30);
INSERT INTO USER_USED_FK2
VALUES(4, 'USER04', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr', NULL);
COMMIT;
SELECT * FROM USER_GRADE2;
SELECT * FROM USER_USED_FK2;
DELETE FROM USER_GRADE2
WHERE GRADE_CODE = 10;
SELECT * FROM USER_USED_FK2;
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, '특별회원');
SELECT * FROM USER_GRADE3;
-- ON DELETE CASCADE
CREATE TABLE USER_USED_FK3 (
USER_NO NUMBER PRIMARY KEY,
USER_ID VARCHAR2(20) UNIQUE,
USER_PWD VARCHAR2(30) NOT NULL,
USER_NAME VARCHAR2(30),
GENDER VARCHAR2(10),
PHONE VARCHAR2(30),
EMAIL VARCHAR2(50),
GRADE_CODE NUMBER CONSTRAINT GRADE_CODE_FK3 REFERENCES USER_GRADE2 ON DELETE CASCADE
/*삭제옵션 */
);
INSERT INTO USER_USED_FK3
VALUES(1, 'USER01', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr', 10);
INSERT INTO USER_USED_FK3
VALUES(2, 'USER02', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr', 10);
INSERT INTO USER_USED_FK3
VALUES(3, 'USER03', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr', 30);
INSERT INTO USER_USED_FK3
VALUES(4, 'USER04', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr', NULL);
COMMIT;
SELECT * FROM USER_GRADE3;
SELECT * FROM USER_USED_FK3;
-- 부모테이블인 USER_GRADE3에서 GRADE_CODE = 10삭제
--> ON DELETE CASCADE 옵션이 설정되어 있어서 오류없이 삭제됨.
DELETE FROM USER_GRADE3
WHERE GRADE_CODE = 10;
컬럼에 기록되는 값에 조건 설정을 할 수 있음
CHECK (컬럼명 비교연산자 비교값)
CREATE TABLE USER_USED_CHECK (
USER_NO NUMBER PRIMARY KEY,
USER_ID VARCHAR2(20) UNIQUE,
USER_PWD VARCHAR2(30) NOT NULL,
USER_NAME VARCHAR2(30),
GENDER VARCHAR2(10) CONSTRAINT GENDER_CHECK CHECK(GENDER IN ('남','여')) ,
PHONE VARCHAR2(30),
EMAIL VARCHAR2(50)
);
INSERT INTO USER_USED_CHECK
VALUES(1, 'USER01', 'PASS01', '홍길동', '남', '010-1234-5678', 'hong1234@kh.or.kr');
INSERT INTO USER_USED_CHECK
VALUES(2, 'USER02', 'PASS02', '홍길동', '남자', '010-1234-5678', 'hong1234@kh.or.kr');
-- ORA-02290: 체크 제약조건(KH.GENDER_CHECK)이 위배되었습니다
-- GENDER 컬럼에 CHECK 제약조건으로 '남','여'만 기록 가능한데, '남자'라는 조건 외 값이 들어와 에러발생
-- ** CHECK 제약조건은 범위로도 설정 가능
-- CHECK(COL1 0 > AND COL1 < 10);
SUBQUERY를 이용한 테이블 생성
컬럼명, 데이터 타입, 값이 복사되고, 제약조건은 NOT NULL만 복사됨
1) 테이블 전체 복사
CREATE TABLE EMPLOYEE_COPY
AS SELECT * FROM EMPLOYEE;
--> 서브쿼리의 조회 결과(RESULT SET)의 모양대로 테이블이 생성됨
2) JOIN 후 원하는 컬럼만 테이블로 복사
CREATE TABLE EMPLOYEE_COPY2
AS
SELECT EMP_NAME, EMP_ID, DEPT_TITLE, JOB_NAME
FROM EMPLOYEE
LEFT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
JOIN JOB USING (JOB_CODE);
SELECT * FROM EMPLOYEE_COPY2;
--> 서브쿼리로 테이블 생성시
-- 테이블의 형태(컬럼명, 데이터타입) + NOT NULL 제약조건만 복사!
-- 제약조건, 코멘트는 복사되지 않기 때문에 별도 추가 작업이 필요하다.
ALTER TABLE 테이블명 ADD [CONSTEAINT 제약조건명] PRIMARY KEY (컬럼명)
ALTER TABLE 테이블명 ADD [CONSTEAINT 제약조건명] FOREIGN KEY (컬럼명)
..................................................................................REFERENCES 참조테이블명(탐조컬럼명)
ALTER TABLE 테이블명 ADD [CONSTEAINT 제약조건명] UNIQUE (컬럼명)
ALTER TABLE 테이블명 ADD [CONSTEAINT 제약조건명] CHECK (컬럼명 비교연산자 비교값)