##테이블 무결성 제약조건
데이터 무결성 제약 조건(Data Integrity Constraint Rule) 테이블에 부적절한 자료(데이터)가 입력되는 것을 방지하기 위해서 테이블을 생성할 때 각 컬럼에 대해서 정의하는 여러 가지 규칙을 의미.
- Not null/null : null을 허용할 지 아니면 반드시 입력받게 할 건지의 조건.
- Unique : 지정된 컬럼에 중복되지 않고 유일한 값만 저장되는 조건.
- Primary key(기본키) : unique + not null
- Check : 특정한 값만 저장되는 필드 조건.
- Default : 기본값으로 특정 값이 저장되도록 설정하는 조건.
- Foreign key(외래키) : 다른 테이블의 컬럼에 들어있는 값만 저장을 허용하는 조건.
USER_CONSTRAINTS 데이터 딕셔너리 뷰 : 제약 조건에 관한 정보를 알려 줌
- owner : 제약 조건을 소유한 사용자명을 저장하는 컬럼.
- constraint_name : 제약 조건명을 저장하는 컬럼.
- constraint_type : 제약 조건 유형을 저장하는 컬럼.
- P : Primary key
- R : Foreign key
- U : Unique
- C : Check, Not null
- table_name : 각 제약 조건들이 속한 테이블의 이름.
- search_condition : 어떤 내용이 조건으로 사용되었는지 설명.
- r_constraint_name : 제약 조건이 foreign key인 경우 어떤 primary key를 참조했는지에 대한 정보를 갖음.
SQL>desc user_constraints;
SQL>column constraint_type format a15
SQL>select constraint_name, constraint_type, table_name from user_constraints;
user_cons_columns 데이터 딕셔너리 뷰 : 어떤 컬럼에 어떤 제약 조건이 지정되었는지 알려주는 데이터 딕셔너리
SQL>column owner format a10
SQL>column constraint_name format a15
SQL>column table_name format a15
SQL>column column_name format a15
SQL>select * from user_cons_columns;
###컬럼 레벨 제약 조건 지정 방법
####NOT NULL 제약 조건을 설정하지 않고 테이블 생성
SQL>drop table emp01;
SQL>create table emp01
(
empno number(4),
ename varchar2(10),
job varchar2(10),
deptno number(2)
);
SQL>insert into emp01
values (null, null, 'SALEMAN', 40);
####not null 제약 조건을 걸고 테이블 생성
SQL>drop table emp02;
SQL>create table emp02
(
empno number(4) not null,
ename varchar2(10) not null,
job varchar2(10),
deptno number(2)
);
SQL>insert into emp02
values (null, null, 'SALEMAN', 40);--[error]
SQL>insert into emp02
values (null, 'SCOTT', 'SALEMAN', 40);--[error]
SQL>insert into emp02
values (7499, 'ALLEN', 'SALEMAN', 30);
####Unique 제약 조건을 설정하여 테이블 생성
SQL>drop table emp03;
SQL>create table emp03
(
empno number(4) unique,
ename varchar2(10) not null,
job varchar2(10),
deptno number(2)
);
SQL>insert into emp03
values (7499, 'ALLEN', 'SALEMAN', 30);
SQL>insert into emp03
values (7566, 'JONES', 'MANAGER', 20);
SQL>insert into emp03
values (null, 'SMITH', 'CLERK', 20);
SQL>insert into emp03
values (null, 'JAMES', 'CLERK', 20);
SQL>insert into emp03
values (null, 'JAMES', 'CLERK', 20);
####not null & unique 제약 조건 : 컬럼 레벨로 제약 조건명 명시하기.
- 사용자가 제약 조건명을 지정하지 않고 제약 조건만을 명시할 경우 오라클 서버가 자동으로 제약 조건명을 부여한다.
- 오라클이 부여하는 제약 조건명은 SYS_ 다음에 숫자를 나열한다.
- 어떤 제약 조건을 위배했는지 알 수 없기 때문에 사용자가 의미있게 제약 조건명을 명시할 수 있도록 오라클은 제공.
SQL>drop table emp04;
SQL>create table emp04
(
empno number(4) constraint emp04_empno_uk unique,
ename varchar2(10) constraint emp04_ename_nn not null,
job varchar2(10),
deptno number(2)
);
SQL>insert into emp04
values (7499, 'ALLEN', 'SALEMAN', 30);
SQL>insert into emp04
values (7499, 'JONES', 'MANAGER', 20);
SQL>select table_name, constraint_name
from user_constraints
where table_name in ('EMP04');
Primary key 제약 조건 설정하기
SQL>drop table emp05;
SQL>create table emp05
(
empno number(4) constraint emp05_empno_pk primary key,
ename varchar2(10) constraint emp05_ename_nn not null,
job varchar2(10),
deptno number(2)
);
SQL>insert into emp05
values (7499, 'ALLEN', 'SALEMAN', 30);
SQL>insert into emp05
values (7499, 'JONES', 'MANAGER', 20);--[error]
SQL>insert into emp05
values (null, 'JONES', 'MANAGER', 20);--[error]
참조 무결성을 위한 Foreign key(외래키) 제약 조건
부모 키가 되기 위한 컬럼은 반드시 부모 테이블의 기본키(primary key)이거나 유일키(unique)로 설정되어 있어야 한다.
SQL>drop table dept01;
SQL>create table dept01
(
deptno number(2) constraint dept01_deptno_pk primary key,
dname varchar2(14),
loc varchar2(13)
);
SQL>insert into dept01
values (10, 'ACCOUNTING', 'NEW YORK');
SQL>insert into dept01
values (20, 'RESEARCH', 'DALLAS');
SQL>insert into dept01
values (30, 'SALES', 'CHICAGO');
SQL>drop table emp06;
SQL>create table emp06
(
empno number(4) constraint emp06_empno_pk primary key,
ename varchar2(10) constraint emp06_ename_nn not null,
job varchar2(10),
deptno number(2) constraint emp06_deptno_fk references dept01(deptno)
);
SQL>insert into emp06
values (7499, 'ALLEN', 'SALEMAN', 30);
SQL>insert into emp06
values (7566, 'JONES', 'MANAGER', 40);--[error]
####Check 제약 조건 설정하기
- 급여 컬럼을 생성하되 값은 500~5000 사이의 값만 저장 가능.
- 성별 저장 컬럼으로 gender를 정의하고 ‘M’, ‘F’ 둘 중 하나만 저장 가능.
SQL>drop table emp07;
SQL>create table emp07
(
empno number(4) constraint emp07_empno_pk primary key,
ename varchar2(20) constraint emp07_ename_nn not null,
sal number(7, 2) constraint emp07_sal_ck check(sal between 500 and 5000),
gender varchar2(1) constraint emp07_gender_ck check(gender in ('M', 'F'))
);
SQL>insert into emp07
values (7499, 'ALLEN', 200, 'M');--[error]
SQL>insert into emp07
values (7499, 'ALLEN', 700, 'M');
SQL>insert into emp07
values (7499, 'JONES', 900, 'A');--[error]
Default 제약 조건 설정하기
지역(loc) 컬럼에 아무 값도 입력하지 않을 때 디폴트 값인 ‘SEOUL’ 입력되도록 디폴트 제약 조건 지정.
SQL>drop table dept02;
SQL>create table dept02
(
deptno number(2) primary key,
dname varchar2(14),
loc varchar2(12) default 'SEOUL'
);
SQL>insert into dept02(deptno, dname)
values (10, 'ACCOUNTING');
SQL>insert into dept02
values (20, 'RESEARCH', 'NEW YORK');
컬럼 레벨로 제약 조건명을 명시해서 제약 조건 설정하기
SQL>create table emp10
(
empno number(4) constraint emp06_empno_pk primary key,
ename varchar2(10) constraint emp06_ename_nn not null,
job varchar2(10),
deptno number(2) constraint emp06_deptno_fk references dept01(deptno)
);
테이블 레벨 방식으로 제약 조건 설정하기
not null 제약 조건은 테이블 레벨 방식으로 제약 조건을 지정할 수 없다.
SQL>create table emp11
(
empno number(4),
ename varchar2(10) constraint emp06_ename_nn not null,
job varchar2(10),
deptno number(2),
primary key(empno),
unique(job),
foreign key(deptno) references dept01(deptno)
);
SQL>create table emp11
(
empno number(4),
ename varchar2(10) constraint emp06_ename_nn not null,
job varchar2(10),
deptno number(2),
constraint emp11_empno_pk primary key(empno),
constraint emp11_job_uk unique(job),
constraint emp11_deptno_fk foreign key(deptno) references dept01(deptno)
);
####제약 조건 추가하기
SQL>alter table emp01
add constraint emp01_empno_pk primary key(empno);
SQL>alter table emp01
add constraint emp01_deptno_fk foreign key(deptno) references dept(deptno);
SQL>insert into emp01
values (null, null, 'SALEMAN', 40);
####not null 제약 조건 추가 하기
SQL>alter table emp01
modify ename constraint emp01_ename_nn not null;
####제약 조건 제거하기
SQL>alter table emp01
drop primary key;
SQL>alter table emp01
drop constraint emp01_ename_nn;
####제약 조건(외래키) 삭제
- 제약 조건의 비활성화
- 자식 테이블인 사원테이블(emp06)은 부모테이블(dept01)에 기본키인 부서번호를 참조하고 있다.
- 부서 테이블의 30번 부서는 사원 테이블에 근무하는 30번 사원이 존재하기 때문에 삭제할 수 없다.
- 부모테이블의 부서번호 30번이 삭제되면 자식테이블에서 자신이 참조하는 부모를 잃어버리게 되므로 삭제할 수 없는 것이다.
- 어떻게 삭제?
- 부서 테이블의 30번 부서에서 근무하는 사원을 삭제한 후 부서 테이블에서 30번 부서를 삭제.
- 참조 무결성 때문에서 삭제가 불가능하므로 emp06 테이블의 외래키 제약 조건을 제거한 후 30번 부서를 삭제.
- 제약조건의 비활성화
- 테이블에서 제약 조건을 삭제하지 않고 일시적으로 적용시키지 않도록하는 방법으로 제약 조건을 비활성화 하는 방법.
- DISABLE_CONSTRAINT : 제약 조건의 일시 비활성화
- ENABLE_CONSTRAINT : 비활성화된 제약 조건을 해제하여 다시 활성화.
- cascade 옵션
- 부모테이블(dept01)과 자식 테이블(emp06) 간의 참조 설정(외래키)이되어 있을 때 부모테이블의 제약 조건을 비활성화하면 이를 참조하고 있는 자식테이블의 제약 조건까지 비활성화 시켜주는 옵션.
SQL>delete from dept01
where deptno=30;
//제약 조건의 비활성화
SQL>alter table emp06
disable constraint emp06_deptno_fk;
SQL>delete from dept01
where deptno=30;
SQL>alter table emp06
enable constraint emp06_deptno_fk;
SQL>insert into dept01
values (30, 'SALES', 'CHICAGO');
//cascade 옵션
SQL>alter table dept01
disable primary key cascade;
SQL>alter table dept01
drop primary key;
SQL>alter table dept01
drop primary key cascade;
##시퀀스(Sequence)
- 유일(UNIQUE)한 값을 생성해주는 오라클 객체이다.
- 시퀀스를 생성하면 기본키와 같이 순차적으로 증가하는 컬럼을 자동적으로 생성 할 수 있다.
- 보통 PRIMARY KEY 값을 생성하기 위해 사용 한다.
- 메모리에 Cache되었을 때 시퀀스값의 액세스 효율이 증가 한다.
- 시퀀스는 테이블과는 독립적으로 저장되고 생성된다.
테이블 생성 후 시퀀스(일련번호)를 따로 만들어야 한다.
####샘플테이블 생성
SQL>create table memos
(
num number(4) primary key,
name varchar2(20) not null,
postDate Date default (sysdate)
);
###해당 테이블의 시퀀스 생성
SQL>create sequence memos_seq
start with 1 increment by 1 ;
####데이터 입력 : 일련번호 포함
SQL>insert into memos(num, name)
values (memos_seq.nextval, '홍길동');
SQL>insert into memos(num, name)
values (memos_seq.nextval, '홍길서');
SQL>insert into memos(num, name)
values (memos_seq.nextval, '홍길남');
SQL>insert into memos(num, name)
values (memos_seq.nextval, '홍길북');
현재 시퀀스가 어디까지 증가되어져 있는지 확인
SQL>select memos_seq.currval from dual;
###시퀀스 수정 : 최대 증가값을 6까지로 제한
SQL>alter sequence memos_seq maxvalue 6;
SQL>insert into memos(num, name)
values (memos_seq.nextval, '이길동');
SQL>insert into memos(num, name)
values (memos_seq.nextval, '박길동');
###시퀀스 삭제
SQL>drop sequence memos_seq;
cf) 권한 부여
- system으로 접속 후
SQL>grant create sequence to 사용자명;
##트랜잭션(transaction)
- commit : 명령어 완전 실행.
- rollback : 명령어 되돌리기(실행 해제)
####테이블 생성
SQL>create table trans
(
num number(2) primary key,
name varchar2(20) not null,
email varchar2(50),
title varchar2(150),
postDate Date default sysdate,
postIP varchar2(20)
);
####시퀀스(일련번호) 생성
SQL>create sequence trans_seq
start with 1 increment by 1;
SQL>insert into trans
values (trans_seq.nextval, '홍길동', 'a@a.com', '안녕하세요, 홍길동입니다.',
sysdate, '127.0.0.1');
SQL>insert into trans
values (trans_seq.nextval, '홍길서', 'b@b.com', '안녕하세요, 홍길서입니다.',
sysdate, '127.0.0.1');
##뷰(View)
- 물리적인 테이블에 근거한 논리적인 가상 테이블.
- 가상이란 단어는 실질적으로 데이터를 저장하고 있지 않기 때문에 붙인 것이고, 테이블이란 단어는 실질적으로 데이터를 저장하고 있지는 않지만 사용자는 마치 테이블을 사용하는 것과 동일하게 뷰를 사용할 수 있기 때문에 붙인 것.
- 뷰는 기본 테이블에서 파생된 객체로서 기본 테이블에 대한 하나의 쿼리문임.
- 실제 테이블에 저장된 데이터를 뷰를 통해서 볼 수 있도록 함.
- 사용자에게 주어진 뷰를 통해서 기본 테이블을 제한적으로 사용하게 됨.
- 뷰는 이미 존재하고 있는 테이블에 제한적으로 접근하도록 한다.
- 뷰를 생성하기 위해서는 실질적으로 데이터를 저장하고 있는 물리적인 테이블이 존재해야 하는데 이 테이블을 기본 테이블이다.
뷰의 기본 테이블 생성
//dept 테이블의 복사본을 dept_copy 으로 생성함.
SQL>create table dept_copy
as
select * from dept;
//emp 테이블의 복사본을 emp_copy으로 생성함.
SQL>create table emp_copy
as
select * from emp;
뷰 정의하기
- 뷰를 생성하기 위해서는 create view로 시작함. as 다음은 마치 서브쿼리문과 유사함.
- 서브쿼리에는 우리가 지금까지 사용했던 select 문을 기술하면 됨.
// 만일 30번 부서에 소속된 사원들의 사번과 이름과 부서번호를 자주 검색한다고 한다면
SQL>select empno, ename, deptno
from emp_copy
where deptno = 30;
SQL>create view emp_view30
as
select empno, ename, deptno
from emp_copy
where deptno = 30;
SQL>select * from emp_view30;
뷰의 내부구조와 user_views 데이터 딕셔너리
SQL>desc user_views;
SQL>select view_name, text from user_views;
뷰의 동작 원리
- 사용자가 뷰에 대해서 질의를 하면 user_views에서 뷰에 대한 정의를 조회한다.
- 기본 테이블에 대한 뷰의 접근 권한을 살핀다.
- 뷰에 대한 질의를 기본 테이블에 대한 질의로 변환한다.
- 기본 테이블에 대한 질의를 통해 데이터 검색한다.
- 검색된 결과를 출력한다.
뷰와 기본 테이블 관계 파악
- 뷰를 통한 데이터 저장이 가능?
SQL>insert into emp_view30 values (8000, 'ANGEL', 30);
SQL>select * from emp_view30;
SQL>select * from emp_copy;
-
insert 문에 뷰(emp_view30)를 사용하였지만, 뷰는 쿼리문에 대한 이름일 뿐 새로운 레코드는 기본 테이블(emp_copy)에 실질적으로 추가되는 것이다.
-
뷰는 실질적인 데이터를 저장한 기본 테이블을 볼 수 있도록 한 투명한 창이다. 즉, 기본 테이블의 모양이 바뀐 것이고 그 바뀐 내용을 뷰라는 창을 통해서 볼 뿐이다. 뷰에 insert 뿐만 아니라, update, delete 모두 사용할 수 있는데, 이 명령문 역시 뷰의 텍스트에 저장되어 있는 기본 테이블을 변경하는 것이다.
####뷰를 사용하는 이유
- 복잡하고 긴 쿼리문을 뷰로 정의하면 접근을 단순화 시킬 수 있다.
- 보안에 유리하다. - 사용자마다 특정 객체만 조회할 수 있도록 권한을 부여할 수 있기 때문
###뷰의 종류
뷰는 뷰를 정의하기 위해서 사용되는 기본 테이블의 수에 따라 두 가지로 나뉜다.
- 단순뷰(simple view)
- 하나의 테이블로 생성
- 그룹 함수의 사용이 불가능
- distinct 사용이 불가능
- insert/update/delete(DML) 등의 사용 가능
- 복합뷰(complex view)
- 여러 개의 테이블로 생성
- 그룹 함수의 사용이 가능
- distinct 사용이 가능
- DML 사용 불가능
####단순뷰
단순 뷰에 대한 데이터 조작
SQL>insert into emp_view30 values(8010, 'HONG', 30);
단순 뷰의 컬럼에 별칭 부여하기
SQL>create view emp_view_copy(사원번호, 사원명, 급여, 부서번호)
as
select empno,ename,sal,deptno
from emp_copy;
SQL>select * from emp_view_copy;
SQL>select * from emp_view_copy where 부서번호=30;
그룹 함수를 사용한 단순 뷰 뷰를 작성할 때 select절 다음에 sum이라는 그룹함수를 사용하면 결과를 뷰의 특정 컬럼처럼 사용하게 된다. 따라서 물리적인 컬럼이 존재하지 않는 가상 컬럼이기에 컬럼명도 상속 받을 수 없다. 뷰를 생성할 때 가상 컬럼을 사용하려면 사용자가 반드시 별칭을 따로 설정해야한다.
SQL>create view view_sal
as
select deptno, sum(sal) sum, avg(sal) avg
from emp_copy
group by deptno;
단순 뷰의 경우 DML 명령어의 조작이 불가능한 경우
- 뷰 정의에 포함되지 않은 컬럼 중에 기본 테이블의 컬럼이 not null 제약 조건이 지정되어 있는 경우 insert문 사용이 불가능하다. 왜냐하면 뷰에 대한 insert문은 기본 테이블에 null 값을 입력하는 형태가 되기 때문이다.
- sal * 12 와 같이 산술 표현식으로 정의된 가상 컬럼이 뷰에 정의되면 insert/update가 불가능하다.
- distinct을 포함한 경우에도 DML(data manipulation language) 명령을 사용할 수 없다.
- 그룹 함수나 group by절을 포함한 경우에도 DML 명령을 사용할 수 없다.
####복합뷰
SQL>select empno,ename,sal,e.deptno,dname,loc
from emp e, dept d
where e.deptno = d.deptno
order by empno desc;
SQL>create view emp_view_dept
as
select empno,ename,sal,e.deptno,dname,loc
from emp e, dept d
where e.deptno = d.deptno
order by empno desc;
###뷰 삭제
SQL>drop view emp_view;
###뷰 생성에 사용되는 다양한 옵션
-
or replace 존재하지 않는 뷰이면 새로운 뷰를 생성하고 기존에 존재하는 뷰이면 그 내용을 변경한다.
-
force/noforce force - 기본 테이블이 존재하지 않을 때도 뷰를 생성해야 되는 경우 사용하는 옵션. noforce - 기본 테이블이 존재하는 경우만 뷰가 생성(default)
-
with check option 뷰를 생성할 때 조건 제시에 사용된 컬럼 값을 변경하지 못하도록 하는 기능을 제공 뷰를 설정할 때 조건으로 설정한 컬럼 이외의 다른 컬럼의 내용은 변경할 수 있음
-
with read only 기본 테이블의 어떤 컬럼에 대해서도 뷰를 통한 내용 수정을 불가능하게 만드는 옵션
##Top Query
상위 몇 개의 데이터만을 출력하고 싶을 때 사용하는 쿼리 Top-N을 구하기 위해 rownum & 인라인뷰가 사용
SQL>select rownum, empno, ename, hiredate from emp;
SQL>select rownum, empno, ename, hiredate
from emp
order by hiredate
SQL>create or replace view view_hire
as
select empno, ename, hiredate
from emp
order by hiredate;
SQL>select rownum, empno, ename, hiredate
from view_hire;
SQL>select rownum, empno, ename, hiredate
from view_hire
where rownum <= 5
//인라인 뷰를 사용 - 중요!!!
SQL>select rownum, empno, ename, hiredate
from (select empno, ename, hiredate
from emp
order by hiredate)
where rownum <= 5;
##사용자(User) 권한(Rule)
###권한의 역할과 종류
- 권한 : 사용자가 특정 테이블을 접근할 수 있도록 하거나 해당 테이블에 sql(select/insert/update/delete)문을 사용 할 수 있도록 제한을 두는 것.
- 데이터베이스 보안을 위한 권한은 시스템 권한과 객체 권한으로 나눌 수 있다.
- 시스템 권한: 사용자의 생성과 제거, DB 접근 및 각종 객체를 생성할 수 있는 권한 등 DBA에 부여됨.
- 객체 권한 : 객체를 조작할 수 있는 권한.
###실습
user01 계정 생성
SQL>conn system/manager
SQL>create user user01 identified by tiger;
데이터베이스 접속 권한
SQL>grant create session to user01;
SQL>create table emp01
(
empno number(4),
ename varchar2(10),
job varchar2(10),
deptno number(2)
);--[error]
테이블 생성 권한
SQL>grant create table to user01;
SQL>create table emp01
(
empno number(4),
ename varchar2(10),
job varchar2(10),
deptno number(2)
);
SQL>insert into emp01 values(7326,'SMITH','CLERK',20);
테이블 스페이스 확인
테이블 스페이스는 디스크 공간을 소비하는 테이블과 뷰 그리고 그 밖의 다른 데이터베이스 객체들이 저장되는 장소
SQL>alter user user01 quita 2m on users;
SQL>insert into emp01 values(7326,'SMITH','CLERK',20);
with admin option
사용자에게 시스템 권한을 with admin option과 함께 부여하면 그 사용자는 데이터베이스 관리자가 아닌데도 불구하고 부여받은 시스템 권한을 다른 사용자에게 부여할 수 있는 권한을 함께 부여받게 된다.
SQL>create user user02 identified by tiger;
SQL>grant create session to user02 with admin option;
SQL>create user user03 identified by tiger;
SQL>conn user02/tiger
SQL>grant create session to user03;
테이블 객체에 대한 select 권한 부여
//scott/emp -> user01
SQL>conn scott/tiger 계정 접속
SQL>grant select on emp to user01;
SQL>conn user01/tiger;
SQL>select * from emp;
스키마(SCHEMA)
객체를 소유한 사용자 명을 의미한다.
SQL>select * from scott.emp;
사용자에게 부여된 권한 조회
- user_tab_privs_made : 현재 사용자가 다른 사용자에게 부여한 권한 정보를 알려줌
- user_tab_privs_recd : 자신에게 부여된 사용자 권한을 알고 싶을 떄
SQL>select * from user_tab_privs_made;
SQL>select * from user_tab_privs_recd;
//한번에 권한 부여
SQL>grant create session, create table, create view to user01;
객체 권한 제거하기
SQL>conn scott/tiger
SQL>select * from user_tab_privs_made;
SQL>revoke select on emp from user01;
with grant option
사용자에게 객체 권한을 with grant option과 함께 부여하면 사용자는 객체를 접근할 권한을 부여 받으면서 그 권한을 다른 사용자에게 부여할 수 있는 권한도 함께 부여받게 된다.
SQL>conn scott/tiger
SQL>grant select on scott.emp to user02 with grant option;
SQL>conn user02/tiger
SQL>grant select on scott.emp to user01 with grant option;
사용자 계정 제거
SQL>conn system/manager
SQL>drop user user03;
롤(Role)
- 사용자에게 보다 효율적으로 권한을 부여할 수 있도록 여러 개의 권한을 묶어 놓은 것.
- 사용자를 생성했으면 그 사용자에게 각종 권한을 부여해야만 생성된 사용자가 데이터베이스를 사용할 수 있음.
- connect role
- 사용자가 데이터베이스에 접속 가능하도록 하기 위해서 다음과 같이 가장 기본적인 시스템 권한 8가지 묶어 놓은 권한.
- alter session, create cluster, create database link, create sequence, create session, create synonym, create table, create view
- resource role
- 사용자가 객체 (테이블, 뷰, 시퀀스)를 생성할 수 있도록 시스템 권한을 묶어 놓은 것.
- create cluster, create procedure, create sequence, create table, create trigger
- DBA role
- 사용자들이 소유한 데이터베이스 객체를 관리하고 사용자들이 작성하고 변경하고 제거 할 수 있도록 하는 모든 권한을 가짐.
SQL>conn system/manager
SQL>create user user03 identified by tiger;
SQL>grant connect, resource to user03;
SQL>conn user03/tiger
SQL>select * from dict
where table_name like '%ROLE%';
##연습문제
[문제1] 기본테이블은 EMP_COPY로 합니다. 20번 부서에 소속된 사원들의 사번과 이름, 부서번호와 상관의 사번을 출력하기 위한 select문을 emp_view20이라는 이름의 뷰로 정의해 보세요.
SQL>create or replace view emp_view20
as
select empno, ename, deptno, mgr
from emp_copy
where deptno=20;
[문제2] 각 부서별 최대 급여와 최소 급여를 출력하는 뷰를 sal_view 라는 이름으로 작성하세요.
SQL>create or replace view sal_view
as
select deptno, max(sal) "최대급여", min(sal) "최소급여"
from emp_copy
group by deptno
order by deptno;
[문제3] 인라인뷰를 이용하여 급여를 많이 받는 순서대로 3명만 출력하는 뷰(sal_top3_view)를 작성하세요.
SQL>select rownum, empno, ename, sal
from (select empno, ename, sal
from emp_copy
where sal is not null
order by sal desc)
where rownum <= 3;
[문제4] acorn/tiger 계정을 생성해서 순번/사원번호/이름/직업/근무부서(컬럼)의 항목을 갖는 테이블을 만들어서 데이터를 저장하되 순번 데이터 입력은 sequence를 이용하여 저장하고, view_acorn 뷰를 생성해서 순번/사원번호/이름만 출력할 수 있도록 만들어보세요.
SQL>conn system/manager
SQL>create user acorn identified by tiger;
SQL>grant create session, create table, create sequence, create view to acorn;
SQL>conn acorn/tiger
SQL>create table emp_acorn(
num number(4) primary key,
empno number(4),
ename varchar2(10),
job varchar2(10),
dname varchar(10));
SQL>create sequence emp_seq start with 1 increment by 1 ;
SQL>insert into emp_acorn values(emp_seq.nextval, 10, 'IRONMAN', 'HERO', 'SHIELD');
SQL>insert into emp_acorn values(emp_seq.nextval, 10, 'HULK', 'HERO', 'SHIELD');
SQL>create view view_acorn
as
select num, empno, ename
from emp_acorn;
인덱스(Index)
- 조회를 빠르게(빠른 검색) 하도록 도와준다.
- sql 명령문의 처리 속도를 향상시키기 위해서 컬럼에 생성하는 오라클 객체
- 장점
- 검색 속도가 빨라진다.
- 시스템에 걸리는 부하를 줄여서 시스템 전체 성능을 향상시킨다.
- 단점
- 인덱스를 위한 추가적인 공간이 필요하다.
- 인덱스를 생성하는데 시간이 걸린다.
- 데이터의 변경작업(DML)이 자주 일어날 경우에는 오히려 성능이 떨어진다.
인덱스 정보 조회
SQL>select index_name, table_name, column_name
from user_ind_columns
where table_name in ('EMP', 'DEPT');
조회 속도 비교하기
SQL>create table emp01
as
select * from emp;
SQL>select index_name, table_name, column_name
from user_ind_columns
where table_name in ('EMP', 'EMP01');
//emp 테이블에는 empno 컬럼에 인덱스가 존재하지만 emp를 서브 쿼리로 복사한 emp01 테이블에는 인덱스가 존재하지 않는다.
서브쿼리문으로 복사한 테이블은 구조와 내용만 복사할 뿐 제약조건은 복사되지 않기 때문이다.
SQL>insert into emp01
select * from emp01;
//자신의 데이터를 그대로 덧붙여서 추가한다. 수행할때마다 2배씩 늘어나는 셈이다.
많은 양의 데이터를 추가한 후 실습을 해본다.
SQL>insert into emp(empno, ename)
values(8000, 'ANGEL');
SQL>set timing on //시간 측정
SQL>select empno, ename
from emp01
where ename='ANGEL';
인덱스 생성 & 제거
기본키(primary key)나 유일키(unique)가 아닌 컬럼에 대해서 인덱스를 지정하려면 create index
를 사용한다.
//인덱스 생성 후 다시 조회하면 시간이 단축된걸 알 수 있다.
SQL>create index idx_emp01_ename
on emp01(ename);
SQL>select empno, ename
from emp01
where ename='ANGEL';
//인덱스 제거
SQL>drop index idx_emp01_ename;
//인덱스의 물리적인 구조과 인덱스의 재생성(최적화)
SQL>alter index idex_emp01_ename rebuild;
####인덱스 사용 기준
- 인덱스를 사용해야 하는 경우
- 테이블에 행(레코드)의 수가 많을 때
- where문에 해당 컬럼이 많이 사용될 때
- 검색 결과가 전체 데이터의 2~4% 정도 일 때
- join에 자주 사용되는 컬럼이나 null을 포함하는 컬럼이 많은 경우
- 인덱스를 사용하지 말아야 하는 경우
- 테이블에 행(레코드)의 수가 적을 때
- where문에 해당 컬럼이 자주 사용되지 않을 때
- 검색 결과가 전체 데이터의 10~15% 이상 일 때
- 테이블에 DML 작업이 많은 경우
인덱스 종류
- 고유 인덱스(Unique Index)
- 기본키나 유일키처럼 유일한 값을 갖는 컬럼에 대해서 생성하는 인덱스
create unique index
- 비고유 인덱스(Nonunique Index)
- 중복된 데이터를 갖는 컬럼에 대해서 인덱스를 생성(default)
- 단일 인덱스(Single Index)
- 한 개의 컬럼으로 구성한 인덱스
- 결합 인덱스(Composite Index)
- 두 개 이상의 컬럼으로 인덱스를 구
- 함수 기반 인덱스(Function Based Index)
##저장 프로시저(stored procedure)
- 복잡한 쿼리문들을 필요할 때 마다 다시 입력할 필요없이 간단하게 호출만 해서 복자한 쿼리문의 생행결과를 얻어올 수 있다.
- 성능도 향상되고, 호환성 문제도 해결된다.
- 여러 번 반복 호출해서 사용할 수 있다.
SQL>create table emp01
as
select * from emp;
SQL>ed proc01;
SQL>@proc01
SQL>execute del_all
SQL>ed proc01
SQL>show error
proc01
create or replace procedure DEL_ALL
is
begin
delete from emp01;
end;
/
저장프로시저 조회하기
SQL>desc user_source
SQL>select name, text
from user_source;
저장 프로시저의 매개변수
SQL>ed proc02;
SQL>@proc02
SQL>execute del_ename('SMITH');
proc02
create or replace procedure del_ename(vename emp01.ename%type)
is
begin
delete from emp01 where ename = vename;
end;
/
IN, OUT, INOUT 매개변수
SQL>ed proc03;
SQL>@proc03;
SQL>variable var_ename varchar2(15);
SQL>variable var_sal number;
SQL>variable var_job varchar2(9);
SQL>execute sel_empno(7788, :var_ename, :var_sal, :var_job);
SQL>print var_ename;
SQL>print var_sal;
SQL>print var_job;
proc03
create or replace procedure sel_empno
( vempno in emp.empno%type,
vename out emp.ename%type,
vsal out emp.sal%type,
vjob out emp.job%type
)
is
begin
select ename, sal, job into vename, vsal, vjob
from emp where empno = vempno;
end;
/