[INDEX]
- index는 검색을 빠르게 하기 위한 수단이다.
- Primary Key와 Unique Key가 지정되면 따로 index가 생성된다
- 장점
- 검색속도가 빨라진다.
- 시스템의 부하를 줄여 성능이 향상된다.
- 단점
- 인덱스 생성에 시간과 공간이 필요하다.
- 삽입/갱신/삭제 가 빈번히 일어날 경우 성능 저하
- index가 필요한 경우
- 데이터가 많을 경우
- JOIN이 많이 사용된 경우
- index가 불필요한 경우
- 데이터가 적을경우
- 삽입/갱신/삭제 가 빈번히 일어날 경우
CREATE BITMAP INDEX emp_idx_depno ON employees(email);
CREATE UNIQUE INDEX emp_idx_ename ON emp(ename);
CREATE INDEX emp_idx_ename ON emp(ename);
CREATE INDEX emp_combi ON emp(ename,job);
SELECT * FROM USER_INDEXES;
SELECT index_name, index_type, table_owner, uniqueness FROM USER_INDEXES;
DROP INDEX EMP_IDX_ENAME;
1) 비트맵 index
- CREATE BITMAP INDEX [index 이름] ON [테이블명](컬럼명)
- 각 컬럼에 대해서 적은 종류의 독특한 값이 있을 경우 사용하는 것이 좋다.(남|여, true|false)
- 데이터가 어디있는지 BIT로 표기 해준다.
- 컬럼이 추가되면 익덱스를 다시 만들어야한다.
- 테이블이 매우 크거나 수정/변경이 잘 일어나지 않는 경우 사용
- bitmap index는 Standard Edition에서만 동작된다.
2) UNIQUE index
- CREATE UNIQUE INDEX [index 이름] ON [테이블명](컬럼명)
- PK & Unique key가 걸려있으면 자동으로 생성된다.
- 중복되지 않는 데이터를 인덱스 키값으로 지정한다.
- 인덱스를 지정할 컬럼에 중복된 값이 들어있으면 아래와 같은 오류 메세지
- 01452. 00000 - "cannot CREATE UNIQUE INDEX; duplicate keys found"
3) NON-UNIQUE index
- CREATE INDEX [index 이름] ON [테이블명](컬럼명)
- 컬럼에 중복을 허용하는 인덱스
4) 결합 인덱스
- CREATE UNIQUE INDEX [index 이름] ON [테이블명](컬럼명1,컬럼명2,...)
- 복수개의 컬럼을 합쳐서 하나의 인덱스를 만들 수 있다.(최대 16개)
- 중복허용을 하고 싶으면 UNIQUE를 제거한다.
[VIEW]
- 뷰는 기본적으로 읽기전용이다.
- 뷰는 하나의 가상테이블이라 생각하면 된다.
- DB의 특정공간을 사용하기 때문에 많이 사용하지 않으면 안만드는 것이 좋다.
- 특정 컬럼들만 뽑아서 보여지기 때문에 보안성은 좋다.
- 뷰는 복잡한 쿼리를 통해 얻을 수 있는 결과를 간단한 쿼리로 얻을 수 있게 한다.
- 한개의 뷰로 여러 테이블에 대한 데이터를 검색 할 수 있다.
1) 뷰의 제한 조건
- 테이블 데이터에 NULL이 있으면 안된다.(뷰에 포함 될 수 없다.)
- WITH READ ONLY 옵션을 설정한 뷰는 데이터를 갱신 할 수 없다.
- WITH CHECK OPTION을 설정한 뷰는 뷰의 조건에 해당되는 데이터만 수정가능
- 하지만 ROWID, ROWNUM, NEXTVAL, CURRVAL 등과 같은 가상 컬럼에 대한 참조를 포함하는 뷰는
어떠한 데이터도 INSERT 불가
CREATE OR REPLACE VIEW vw_name_lmj AS
SELECT e.ename,d.depname FROM emp e, dept d WHERE e.depno=d.depno;
CREATE OR REPLACE VIEW vw_checkopt AS
SELECT ename,job,depno FROM emp WHERE depno=1 WITH CHECK OPTION;
UPDATE vw_checkopt SET job='manager' WHERE ename='lee';
UPDATE vw_checkopt SET depno=2 WHERE ename='lee';
CREATE OR REPLACE VIEW read_only AS
SELECT ename, job, depno FROM emp WHERE depno=2 WITH READ ONLY;
SELECT * FROM read_only;
UPDATE read_only SET ename='ahn' WHERE job='staff';
SELECT * FROM user_views;
SELECT VIEW_NAME, TEXT FROM user_views;
DROP VIEW VW_NAME_LMJ;
2) 뷰 생성
- CREATE [OR REPLACE] [FORCE|NONFORCE] VIEW [VIEW 이름] AS [sub-query]
WHERE 조건 [WITH CHECK OPTION | WITH READ ONLY]
- CREATE VIEW : 뷰를 다시만든다거나 뷰의 구조를 변경해야 할 경우 다 지우고 다시 만든다.
- OR REPLACE : 같은 이름의 뷰가 있을 경우 기존 뷰를 갱신한다.
- FORCE : 기본 테이블 유무에 상관없이 VIEW 생성 (안써주면 기존 테이블에서 값 가져옴)
- 뷰 생성시 `ORA-01031: 권한이 불충분합니다` 이러한 에러가 나면 SYS에서 권한부여 해줘야한다.
(GRANT CREATE VIEW TO C##web_user;)
3) WITH CHECK OPTION
- 뷰를 생성하는 조건식을 만족하는 컬럼은 UPDATE할 수 없다.(수정할 수 없다)
4) WITH READ ONLY
- SELECT만 가능한 VIEW
[SEQUENCE]
- 유일값(unique)을 생성해주는 오라클 객체이다.
- 시퀀스를 생성하면 절대로 중복되지 않는 증가 값을 얻게 된다.
- 보통 PK 생성을 위해서 사용된다.
- 테이블에 종속되지 않아 독립적으로 생성 저장된다.
- 메모리에 cache되었을때 액세스 효율이 증가된다.
CREATE SEQUENCE seq_empno;
SELECT seq_empno.NEXTVAL FROM DUAL;
SELECT seq_empno.CURRVAL FROM DUAL;
1) SEQUENCE 생성
- CREATE SEQUENCE [시퀀스 name] / 일반적인 시퀀스, 아래내용은 옵션
- [START WITH n] [INCREMENT BY n]
- [MAXVALUE n | NOMAXVALUE] [MINVALUE n | NOMINVALUE]
- [CYCLE | NOCYCLE] [CACHE|NOCACHE]
2) 해당 시퀀스 확인
- NEXTVAL은 현재보다 +1
- CURRVAL은 현재이기 때문에 NEXTVAL실행 없이 최초로 사용할 경우 오류난다.
CREATE SEQUENCE seq_start START WITH 8000 INCREMENT BY 1 CACHE 20;
CREATE SEQUENCE seq_max MAXVALUE 10;
CREATE SEQUENCE seq_cycle MAXVALUE 10 CYCLE CACHE 5;
CREATE SEQUENCE seq_min START WITH 5 MINVALUE 5 MAXVALUE 10 CYCLE CACHE 5;
3) [START WITH n] [INCREMENT BY n]
- START WITH : 시퀀스의 시작값, n을 8000으로 지정하면 8000부터 순차 증가
- INCREMENT BY : 증가하는 수 (default :1)
4) MAX 옵션
- 시퀀스 최대값 지정
- 최대값 지정시 최대값을 넘어가면 오류 발생
5) CYCLE 옵션
- 최대값 도달시 순환여부
- CYCLE을 줄 경우 돌아갈 수를 미리 기억하도록 캐시설정이 들어가야한다.
- CACHE : 원하는 숫자 만큼 미리 만들어서 캐시에 상주 시킨다.
6) MIN 옵션
- 지정안하면 1, 시작값이 최소값보다 작으면 오류발생
- 단독적으로 쓰이는 것 보다는 MAX가 있고 CYCLE로 다시 돌아갈때의 MINVALUE로 최소값을 정해준다.
ALTER TABLE emp ADD (emp_no NUMBER(5));
INSERT INTO emp(emp_no,ename,job,depno,hiredate)
VALUES(seq_empno.NEXTVAL ,'tiger','manager',3,SYSDATE);
SELECT * FROM USER_SEQUENCES;
ALTER SEQUENCE seq_empno INCREMENT BY 10 CACHE 40;
DROP SEQUENCE SEQ_MAX;
7) 실제 SEQUENCE 사용 예시
- 테이블에 데이터 삽입시에 시퀀스를 넣어서 해당 데이터를 유일값으로 생성해준다.
[Function]
1. 집계함수
SELECT COUNT(depno) AS 팀수 FROM dept;
SELECT MAX(commission) FROM employees;
SELECT MIN(commission) FROM employees;
SELECT AVG(salary) FROM employees;
SELECT SUM(salary) FROM employees WHERE commission=10;
1. 집계함수 : 여러행 또는 테이블 전체 행으로부터 하나의 결과값을 반환하는 함수
- GROUP BY 시 노출되는 컬럼 -> 공통으로 묶여지는 컬럼, 집계함수를 사용하여 추출한 내용
2. 문자열(**CHAR) 타입을 다루는 함수
SELECT CONCAT('www.','oracle')||'.com' AS url FROM DUAL;
SELECT INITCAP('oracleclub') FROM DUAL UNION ALL
SELECT LOWER('OracleClub') FROM DUAL UNION ALL
SELECT UPPER('oracleclub') FROM DUAL;
SELECT LPAD('oracleclub',12,'*') AS pass FROM DUAL;
SELECT RPAD('oracleclub',12,'*') AS pass FROM DUAL;
SELECT RPAD('oracleclub',8,'*') AS pass FROM DUAL;
SELECT SUBSTR('oracleclub',3) AS title FROM DUAL;
SELECT SUBSTR('oracleclub',3,4) AS title FROM DUAL;
SELECT SUBSTR('oracleclub',-3,2) AS title FROM DUAL;
SELECT SUBSTRB('oracleclub',2) AS title FROM DUAL;
SELECT SUBSTRB('오라클클럽',2) AS title FROM DUAL;
1) CONCAT(char1, char2) :문자열을 합치는 함수
3) LPAD(char1,n,[char2]), RPAD(char1,n,[char2])
- LPAD : 왼쪽에 문자를 끼워 넣는 역할
- RPAD : 오른쪽에 문자를 끼워 넣는 역할
- n은 반환되는 문자열의 전체 길이,
- char1의 문자열이 n보다 클 경우 char1을 n개의 문자열만큼만 반환(뒤부터 잘림)
- 특정한 규칙에 의해서 자릿수를 맞춰야 할 경우에도 사용
4) SUBSTR(char,m,n), SUBSTRD(char,m,n)
- SUBSTR : m번째 자리부터 길이가 n개인 문자열을 반환한다. n을 안쓰면 끝까지 보여줌
- m이 음수일 경우 뒤에서 m번째 문자열부터 n개의 문자열을 반환.
- SUBSTRB : B는 Byte를 의미한다. Byte단위로 처리하겠다.
- DB는 INDEX가 1부터 시작
SELECT LENGTH('오라클클럽') AS title FROM DUAL UNION ALL
SELECT LENGTHB('오라클클럽') AS title FROM DUAL;
SELECT REPLACE('oracleclub','oracle','DB') AS title FROM DUAL;
SELECT REPLACE('OracleClub','oracle','DB') AS title FROM DUAL;
SELECT REPLACE('OracleClub','Oracle','DB') AS title FROM DUAL;
SELECT INSTR('CORPORATE FLOOR','OK') AS idx FROM DUAL;
SELECT INSTR('CORPORATE FLOOR','OR') AS idx FROM DUAL;
SELECT INSTR('CORPORATE FLOOR','OR',3) AS idx FROM DUAL;
SELECT INSTR('CORPORATE FLOOR','OR',3,2) AS idx FROM DUAL;
SELECT TRIM('o' FROM 'oracleclub') AS title FROM DUAL;
SELECT TRIM(' oracleclub ') AS title FROM DUAL;
SELECT LTRIM('oracleclub','oracle') AS title FROM DUAL;
SELECT LTRIM(' oracleclub ') AS title FROM DUAL;
SELECT RTRIM('oracleclub','club') AS title FROM DUAL;
SELECT RTRIM(' oracleclub ') AS title FROM DUAL;
5) LENGTH(char), LENGTHB(char) : 길이 반환
6) REPLACE(char1, src,dst)
- 문자열 char1에서 src를 dst로 바꿈
- 대소문자 구분한다.
7) INSTR(char1,str1,m,n)
- 문자열이 포함되어 잇는지 조사하여 위치를 반환
- 지정된 문자열이 없으면 0을 반환
- char1: 대상 문자열 , str1 : 찾을 문자열
- m : 시작위치 , n : 시작위치에서 n번째 발견되는 놈
8) TRIM(char1 FROM char2)
- 특정한 문자열을 제거 하는데 사용한다.
- 만약에 제거할 문자를 명시하지 않으면 공백이 제거된다.
9) LTRIM(char1,char2) : 지정한 문자열이 대상문자열을 왼쪽부터 제거 (반복되는 문자도 제거)
10) RTRIM(char1,char2) : 지정한 문자열이 대상문자열을 오른쪽부터 제거 (반복되는 문자도 제거)
3. DateTime Functions(시간과 날짜를 다루는 함수)
SELECT to_char(SYSDATE,'YYYY-MM-DD HH24:MI:SS') AS 현재시간 FROM DUAL;
SELECT to_char(SYSDATE-1,'YYYY-MM-DD HH24:MI:SS') AS 하루전시간 FROM DUAL;
SELECT to_char(SYSDATE-1/24,'YYYY-MM-DD HH24:MI:SS') AS "1시간전" FROM DUAL;
SELECT to_char(SYSDATE-1/24/60,'YYYY-MM-DD HH24:MI:SS') AS "1분전" FROM DUAL;
SELECT to_char(SYSDATE-(5/24 + 30/24/60 + 10/24/60/60),'YYYY-MM-DD HH24:MI:SS')
AS "5시간30분10초전" FROM DUAL;
SELECT to_char(SYSTIMESTAMP,'YYYY-MM-DD HH24:MI:SS.FF9') AS 현재시간 FROM DUAL;
SELECT to_char(SYSTIMESTAMP-1/24,'YYYY-MM-DD HH24:MI:SS') AS "1시간전" FROM DUAL;
SELECT to_char(SYSTIMESTAMP-1/24/60,'YYYY-MM-DD HH24:MI:SS') AS "1분전" FROM DUAL;
SELECT ADD_MONTHS(SYSDATE,3) AS "3달후" FROM DUAL;
SELECT ADD_MONTHS(SYSTIMESTAMP,3) AS "3달후" FROM DUAL;
SELECT MONTHS_BETWEEN(TO_DATE('2021-05-10', 'YYYY-MM-DD'),
TO_DATE('2021-02-03','YYYY-MM-DD')) AS "date" FROM DUAL;
SELECT TO_DATE('2021-05-10', 'YYYY-MM-DD') - TO_DATE('2021-02-03','YYYY-MM-DD')
AS "DAY" FROM DUAL;
SELECT LAST_DAY(SYSDATE) AS lasyday FROM DUAL;
SELECT NEXT_DAY(SYSDATE,1) "NEXT WENDSEDAY" FROM DUAL;
SELECT NEXT_DAY(TO_DATE('2021/03/01','YYYY/MM/DD'),2) "3월 둘째주 월요일" FROM DUAL;
4. numberic 함수
SELECT ABS(-1.234) AS absolute FROM DUAL;
SELECT CEIL(10.1234) FROM DUAL;
SELECT CEIL(-10.1234) FROM DUAL;
SELECT FLOOR(10.1234) FROM DUAL;
SELECT FLOOR(-10.1234) FROM DUAL;
SELECT ROUND(15.193,1) FROM DUAL;
SELECT ROUND(15.193) FROM DUAL;
SELECT TRUNC(789.5597,2) FROM DUAL;
SELECT TRUNC(789.5597,-2) FROM DUAL;
SELECT MOD(9,4) FROM DUAL;