-- 테이블에서 수정할 수 있는 것
1. 제약 조건(추가/삭제) -- 수정이 안돼서 수정하려면 삭제하고 추가
2. 컬럼(추가/수정/삭제) -- 가능은 하나 웬만하면 처음부터 잘 짓기
3. 이름변경 (테이블명, 컬럼명..)
-- [작성법]
-- 1) 추가 : ALTER TABLE 테이블명
-- ADD [CONSTRAINT 제약조건명] 제약조건(지정할컬럼명)
-- [REFERENCES 테이블명[(컬럼명)]]; <-- FK 인 경우 추가
-- 2) 삭제 : ALTER TABLE 테이블명 DROP CONSTRAINT 제약조건명;
-- * 제약조건 자체를 수정하는 구문은 별도 존재하지 않음!
--> 삭제 후 추가를 해야함.
-- DEPARTMENT 테이블 복사 (컬럼명, 데이터타입, NOT NULL만 복사) CREATE TABLE DEPT_COPY AS SELECT * FROM DEPARTMENT; SELECT * FROM DEPT_COPY; -- DEPT_COPY의 DEPT_TITLE 컬럼에 UNIQUE 추가 ALTER TABLE DEPT_COPY ADD CONSTRAINT DEPT_COPY_TITLE_U UNIQUE(DEPT_TITLE); -- DEPT_COPY의 DEPT_TITLE 컬렘에 UNIQUE 삭제 ALTER TABLE DEPT_COPY DROP CONSTRAINT DEPT_COPY_TITLE_U; -- 오라클에서 지어준 랜덤이름은 찾아서 삭제해줘야 함 -- *** DEPT_COPY의 DEPT_TITLE 컬럼에 NOT NULL 제약조건 추가 / 삭제 *** ALTER TABLE DEPT_COPY ADD CONSTRAINT DEPT_COPY_TITLE_NN NOT NULL(DEPT_TITLE); --> NOT NULL 제약조건은 새로운 조건을 추가하는 것이 아닌 -- 컬럼 자체에 NULL을 허용 / 비허용을 제어하는 성질 변경의 형태로 인식됨. -- MODIFY (수정하다) 구문을 사용해서 NULL 제어 ALTER TABLE DEPT_COPY MODIFY DEPT_TITLE NOT NULL; -- DEPT_TITLE 컬럼에 NOT NULL 작용 ALTER TABLE DEPT_COPY MODIFY DEPT_TITLE NULL; -- DEPT_TITLE 컬럼에 NULL 허용
-- 컬럼 추가
-- ALTER TABLE 테이블명 ADD(컬럼명 데이터타입 [DEFAULT '값']);
-- 컬럼 수정
-- ALTER TABLE 테이블명 MODIFY 컬럼명 데이터타입; --> 데이터 타입 변경
-- ALTER TABLE 테이블명 MODIFY 컬럼명 DEFAULT '값'; --> DEFAULT 값 변경
-- 컬럼 삭제
-- ALTER TABLE 테이블명 DROP (삭제할컬럼명);
-- ALTER TABLE 테이블명 DROP COLUMN 삭제할컬럼명;
-- CNAME 컬럼 추가 ALTER TABLE DEPT_COPY ADD (CNAME VARCHAR2(30)); -- 새로 추가한 컬럼에 있는 값은 NULL -- LNAME 컬럼 추가 (기본값 '한국') ALTER TABLE DEPT_COPY ADD (LNAME VARCHAR2(30) DEFAULT '한국'); --> 컬럼이 생성되면서 DEFAULT 값이 자동 삽입되어있음 -- D10 개발 1팀 추가 INSERT INTO DEPT_COPY VALUES('D10', '개발1팀', 'L1', NULL, DEFAULT); -- ORA-12899: "KH"."DEPT_COPY"."DEPT_ID" 열에 대한 값이 너무 큼(실제: 3, 최대값: 2) --> DEPT_ID의 데이터타입이 CHAR(2) 이므로 영어+숫자 2글자까지 저장 가능 --> D10은 3바이트. CHAR(2) 들어올 수 없음 --> VARCHAR2(3)으로 변경해보기 (남는 바이트 메모리 반환 위해!) -- DEPT_ID 컬럼 데이터 타입 수정 ALTER TABLE DEPT_COPY MODIFY DEPT_ID VARCHAR2(3) --> 컬럼 데이터 타입 수정 후 다시 위 INSERT 실행 -> 삽입 성공 확인!
-- LNAME의 기본값을 'KOREA' 로 수정 ALTER TABLE DEPT_COPY MODIFY LNAME DEFAULT 'KOREA'; -- 오류 --> !! 기본값을 변경했다고 해서 기존 데이터가 변하지는 않음! --> 앞으로 INSERT 될 데이터만 변경된 내용으로 삽입됨. -- LNAME '한국' -> 'KOREA' 변경 UPDATE DEPT_COPY SET LNAME = DEFAULT WHERE LNAME = '한국'; -- DEPT_COPY 모든 컬럼 삭제 ALTER TABLE DEPT_COPY DROP (LNAME); -- LNAME 컬럼 사라짐 ALTER TABLE DEPT_COPY DROP COLUMN CNAME; -- CNAME 컬럼도 사라짐 ALTER TABLE DEPT_COPY DROP COLUMN LOCATION_ID; -- 사라짐.. ALTER TABLE DEPT_COPY DROP COLUMN DEPT_TITLE; -- 사라짐..
ALTER TABLE DEPT_COPY DROP COLUMN DEPT_ID; -- 오류 뜨며 삭제 안됨!! -- 왜냐하면? -- 컬럼 삭제 시 유의사항! -- 테이블이란, 행과 열로 이루어진 DB의 가장 기본적인 객체. -- 그러므로 최소 1개 이상의 컬럼이 존재해야하기 때문에 -- 모든 컬럼을 다 삭제할 순 없다! -- 테이블 삭제 DROP TABLE DEPT_COPY; -- 테이블 삭제됨! SELECT * FROM DEPT_COPY; -- ORA-00942: 테이블 또는 뷰가 존재하지 않습니다 -- DEPARTMENT 테이블 복사해서 DEPT_COPY 생성 CREATE TABLE DEPT_COPY AS SELECT * FROM DEPARTMENT; --> 컬럼명, 데이터타입, NOT NULL 여부만 복사 -- DEPT_COPY 테이블에 PK 추가 -- (컬럼 : DEPT_ID, 제약조건명 : D_COPY_PK) ALTER TABLE DEPT_COPY ADD CONSTRAINT D_COPY_PK PRIMARY KEY(DEPT_ID);
-- 1) 컬럼명 변경 (DEPT_TITLE -> DEPT_NAME) RENAME 변경할거 변경할거이름 TO 변경될이름 ALTER TABLE DEPT_COPY RENAME COLUMN DEPT_TITLE TO DEPT_NAME;
SELECT * FROM DEPT_COPY; -- 2) 제약조건명 변경 (D_COPY_PK -> DEPT_COPY_PK) ALTER TABLE DEPT_COPY RENAME CONSTRAINT D_COPY_PK TO DEPT_COPY_PK;
-- 3) 테이블명 변경 (DEPT_COPY -> DCOPY) ALTER TABLE DEPT_COPY RENAME TO DCOPY; SELECT * FROM DEPT_COPY; -- ORA-00942: 테이블 또는 뷰가 존재하지 않습니다. SELECT * FROM DCOPY;
-- DROP TABLE 테이블명 [CASCADE CONSTRAINTS];
-- 제약조건이 걸려있어 관계형성이 되어있는 테이블 삭제 방법임.
-- 1) 관계가 형성되지 않은 테이블 삭제 DROP TABLE DCOPY; -- ORA-00942: 테이블 또는 뷰가 존재하지 않습니다 -- 2) 관계가 형성된 테이블 삭제 CREATE TABLE TB1( TB1_PK NUMBER PRIMARY KEY, TB1_COL NUMBER ); -- 부모 테이블 SELECT * FROM TB1; CREATE TABLE TB2( TB2_PK NUMBER PRIMARY KEY, TB2_COL NUMBER REFERENCES TB1 --() 자동참조 해주면 알아서 PRIMARY KEY로! ); -- 자식 테이블 SELECT * FROM TB2; -- TB1에 샘플 데이터 삽입 INSERT INTO TB1 VALUES(1, 100); INSERT INTO TB1 VALUES(2, 200); INSERT INTO TB1 VALUES(3, 300); -- TB2에 샘플 데이터 삽입 INSERT INTO TB2 VALUES(11, 1); INSERT INTO TB2 VALUES(12, 2); INSERT INTO TB2 VALUES(13, 3); COMMIT; -- TB1과 TB2는 부모-자식 테이블 관계 형성된 상태 -- 부모인 TB1 테이블을 삭제하려고 할 때 DROP TABLE TB1; -- ORA-02449: 외래 키에 의해 참조되는 고유/기본 키가 테이블에 있습니다 -- 너 자식테이블 있어서 삭제 못해! --> 해결 방법 -- 1) 자식을 먼저 없앤 후 부모 삭제 -- 2) ALTER 를 이용해서 FK 제약조건 삭제 후 TB1(부모) 삭제 -- 3) DROP TABLE 삭제옵션 CASCADE CONSTRAINTS 사용 --> CASCADE DONSTRAINTS : 삭제하려는 테이블과 연결된 FK 제약조건을 모두 삭제 DROP TABLE TB1 CASCADE CONSTRAINTS; -- 테이블 삭제 시 FK관계도 모두 삭제 SELECT * FROM TB1; -- ORA-00942: 테이블 또는 뷰가 존재하지 않습니다 SELECT * FROM TB2; -- TB2 테이블만 아무 관계없이 남게 됨.
/* DDL 주의 사항 */
-- 1. DDL은 COMMIT / ROLLBACK 이 되지 않는다.
-- 2. DDL과 DML 구문 섞어서 수행하면 안된다!
-- DDL(CREATE, ALTER, DROP : 객체 생성/수정/삭제)
-- DML(INSERT, UPDATE, DELETE : 데이터(행) 추가/갱신/삭제)
--> DDL은 수행 시 존재하고 있는 트랜잭션을 모두 DB에 강제 COMMIT 시킴
--> DDL이 종료된 후 DML 구문을 수행할 수 있도록 권장!
COMMIT; -- EX) -- DML (INSERT) INSERT INTO TB2 VALUES(14, 4); INSERT INTO TB2 VALUES(15, 5); -- DDL (컬럼명 변경) ALTER TABLE TB2 RENAME COLUMN TB2_COL TO TB2_COLUMN; -- 강제커밋 ROLLBACK; -- ROLLBACK 안됨 ( 14,4 15,5 롤백안됨!!) --> 위에서 DDL 구문 중 ALTER를 사용해서 -- 그 시점에 강제 COMMIT 되었기 때문에!!
논리적 가상 테이블
-> 테이블 모양을 하고는 있지만, 실제로 값을 저장하고 있진 않음.
SELECT문의 실행 결과(RESULT SET)를 저장하는 객체
VIEW 사용 목적
VIEW 사용 시 주의 사항
- VIEW 작성법
CREATE [OR REPLACE] [FORCE | NOFORCE] VIEW 뷰이름 [컬럼 별칭]
AS 서브쿼리(SELECT문)
[WITH CHECK OPTION]
[WITH READ OLNY];
1) OR REPLACE 옵션 :
기존에 동일한 이름의 VIEW가 존재하면 이를 변경
없으면 새로 생성
2) FORCE | NOFORCE 옵션 :
FORCE : 서브쿼리에 사용된 테이블이 존재하지 않아도 뷰 생성
NOFORCE(기본값): 서브쿼리에 사용된 테이블이 존재해야만 뷰 생성
3) 컬럼 별칭 옵션 : 조회되는 VIEW의 컬럼명을 지정
4) WITH CHECK OPTION 옵션 :
옵션을 지정한 컬럼의 값을 수정 불가능하게 함.
5) WITH READ OLNY 옵션 :
뷰에 대해 SELECT만 가능하도록 지정.
VIEW 를 생성하기 위해서는 권한이 필요하다! -- (SYS 관리자 계정 접속) ALTER SESSION SET "_ORACLE_SCRIPT" = TRUE; --> 계정명이 언급되는 상황에서는 이 구문 필수적으로 진행! -- C## 안 붙이겠다. -- VIEW 생성 권한 부여 GRANT CREATE VIEW TO kh; CREATE VIEW V_EMP AS SELECT * FROM EMPLOYEE; -- ORA-01031: 권한이 불충분합니다. (SYS관리자 계정 접속 전!!) -- 위 구문 마치고 다시 kh로 돌아와서 구문 실행! --> VIEW 생성 구문 기초 문법!!! SELECT * FROM V_EMP; -- 사번, 이름, 부서명, 직급명 조회하기 위한 VIEW 생성 CREATE OR REPLACE VIEW V_EMP AS SELECT EMP_ID 사번, EMP_NAME 이름, NVL(DEPT_TITLE, '없음') 부서명, JOB_NAME 직급명 FROM EMPLOYEE JOIN JOB USING (JOB_CODE) LEFT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID) ORDER BY 사번 ASC; -- ORA-00955: 기존의 객체가 이름을 사용하고 있습니다. -- -> 오류를 고치기 위해 위에 CREATE OR RELACE VIEW로 바꿔줌
-- V_EMP에서 대리 직원들을 이름 오른차순으로 조회 -- VIEW 조회 결과로 보이는 컬럼명을 이용해야 한다!! SELECT * FROM V_EMP -- 현재 상태가 위에서 바꿔놓은 형태임 WHERE 직급명 = '대리' ORDER BY 이름;
/* VIEW를 이용해서 DML 사용하기 + 문제점 확인 */ -- DEPARTMENT 테이블을 복사한 DEPT_COPY2 생성(테이블로 생성 VIEW 말고 ㅋㅋ) CREATE TABLE DEPT_COPY2 AS SELECT * FROM DEPARTMENT; -- DEPT_COPY2 테이블에서 DEPT_ID, LOCATION_ID 컬럼만 이용해서 -- V_DCOPY2 VIEW 생성 CREATE OR REPLACE VIEW V_DCOPY2 AS SELECT DEPT_ID, LOCATION_ID FROM DEPT_COPY2; -- V_DCOPY2 VIEW 생성 확인하기 SELECT * FROM V_DCOPY2;
-- 원본 테이블 SELECT * FROM DEPT_COPY2; -- V_DCOPY2 VIEW를 이용해서 INSERT 수행 INSERT INTO V_DCOPY2 VALUES ('D0', 'L2'); -- 가상 테이블인 VIEW 인데도 INSERT가 성공함! SELECT * FROM DEPT_COPY2; -- D0, NULL, L2 삽입
-- VIEW에 INSERT를 수행했지만 -- VIEW 생성 시 사용한 원본 테이블에도 -- 값이 함께 INSERT 됨을 확인!! --> 모든 컬럼 값이 INSERT 된 것이 아니라 -- VIEW를 생성할 때 사용된 컬럼에만 데이터가 삽입 되었고 -- 사용되지 않은 컬럼(DEPT_TITLE)에는 NULL이 들어감! --> NULL은 DB의 무결성을 약하게 만드는 주요 원인이다! --> 그러므로 가능하면 의도되지 않은 NULL은 존재하지 않게 해야 한다. -->> 찐막으로 VIEW를 이용한 DML은 사용을 지양한다!!!! /* 무결성 : 데이터베이스에서 데이터를 정확하고 일관되게 * 유지하기 위한 중요한 개념. * * 데이터의 정확성, 일관성, 신뢰성을 보장함. */ /* WITH READ ONLY 옵션 사용하기 */ -- 왜 사용할까? --> VIEW를 이용해서 DML(INSER/UPDATE/DELETE)을 막기 위해서! CREATE OR REPLACE VIEW V_DCOPY2 AS SELECT DEPT_ID, LOCATION_ID FROM DEPT_COPY2 WITH READ ONLY; -- 수행하면 읽기 전용 -- INSERT 수행 INSERT INTO V_DCOPY2 VALUES ('D0', 'L3'); -- ORA-42399: 읽기 전용 뷰에서는 DML 작업을 수행할 수 없습니다.
*** SEQUENCE 왜 사용할까?? ***
PRIMARY KEY(기본키) : 테이블 내 각 행을 구별하는 식별자 역할
NOT NULL + UNIQUE의 의미를 가짐
PK가 지정된 컬럼에 삽입될 값을 생성할 때 SEQUENCE를 이용하면 좋다!
[작성법]
CREATE SEQUENCE 시퀀스이름
[START WITH 숫자] -- 처음 발생시킬 시작값 지정, 생략하면 1이 기본
[INCREMENT BY 숫자] -- 다음 값에 대한 증가치, 생략하면 1이 기본
[MAXVALUE 숫자 | NOMAXVALUE] -- 발생시킬 최대값 지정, 생략하면 기본값은 10^27 - 1 (즉, 매우 큰 값)입니다 / NOMAXVALUE를 사용하면 최대값 제한이 없음을 의미
[MINVALUE 숫자 | NOMINVALUE] -- 최소값 지정 , 기본값은 -10^26 / NOMINVALUE를 사용하면 최소값 제한이 없음을 의미
[CYCLE | NOCYCLE] -- 값 순환 여부 지정 , 기본값은 NOCYCLE
-- CYCLE: 값이 최대값에 도달하면 다시 최소값부터 순환
-- NOCYCLE: 값을 순환하지 않고, 최대값에 도달하면 오류를 발생시킴
[CACHE 시퀀스개수 | NOCACHE] -- 기본값은 20
-- 시퀀스의 캐시 메모리는 할당된 크기만큼 미리 다음 값들을 생성해 저장해둠
--> 시퀀스 호출 시 미리 저장되어진 값들을 가져와 반환하므로
-- 매번 시퀀스를 생성해서 반환하는 것보다 DB속도가 향상됨.
** 사용법 **
1) 시퀀스명.NEXTVAL : 다음 시퀀스 번호를 얻어옴.
(INCREMENT BY 만큼 증가된 수)
단, 생성 후 처음 호출된 시퀀스인 경우
START WITH에 작성된 값이 반환됨.
2) 시퀀스명.CURRVAL : 현재 시퀀스 번호를 얻어옴.
단, 시퀀스가 생성 되자마자 호출할 경우 오류 발생.
== 마지막으로 호출한 NEXTVAL 값을 반환
시퀀스 생성하기 CREATE SEQUENCE SEQ_TEST_NO START WITH 100 -- 시작번호 100 INCREMENT BY 5 -- NEXTVAL 호출 후 5씩 증가 MAXVALUE 150 -- 증가 가능한 최대값이 150 NOMINVALUE -- 최소값 없음 NOCYCLE -- 반복 안함 NOCACHE; -- 미리 만들어둘 시퀀스 번호 없음
시퀀스 삭제하기 DROP SEQUENCE SEQ_TEST_NO; -- 시퀀스 테스트할 테이블 생성 CREATE TABLE TB_TEST( TEST_NO NUMBER PRIMARY KEY, TEST_NAME VARCHAR2(30) NOT NULL );-- 현재 시퀀스 번호 확인 SELECT SEQ_TEST_NO.CURRVAL FROM DUAL; -- ORA-08002: 시퀀스 SEQ_TEST_NO.CURRVAL은 이 세션에서는 정의 되어 있지 않습니다. --> CURRVAL의 정확한 의미는 -- 가장 최근 호출된 NEXTVAL의 값을 반환함을 뜻함 --> NEXTVAL을 호출한 적이 없어서 오류 발생! --> 해결방법 : NEXTVAL 호출하기 SELECT SEQ_TEST_NO.NEXTVAL FROM DUAL; -- 시퀀스 생성 후 첫 NEXTVAL == START WITH 값인 100
SELECT SEQ_TEST_NO.CURRVAL FROM DUAL; -- 100 -- 가장 최근 호출한 NEXTVAL 값이 100이니까!
-- NEXTVAL 을 호출할 때마다 -- INCREMENT BY 에 작성된 수만큼 증가하는지 확인 SELECT SEQ_TEST_NO.NEXTVAL FROM DUAL; -- 처음 : 100 -- 1회 : 105 -- 2회 : 110 -- TB_TEST 테이블에 PK값을 SEQ_TEST_NO 시퀀스로 생성하기 INSERT INTO TB_TEST VALUES (SEQ_TEST_NO.NEXTVAL, '짱구'); -- 125 INSERT INTO TB_TEST VALUES (SEQ_TEST_NO.NEXTVAL, '철수'); -- 130 INSERT INTO TB_TEST VALUES (SEQ_TEST_NO.NEXTVAL, '유리'); -- 135
-- UPDATE 에서 시퀀스 사용하기 -- '짱구'의 PK 컬럼값을 -- SEQ_TEST_NO 시퀀스의 다음 생성값으로 변경하기 UPDATE TB_TEST SET TEST_NO = SEQ_TEST_NO.NEXTVAL WHERE TEST_NAME = '짱구'; -- ORA-08004: 시퀀스 SEQ_TEST_NO.NEXTVAL exceeds MAXVALUES --> MAXVALUE 150 보다 더 증가할 수 없다! SELECT * FROM TB_TEST;
-- SEQUENCE 변경 (ALTER) --> START WITH 빼고 모두 변경 가능!! [작성법] ALTER SEQUENCE 시퀀스이름 [INCREMENT BY 숫자] [MAXVALUE 숫자 | NOMAXVALUE] [MINVALUE 숫자 | NOMINVALUE] [CYCLE | NOCYCLE] [CACHE 숫자 | NOCACHE] -- SEQ_TEST_NO 의 MAXVALUE 값을 200으로 수정 ALTER SEQUENCE SEQ_TEST_NO MAXVALUE 200; -- 200까지 증가 ㅋㅋ -- 200까지 증가 시켜서 변경확인 SELECT SEQ_TEST_NO.NEXTVAL FROM DUAL;
-- VIEW, SEQUENCE 삭제 -- V_DCOPY2 VIEW 삭제 DROP VIEW V_DCOPY2; -- SEQ_TEST_NO SEQUENCE 삭제 DROP SEQUENCE SEQ_TEST_NO;
SQL 구문 중 SELECT 처리 속도를 향상 시키기 위해
컬럼에 대하여 생성하는 객체
인덱스 내부 구조는 B* 트리(B-star tree) 형식으로 되어있음.
[작성법]
CREATE [UNIQUE] INDEX 인덱스명
ON 테이블명 (컬럼명[, 컬럼명 | 함수명]);
DROP INDEX 인덱스명;
이진 트리 형식으로 구성되어 자동 정렬 및 검색 속도 증가.
조회 시 테이블의 전체 내용을 확인하며 조회하는 것이 아닌
인덱스가 지정된 컬럼만을 이용해서 조회하기 때문에
시스템의 부하가 낮아짐.
데이터 변경(INSERT,UPDATE,DELETE) 작업 시 이진 트리 구조에 변형이 일어남
-> DML 작업이 빈번한 경우 시스템 부하가 늘어 성능이 저하됨.
인덱스도 하나의 객체이다 보니 별도 저장공간이 필요(메모리 소비)
인덱스 생성 시간이 필요함.
PK ,FK, UNIQUE 제약조건이 설정된 컬럼에 대해 UNIQUE INDEX가 자동 생성된다.
PK에 자동 생성되는 이유 : 기본 키는 중복을 허용하지 않고, NOT NULL이어야 하기 때문이다.
UNIQUE 제약조건 설정 컬럼에서 자동생성 되는 이유 : 중복을 허용하지 않는 고유 값을 보장해야 하기 때문이다.
SELECT ROWID, EMP_ID, EMP_NAME FROM EMPLOYEE; -- ROWID : 오라클에서 각 행의 고유한 주소를 나타내는 가상 컬럼(물리적 주소) -- 인덱스가 ROWID 저장함. -- 인덱스는 컬럼의 값과 해당행의 ROWID를 매핑해서 저장함. -- 컬럼값 -> 해당 행의 ROWID를 빠르게 찾아낼 수 있다! -- 현재 사용자에 생성된 인덱스 목록 조회 SELECT INDEX_NAME, TABLE_NAME, UNIQUENESS, STATUS FROM USER_INDEXES; -- EMPLOYEE 테이블의 EMP_NAME 컬럼에 인덱스 생성 CREATE INDEX IDX_EMP_NAME ON EMPLOYEE (EMP_NAME); --> EMPLOYEE 테이블의 EMP_NAME 컬럼에 대해 빠른 검색이 가능 /* * 인덱스명 : IDX_EMP_NAME * 테이블명 : EMPLOYEE * 컬럼명 : EMP_NAME * 목적 : EMP_NAME 이용한 컬럼 검색 속도 향상 * */ -- EMPLOYEE 테이블의 EMAIL 컬럼에 UNIQUE INDEX 생성 CREATE UNIQUE INDEX IDX_UNIQUE_EMAIL ON EMPLOYEE (EMAIL); -- UNIQUE INDEX 는 중복 방지 -- EMIAL 컬럼에 중복되지 않는 고유한 값만 허용 --> 중복된 EMAIL 삽입 시 오류 발생!
-- 인덱스 성능 확인용 테이블 생성 CREATE TABLE TB_IDX_TEST ( TEST_NO NUMBER PRIMARY KEY, -- 자동으로 UNIQUE INDEX 생성됨 TEST_ID VARCHAR2(20) NOT NULL ); -- TB_IDX_TEST 테이블에 -- 샘플데이터 100만개 삽입 (PL/SQL 사용) -- * PL/SQL 이란? -- 오라클 데이터베이스에서 사용하는 절차적 확장 언어. -- 변수, 조건문(IF/CASE), 반복문(LOOP, WHILE) 사용 가능 BEGIN FOR I IN 1..1000000 -- I 는 1부터 100만까지 반복 LOOP INSERT INTO TB_IDX_TEST VALUES(I, 'TEST' || I); END LOOP; COMMIT; -- 모든 삽입 작업을 커밋 END; SELECT COUNT(*) FROM TB_IDX_TEST; -- 100만개 행이 삽입됨을 확인 -- 인덱스를 사용해서 검색하는 방법 --> WHERE 절에 INDEX가 적용된 컬럼을 언급하기 /* 인덱스 X */ -- TEST_ID 가 'TEST500000' 인 행 조회하기 SELECT * FROM TB_IDX_TEST WHERE TEST_ID = 'TEST500000'; -- 0.030s /* 인덱스 O */ -- TEST_NO가 500000인 행을 조회하기 SELECT * FROM TB_IDX_TEST WHERE TEST_NO = 500000; -- 0.001s -- 보통 10~30배 차이