* 모든 계정이 백업과 복구를 수행할 수 있음

* DOS창에서 수행

 

 1. 백업 

- exp.exe 사용

   > set path로 경로 확인후 진행

   > exp -help하면 도움말 보기

- 계정의 테이블만 백업) exp userid=계정명/비번 tables=테이블명,,, file=경로/백업파일명.dmp

- 계정의 모든 객체 백업) exp userid=계정명/비번 full=y file=경로/백업파일명.dmp

                                               > table, index, sequence, function,,,, 가능

 

 

 2 . 복구 

- imp.exe 사용

  > 도움말 보기 : imp -help

- 백업한 계정으로 복구할 수 있음

- 계정 내에 같은 이름의 객체가 존재하면 복구되지 않음

- 복구파일은 테이블만 백업한 파일 or 모든 파일 백업한 파일 모두 가능

- 테이블만 복구) imp userid=계정명/비번 tables=테이블명 file=경로/복구할 파일명.dmp

- 모든 객체 복구) imp userid=계정명/비번 full=y file=경로/복구할 파일명.dmp

                                 > 백업파일명 = 복구할 파일명

 

 

 3. exists 

- 조회 결과가 있으면 true, 없으면 false를 반환하는 함수

- where 절에서 사용

- 문법)  select 컬럼명

               from 테이블명

               where exists (서브쿼리)

               => 서브 쿼리의 실행 결과가 존재하면 바깥 쿼리문을 수행함

 

 

 

'Development > Oracle' 카테고리의 다른 글

[Oracle] index  (0) 2021.10.04
[Oracle] 권한부여 & 회수 / synonym / view  (0) 2021.10.01
[Oracle] sequence  (0) 2021.09.30
[Oracle] alter  (0) 2021.09.29
[Oracle] 제약사항 (Constraint)  (0) 2021.09.28

 index 

- 많은 양의 레코드에서 필요한 값을 빠르게 검색하기 위해 사용 (검색속도 향상)

- 레코드 수가 적으면 index를 사용하지 않는 것이 더 빠름

- 자동 인덱스, 수동 인덱스를 제공

  • 자동 인덱스 : 테이블을 생성할 때 primary key, unque를 생성하면 자동으로 생성되는 인덱스
  • 수동 인덱스 : 개발자가 생성하는 인덱스

- unique index, non-unique index, bitmap index, composite index 4가지를 제공

- 실제 테이블과 생성된 index는 별개로 동작함

   (테이블에 DML이 발생하더라도, index에는 반영되지 않음)

   -> 시간이 지날수록 실제 데이터와 인덱스 간의 정보차가 발생

    => 인덱스를 주기적으로 rebuild 해야 함!

- 테이블 삭제 시 인덱스도 함께 삭제 됨

 

- 인덱스로 설정해야하는 컬럼의 선정기준

  • where절에서 자주 사용되는 컬럼
  • where절에서 사용되더라도 함수를 사용하지 않고 조회하는 컬럼
  • 자주 변경되지 않는 컬럼

- 인덱스는 전체 레코드 중 10~15% 정도의 결과가 조회될 때 가장 속도가 빠름

  (인덱스가 항상 빠른 것은 아님)

- 인덱스는 테이블의 주소에 대한 참조 (DBMS는 내용에 의한 참조)

     => Oracle에서는 record의 주소를 rowid 컬럼(유일함)으로 사용

- 인덱스 생성) create [인덱스종류] index on 테이블명 (컬럼명,,,);

     => 해당 테이블의 컬럼을 조회 조건으로 사용하여 검색

- 인덱스 삭제) drop 인덱스 인덱스명;

- 인덱스 갱신) alter index 인덱스명 rebuild;

   -> 실제 테이블과 인덱스의 데이터를 일치시키는 것!

 

* index 종류별 생성문법 

1) unique 인덱스

 - 컬럼의 값이 유일할 때 사용하는 인덱스

 - 컬럼의 값이 null이거나 유일해야 함

 - 테이블을 생성할 때 PK를 설정하거나 unique를 설정하면 자동생성되는 자동 인덱스

- 수동 생성도 가능

 - 문법) create unique index 인덱스명 on 테이블명 (컬럼명);

2) non-unique 인덱스

 - 컬럼의 값이 중복될 때 사용하는 인덱스

 - 문법) create index 인덱스명 on 테이블명 (컬럼명);

3) bitmap 인덱스

 - 컬럼의 값이 키는 아니지만 독특한 형태일 때 사용하는 인덱스

     Ex) LOT 번호

 - 문법) create bitmap index 인덱스명 on 테이블명(컬럼명);

4) composite 인덱스

 - 여러 개의 컬럼이 조합되어 사용되는 인덱스

 - 문법) create index 인덱스명 on 테이블명(컬럼명 ,,, )

 

* 인덱스를 사용한 검색

- index hint를 기술함 : 여러 줄 주석과 한 줄 주석 방식 사용

       /*+ */ : 여러 줄 주석방식

       --+  : 한 줄 주석 방식

- index hint를 사용하면 정렬의 효과를 얻을 수 있음

- select 쿼리에 가장 처음에 기술함 : selelct /*+ 인덱스힌트 */ 컬럼명,,,

  > 인덱스 힌트 : 인덱스 종류 (테이블명(alias) 인덱스명)

       Ex) index (emp PK_EMP)  : 순방향 정렬의 효과

              index_desc (emp PK_EMP)  : 역방향 정렬 // 단, record가 많다면 정렬 안 되고  where절을 사용했을 때만 정렬됨

 

* index 관련 data dictionary

- 테이블에 설정된 인덱스 조회 : user_indexes data dictionary

    > last_analyzed column은 마지막으로 rebuild된 시간을 보여줌

- index로 설정된 컬럼을 조회 : user_ind_columns data dictionary

 


# 오늘의 코딩 #

-  인덱스 생성 / 조회를 해보자

 

#인덱스 생성

--사원번호로 non-unique index 생성
create unique index empno_ind on test_emp(empno);

select *
from user_ind_columns
where table_name='TEST_EMP';

#출력결과#

=> 딕셔너리를 조회하면 생성한 인덱스를 확인할 수 있다!

 


#인덱스를 이용한 조회

--인덱스를 사용한 조회, select hint 부여
select  /*+ index (test_emp EMPNO_IND)*/ empno, name, sal, hiredate
from    test_emp
where   empno =7788;

#출력결과#

=> 특정 사원번호를 인덱스를 통해 조회 가능!!

'Development > Oracle' 카테고리의 다른 글

[Oracle] 백업/복구/exists 함수  (0) 2021.10.06
[Oracle] 권한부여 & 회수 / synonym / view  (0) 2021.10.01
[Oracle] sequence  (0) 2021.09.30
[Oracle] alter  (0) 2021.09.29
[Oracle] 제약사항 (Constraint)  (0) 2021.09.28

 

 권한부여 & 회수 

- 생성된 계정이 할 수 있는 일을 부여하는 것

   > 생성된 계정은 아무런 권한을 가지고 있지 않음

- 관리자 계정만 권한 부여, 권한 회수가 가능함

- grant로 주는 권한은 oracle에 재접속해야 반영됨

권한명 하는일
connect Oracle DBMS에 접속할 수 있는 권한
resource Oracle DBM 자원 사용 권한
 - table space를 사용할 수 있음 (table 생성 등)
dba 일반계정을 DBA계정으로 권한 부여
 - 일반 계정이 관리자의 역할을 수행할 수 있음
create view view 생성 권한
create synonym 시노님 생성 권한

 

* synonym

- 테이블에 별명을 부여하여 사용하는 객체

- create synonum 권한이 부여된 계정만 사용할 수 있음

- alias와는 다르게, synonym명과 원래 테이블명 둘다 사용 가능

- user_synonyms data dictionary에서 확인 가능

- synonym과 public synonym지원 (public synonym은 다른 계정에서도 사용 가능함)

- 권한 부여) grant [public] create synonym to 계정명;

- 권한 회수) revoke [public] create synonym from 계정명;

- 시노님 생성) create synonym 시노님명 for 테이블명;

- 시노님 삭제) drop synonym 시노님명;

 

* grant,revoke 사용 (DCL)

- 권한 부여) grant 권한,,, to 계정명;

- 권한 회수) revoke 권한,,, from 계정명;

- Oracle 12c 부터는 resource 권한만 부여되어서는 테이블을 생성할 수 없음

   >> resource 권한 이후 table space에 대한 사용권한을 부여해야 함

   > 문법) alter user 계정명 default tablespace 테이블 스페이스명 quota unlimited on users

- 계정 사용하는 기본 tablespace는 users01.dbf파일이고 users라는 이름으로 사용됨

 

* 권한 관련 data dictionary

- DBMS 자체의 사용권한 조회 : dba_role_privs

- SQL문의 사용권한 조회(synonym, view도 확인가능) : dba_sys_privs

- synonym 조회 : user_synonyms

 

 

 view 

- 실제 테이블로부터 도출된 가상테이블

- 권한이 부여된 계정만 view를 생성할 수 있음

- user_views data dictionary에서 확인 가능

- 장점) 실제 테이블을 숨겨놓고 가상 테이블을 사용하므로 보안성이 향상됨

- DML 작업이 가능

    > view에 작업한 내용이 실제 테이블에 반영되고 테이블에서 작업한 내용이 view에 반영됨

- view에 DML작업을 막고 싶다면 veiw를 생성할 때 가장 마지막에 with read only를 사용

 

- 단순 뷰(하나의 테이블로 도출된 view), 복합 뷰(여러 개의 테이블에서 도출된 view)로 생성할 수 있음

① 단순 뷰

- 하나의 테이블에서 도출된 뷰

- 함수나 연산자를 사용하지 않고 만들어진 뷰

- DML 수행(insert, updtae, select, delete)이 가능함

② 복합 뷰

- 여러 개의 테이블에서 도출된 뷰

- join, 함수, 연산식을 사용한 뷰

 > 함수/연산식 :
     (insert,update) 연산, 함수가 사용된 열은 추가 작업이 되지 않음 / 해당 컬럼을 제외한 일반 컬럼은 사용 가능
     (delete) 집계함수를 사용하여 view를 생성하면 delete 불가 /
                      단일함수, 연산자를 사용한 컬럼에 대해서는 view에 생성된 값과 같다면 삭제 가능

  > join : DML 중 select만 가능 (insert, update, delete 불가)

              : view를 생성하면 select이 단순해짐

         => 복잡한 join을 만들어두고, 필요한 것만 그때그때 select하자!

 

* view 권한부여/회수 : 관리자 계정만 가능

- 권한 부여) grant creat view to 계정명;

- 권한 회수) revoke create view from 계정명;

- view 생성) create view 뷰명 (컬럼명,,,) as (select ,,,);  -- create subquery와 문법 동일

                                                                                                          -- (컬럼명,,)은 생략 가능

- view 삭제) drop veiw 뷰명;  -- 테이블이 삭제되면 view도 삭제됨

'Development > Oracle' 카테고리의 다른 글

[Oracle] 백업/복구/exists 함수  (0) 2021.10.06
[Oracle] index  (0) 2021.10.04
[Oracle] sequence  (0) 2021.09.30
[Oracle] alter  (0) 2021.09.29
[Oracle] 제약사항 (Constraint)  (0) 2021.09.28

 sequence 

- 순차적으로 증가하는 번호를 관리하는 객체

- 레코드를 insert하는 순서대로 번호를 넣어야 할 때

- 오라클 버전에 따라 순차적인 번호를 사용하지 못할 수도 있음

    > 12c 이전에는 오라클이 종료되면 cache에 설정한 sequence 번호가 사라짐

        (8i, 9i, 10g,11g)

    > 12c 이후 부터는 insert를 실패한 경우에만 번호가 사라짐 (12c~19c)

- user_sequences data dictionary에서 생성된 시퀀스를 확인할 수 있음

 

- 시퀀스 생성) create sequence 시퀀스명

                           increment by   증가값

                           start with      시작값

                           maxvalue      끝값

                           cache         메모리에 올릴 번호 개수

                           반복여부; (cycle | nocycle)

  > 시퀀스 생성 옵션의 기재 순서는 없음

  > cache는 20이 기본, 반복여부는 nocycle(반복아님)이 기본

  > 반복이 nocycle인 경우에는 maxvalue이후에 nextval하면 error

  > 생성된 시퀀스는 사용자가 nextval로 값을 사용해야 메모리에 로드됨 (메모리에 생성된 시퀀스만 사용 가능)

 

- 값 얻기) 시퀀스명.nextval

  > 메모리에 시퀀스가 로드되지 않으면 메모리에 시퀀스를 로딩하고 다음 번호를 얻음

                   시퀀스명.currval

  > 메모리에 로드되어있는 시퀀스의 현재 번호를 얻음(메모리에 로딩은 할 수 없음)

  > 시퀀스 객체가 메모리에 로딩되어있지 않다면 error 발생 (currval을 먼저 쓰면 error)

 

- 시퀀스 삭제) drop sequence 시퀀스명;

 

- 시퀀스 사용 중 쿼리가 실패하면 해당 번호는 사라짐.

   따라서, 순차적인 번호가 모두 존재해야하는 경우에는 시퀀스 쓰지 말고 서브쿼리 쓰자!! 

 


# 오늘의 코딩 #

- 시퀀스를 사용해보자!

 

#시퀀스 생성 및 사용

---시퀀스 생성
-- 1 ~ 100 까지 1씩 증가하는 반복하지 않는 시퀀스를 생성하고
-- cp_test_emp 테이블에 시퀀스를 사용하여 아래와 같이 사원정보를 추가하자

-- 1. 김동동 2800
-- 2. 박나나 2900
-- 3. 이사랑 2801

--시퀀스 생성
create sequence test_sequence
increment by 1
start with 1
maxvalue 100
nocycle;

--값 추가
insert into cp_test_emp(EMPNO, NAME, SAL)
values (test_sequence.nextval, '김동동', 2800);

insert into cp_test_emp(EMPNO, NAME, SAL)
values (test_sequence.nextval, '박나나', 2900);

insert into cp_test_emp(EMPNO, NAME, SAL)
values (test_sequence.nextval, '이사랑', 2801);
commit;

select * from cp_test_emp;
select * from user_sequences where sequence_name='TEST_SEQUENCE';

#출력결과#

=> empno(시퀀스 사용 부분)이 insert한 순서대로 부여된 것 확인! 

=> user_sequences 딕셔너리에서 조회하면 만든 시퀀스를 조회할 수 있음

 


#시퀀스 삭제

--시퀀스 삭제
drop sequence test_sequence;

#출력결과#

=> 삭제완료!

'Development > Oracle' 카테고리의 다른 글

[Oracle] index  (0) 2021.10.04
[Oracle] 권한부여 & 회수 / synonym / view  (0) 2021.10.01
[Oracle] alter  (0) 2021.09.29
[Oracle] 제약사항 (Constraint)  (0) 2021.09.28
[Oracle] union / join / driving table  (0) 2021.09.26

 alter 

- DDL

- 테이블의 관리, 제약사항 관리, 계정관리를 할 수 있는 쿼리 (자주 쓰임!!!)

 

 

1. 테이블의 관리

- 컬럼 추가, 컬럼테이터형 변경, 컬럼 삭제, 컬럼명 변경, 테이블명 변경

- 문법) alter table 테이블명 작업…;

 

** 컬럼 관리의 경우 주의할 점 :

① 제약사항을 붙여서 추가/변경 등 할 수 있으나 레코드의 구성이 제약사항에 위배된다면 추가할 수 없음

② 컬럼 데이터형 변경이나 컬럼명의 경우 기존 데이터 값에 따라 될수도 안 될수도 있음

 

1) 컬럼 추가

 - 추가된 컬럼은 제일 마지막에 추가됨

 - 문법) alter table 테이블명 add 컬럼명 데이터형(크기) 컬럼단위 제약사항;

2) 컬럼 데이터형 변경

- 레코드가 존재하지 않으면 데이터 형 자체를 변경할 수 있음

- 레코드가 존재하면 동일 데이터형에서 크기만 변경할 수 있음

   > 크기를 줄이는 것은 기존 컬럼 값의 크기에 따라 될 수도 안 될수도 있음.

 - 문법) alter table 테이블명 modify 컬럼명 데이터형(크기) 컬럼단위 제약사항;

3) 컬럼 삭제

  - 컬럼에 설정된 제약사항도 같이 삭제됨

  - 법) alter table 테이블명 drop column 컬럼명;

4) 컬럼명 변경

  - 테이블의 다른 컬럼명과는 다르게 변경

  - 문법) alter table 테이블명 rename column 원본컬럼명 to 변경할 컬럼명;

5) 테이블명 변경

 - 문법) alter table 원본테이블명 rename to 변경할 테이블명;

 

 

2. 제약사항 관리

- 제약사항 추가, 삭제, 활성화, 비활성화

- 제약사항의 활성화(enable), 비활성화(disable) 상태는 user_constraints의 status 컬럼에서 확인 가능

 

1) 제약사항 추가

- 테이블단위 제약사항 문법으로 추가함

- 문법) alter table 테이블명 add constraint 제약사항명 제약사항종류 (적용컬럼);

2) 제약사항 삭제

  - PK를 지우면 pk 설정시 따라오는 not nul도 같이 지워짐

- 문법) alter table 테이블명 drop constraint 제약사항명;

3) 제약사항 활성화/비활성화

- 주의) 비활성화 후 활성화를 할 때, 컬럼 값의 상황에 따라 활성화가 되지 않을 수도 있음

- 문법) alter table 테이블명 상태 constraint 제약사항명;

 > 상태에 enable 기입 : 활성화 / 컬럼에 설정된 제약사항을 체크함

 > 상태에 disable 기입 : 비활성화 / 컬럼에 설정된 제약사항을 체크하지 않음
      (제약사항이 PK인데 비활성화 되어있으면 중복값도 추가 가능해짐)

 

 

3. 계정 관리

- 계정 잠그거나 열기, 계정의 비밀번호 변경

1) 계정의 비밀번호 변경

- 모든 계정이 가능 (관리자는 다른 계정의 비밀번호를 변경(=재설정)할 수 있음)

- 문법) alter user 계정명 identified by 비번;

2) 계정을 잠그거나 열기

- 관리자 계정만 가능 (관리자 계정으로 로그인 한 후 다른 계정을 잠그거나 열 수 있음)

- 연습해볼 때는 login을 관리자계정으로 하고 해보자 (id : system / pw : managerjang)

- 문법) alter user 계정명 account lock | unlock;

 

 

** dba_users data dictionary : 계정에 대해 조회할 수 있는 data dictionary

 

 


# 오늘의 코딩 #

- alter를 사용해보자

 

#컬럼명 변경하기

--table 생성
select * from emp;
create table test_emp as (select * from emp);

--alter로 컬럼명 변경 (ename -> name)
alter table test_emp rename column ename to name;

#출력 결과#

<기존 테이블>

<변경된 테이블>

=> 컬럼명 변경 완료!

 


#PK 제약사항 추가하기

-- alter로 empno에 PK 제약사항 추가
alter table test_emp add constraint pk_test_emp primary key (empno);

-- 제약사항 조회
select *
from   user_constraints
where table_name='TEST_EMP';

#출력 결과#

=> user_constraints 딕셔너리 조회 결과 

     PK가 잘 들어가 있당!

 제약사항 (Constraint) 

- 테이블에 입력되는 값을 개발자가 원하는 범위에서 입력받기 위해 설정하는 것

- 제약사항명은 유일해야 함 (data dictionary에 등록되기 때문)

- key 종류 : primary key, foreign key, unique

  check 종류 : check, not null

- column level constraint(컬럼단위 제약사항)와 table level constraint(테이블단위 제약사항)로 설정할 수 있음

- alter를 가지고 편집할 수 있음

- 테이블이 drop(삭제)되면 제약사항은 같이 삭제됨

- 문법) 

  create table 테이블명 (

   컬럼명 테이터형(크기) constraint 제약사항명 제약사항종류, << 컬럼 단위 제약사항   

   ...

   constraint 제약사항명 제약사항종류(적용컬럼) << 테이블 단위 제약사항   ...  

   );

 

 제약사항 종류 

1) primary key (주키, 기본키) - PK

null을 허용하지 않고, 컬럼의 값을 유일하게 저장해야할 때 (값이 반드시 있으면서 유일)

- 하나의 테이블에 하나의 PK만 존재할 수 있음

- PK는 n개의 컬럼으로 구성될 수 있음

- PK는 다른 테이블에서 foreign key로 참조할 수 있음

- 컬럼단위 제약사항과 테이블단위 제약사항으로 설정할 수 있음

- user_constraints에서 constraint_type : 'P'

- 테이블에 primary key를 설정하면 Oracle에서는 index가 자동 생성됨 (user_indexes data dictionary에서 확인 가능)

- 문법) 

  • 컬럼단위 제약사항(column level constraints)
    - PK를 하나의 컬럼으로만 구성할 수 있음
    - 컬럼명 데이터형(크기) constraint pk_테이블명 primary key, 
       --> PK인 컬럼명을 식별할 수 있음
  • 테이블단위 제약사항(table level constraints)
    - PK를 n개의 컬럼으로 구성할 수 있음
    - constraint pk_테이블명 primary key (컬럼명,,,) 
      --> 컬럼 정의와 제약사항 정의를 분리할 수 있음

* 테이블단위 제약사항에서 PK를 n개의 컬럼으로 구성하는 경우 

 - 생산물 추적(자동차의 리콜 LOT 번호 관리), 영화관 좌석 예매

     > 영화관의 좌석은 특정 시간에만 유일하다.

    > 1일에 1번 타임에 1좌석, 1일에 1타임에 2좌석은 OK . 1일에 1타임에 2좌석 또 하면 error

 

* constraint pk_테이블명 생략 가능 (하지만 PK,FK,UK는 다 준다고 생각하면 됨!!)

- Oracle이 제약사항명을 자동 생성하여 primary key를 설정함 (SYS_C...형태)

- 단, 제약사항명을 pk_테이블명으로 주지 않으면 무결성 제약조건 위배에 관한 error msg에서 오류 원인을 식별하기 힘듦

 

 

2) foreign key (외래키, 참조키) - FK

- 컬럼의 값을 다른 테이블(부모 테이블)의 값으로만 추가해야 할 때

- 하나의 테이블에서 여러 개의 컬럼에 FK를 설정할 수 있음

- null 허용

- user_constraints에서 constraint_type : 'R'

- foreign key가 참조하는 레코드가 존재하는 부모테이블의 레코드는 삭제되지 않음

  > 삭제 방법1) 참조하는 자식 레코드를 모두 삭제한 후 부모테이블의 레코드를 삭제

  > 삭제 방법2) 컬럼의 FK 부여시, on delete cascade 옵션 추가

- 컬럼 단위 제약사항과 테이블 단위 제약사항 두가지로 설정 가능

- foreign key로 설정하는 컬럼은 부모 테이블의 컬럼명과 같을 필요는 없고, 데이터형만 같으면 됨

- 문법) 

  • 컬럼단위 제약사항(column level constraints)
    > 제약사항 종류 명시하지 않음
    > 컬럼명 데이터형(크기) constraint fk_컬럼명 references 부모테이블명(참조할컬럼명) [on delete cascade]  
      --> FK는 테이블 하나에 여러 컬럼을 설정할 수 있으니까 테이블명 대신 컬럼명으로 제약사항명을 작성
      --> 다른 테이블에 동일 컬럼명의 fk가 존재한다면 충돌할 수 있으므로, 이때는 fk_테이블명_컬럼명 이렇게 작성
  • 테이블단위 제약사항(table level constraints)
    > 제약사항 종류를 명시함
    constraint fk_컬럼명 foreign key (적용 컬럼) references 부모테이블명(참조할컬럼명) [on delete cascade]
    --> FK 적용컬럼의 수와 참조하는 부모의 참조컬럼의 수가 같아야 함! PK처럼 한 번에 여러개 설정 불가!

 

3) unique 

null을 허용하면서, 유일한 값을 추가해야할 때 (null은 몇 개든 넣을 수 있음)

  (Ex. email 주소, 휴대폰 번호, 카드 번호 - 없을 수도 있지만 있다면 유일함)

- 하나의 테이블에 여러 개의 unique를 설정할 수 있음

- user_constraints에서 constraint_type : 'U'

- unique를 설정하면 index가 자동 생성됨

- 컬럼단위 제약사항, 테이블단위 제약사항 두 가지로 사용 가능

- 문법) 

  • 컬럼단위 제약사항(column level constraints)
    > 컬럼명 데이터형(크기) constraint uk_컬럼명 unique,
      --> UK도 테이블 하나에 여러 개의 컬럼을 설정하므로 컬럼명으로 제약사항명을 작성
            (uk_테이블명_컬럼명 이렇게 해도 됨)
  • 테이블단위 제약사항(table level constraints)
    > constraint uk_컬럼명 unique (적용 컬럼)

 

4) check 조건

- 컬럼에 원하는 범위의 값으로만 추가해야 할 때 설정 (연령 제한, 성별 제한 등)

- not null과 check 조건은 컬럼단위 제약사항으로, 제약사항명을 부여하지 않고 설정함

  > 둘다 테이블단위 제약사항으로 정의할 수 있으나 컬럼단위로 많이 함

  > 제약사항명 부여할 수 있으나 부여 X

- user_constraints에서 constraint_type : 'C'

- check 조건은 key가 아니라 check 종류

- 문법) 기본 : 컬럼명 데이터형(크기) check (컬럼명 조건) 

     > constraint 키워드 안 씀. 시스템에서 부여한 제약사항명이 부여됨

     > 컬럼명 : check 조건이 설정된 컬럼만(자신만) 정의할 수 있음 (다른 컬럼을 참조하여 설정할 수 없음)
     > 컬럼명 조건 ex. age between 1 and 10

        --> 조건 : 연산자 사용 (> < => ,,,,)

* 제약사항명 부여 : 컬럼명 데이터형(크기) constraint 제약사항명 check (컬럼명 조건)

    > constraint 키워드를 사용하면 됨 
    > ex) 성별컬럼에 M 또는 F만 입력 가능
       gender char(1) constraint chk_gender check (gender in (‘M’,’F’))
 

 

5) not null 조건

- 컬럼에 값을 반드시 입력해야 하는 경우 (정의되는 모든 컬럼에는 null이 생략되어 있음)

- 컬럼단위 제약사항으로 설정

create subquery로 복사되는 제약사항

   > not null만 제약사항 중에 유일하게 복사됨

   > pk의 기본 사항인 not null은 복사 안됨. 직접 not null이라는 check 조건을 부여해야 복사됨

- user_constraints에서 constraint_type : 'C' 

- not null을 nn으로 줄여쓰기도 함

- 문법) 컬럼명데이터형(크기) not null 

 

 

6) default

- 컬럼에 null이 입력되는 상황에서 null 대신에 들어갈 값 설정

  > null 입력은 컬럼 생략으로만 가능
      (문자열도 컬럼생략만 가능. ‘’empty 쓰면 default가 아닌 그냥 null이 입력됨)

- user_tab_cols data dictionary에서 확인 : data_default column에서 확인 가능

> default는 제약사항이 아니므로 user_constraints에서 확인 불가

> 컬럼정보를 가진 data dictionary에서 확인 가능

- 컬럼 단위의 문법으로만 설정 가능

- 문법) 컬럼명 데이터형(크기) default 기본값

 

 

** 제약사항 관련 data dictionary

- user_constraints data dictionary : 테이블에 걸려있는 constraints 확인 가능

- user_cons_columns data dictionary : 제약사항이 설정된 컬럼 확인 가능
                                                                               > constraints name 및 컬럼을 볼 수 있음

-  user_indexes data dictionary : 인덱스 조회 가능 (PK, UK는 생성하면 index가 자동생성됨)

'Development > Oracle' 카테고리의 다른 글

[Oracle] sequence  (0) 2021.09.30
[Oracle] alter  (0) 2021.09.29
[Oracle] union / join / driving table  (0) 2021.09.26
[Oracle] subquery / Scalar subquery / inline view  (0) 2021.09.24
[Oracle] function(함수)  (0) 2021.09.20

 1. union 

- 여러 개의 테이블의 조회 결과를 아래로 붙여서 조회하는 쿼리문

- 컬럼의 이름은 상관없음. (단, 조회되는 인라인뷰의 컬럼명은 첫 번째 쿼리문의 컬럼명이 나옴)

1) 조건

 ① 위 테이블의 컬럼 데이터형과 아래에 연결되는 테이블의 컬럼의 데이터형이 일치할 것

 ② 위 테이블의 컬럼 개수와 아래 테이블의 컬럼의 개수가 일치할 것
    > 테이블이 가지고 있는 컬럼 개수가 아니라 조회할 때의 컬럼 개수

2) 종류

- union : 중복 레코드가 출력되지 않음

- union all : 중복 레코드가 출력됨

3) 문법)

         select 컬럼명 ,,, from 테이블명 [where~group by ~ ,,,,]

         union [all]

         select 컬럼명 ,,, from 테이블명 [where~group by ~ ,,,,]

         union [all]

         select 컬럼명 ,,, from 테이블명 where~group by ~ ,,,,]

         .... 

 

** union은 컬럼을 조회하지 않고 고정값으로 조회할 수 있음

 - 원래 데이터가 있음에도 지정한 고정값으로 조회 결과가 합쳐짐

 - 고정값 지정 시 컬럼의 데이터형과 같은 형식으로 기입해야 함!

 - 없는 컬럼도 고정값으로 추가하여 조회할 수 있음

 

 

 

  2. join 

- 서로 다른 테이블을 합쳐서(옆으로 붙여서) 조회할 때 

- 정규화(normalization)가 진행되면 테이블이 분리되어 데이터가 저장됨

  => 쪼개진 데이터를 붙여서 가져오기 위해 join 수행

- oracle에서는 Oracle join문법ANSI join 문법을 제공함

=> ANSI(American National Strandards Institute) query는 모든 DBMS에서 사용가능(좀 길다)

- 종류 : inner join, outer join, self join, cross join(=full outer join)이 존재

- 주의

   ① 조인 조건을 잘못 설정하면 cartesian product(카티션 프로덕트)가 발생 (=데카르트 곱)

         => 모든 레코드가 곱해져서 결과로 생성됨 (이렇게 조회된 레코드는 난장판~)

   ② 조인의 키가 되는 driving table을 주의하여 선정 (속도의 차)

 

** driving table

- 조인 시 key가 되는 table

  (조인 조건 작성할때, ‘비교테이블 = 기준테이블’ 이렇게 작성 / 기준 table이 driving 테이블)

- 선정기준 : 부모(PK)-자식(FK) 관계라면 부모가 driving table

                    : 레코드의 건수가 적은 테이블

                    : 레코드의 수가 비슷하다면, 레코드의 다양성이 적은 테이블

- driving table을 잘 선정하면 검색횟수가 줄어서 속도가 향상됨!!

 

** equi join(등가조인) : 값이 같은 걸(=) 조인 조건에 넣는 것 (emp.dept no = dept.deptno)

    non-equi join : ‘=’ 연산자 이외의 비교 연산자를 사용하는 것

 

 

1) inner join

- 양쪽 테이블에 같은 컬럼 값이 존재하는 레코드만 조회

- 모든 레코드를 조회할 수 없음

- 문법)

ANSI ORACLE
select          컬럼명, 테이블명.컬럼명, alias.컬럼명
from            테이블명 alias
inner join  조인할 테이블 명 alias
on                조인조건 (alias 사용)

where         검색조건
select    컬럼명, 테이블명.컬럼명, alias.컬럼명
from      테이블명 alias, 조인할 테이블명 alias,,,
where    조인조건 and 검색조건

* on은 보통 key를 비교하게 됨 (PK나 FK)

* from의 테이블과 join 테이블의 순서는 상관없음 (어차피 같은 값 찾아서 조회하기 때문!)

 

 

2) outer join

- 한쪽 테이블에만 레코드가 존재하더라도 검색 가능

- outer join 종류 : left, right, full

   > 레코드가 존재하는 테이블을 선정하는 것 (잘못 선정하면 inner join과 같아짐)

   > 레코드의 구성을 알 때 : left, right / 레코드의 구성을 모를 때 : full

   > full outer를 사용하면 속도가 엄청 느려지고 순서가 뒤섞여서 잘 안씀 (oracle에서 full outer join은 지원 안 함)

- 문법)

* 주의) ANSI와 Oracle은 레코드가 있는쪽/없는쪽 사용이 다름

ANSI ORACLE
select                       컬럼명, 테이블명.컬럼명, alias.컬럼명
from                         테이블명 alias
종류 [outer] join  조인할 테이블 명 alias
on                             조인조건 (alias 사용)

where                     검색조건
select    컬럼명, 테이블명.컬럼명, alias.컬럼명
from      테이블명 alias, 조인할 테이블명 alias,,,
where   조인조건 and 검색조건
               -- 조인조건 : 레코드가 없는 쪽에 (+)
              

* ANSI) 조인할 테이블과 조회할 컬럼명에는 key가 되는 테이블을 사용해야 함

    > 부모 테이블과 같이 모든 종류의 레코드를 가지고 있는 테이블을 사용!

    > left outer join일 경우, from에 키가 되는 테이블

       right outer join일 경우, from 다음에 오는 조인 테이블에 키가 되는 테이블 기재

* oracle outer join) 조인 조건에 (+) 기호를 레코드가 없는 쪽 컬럼에 기술

    > driving table을 뒤에 배치하니까 웬만해서는 alias.컬럼명(+) = alias.컬럼명 (반대도 당연 가능)

    >> 단, (+)를 양쪽 모두에 붙일 수 없음 (oracle은 full outer join 지원하지 않음)

 

 

3) self join

- 하나의 테이블을 join하는 것 

- 테이블에 alias를 필수적으로 부여하고(테이블 식별), 검색목적과 조건목적으로 테이블을 구분하여 사용

> 조회목적 (조회하는 컬럼과 조인 조건에만 등장) / 조건목적 (조인조건과 검색조건에만 등장)

- 조인 조건이 다른 것을 가져오는 non-equi join을 많이 사용함 ('='인 equi join을 사용하면 쓰레기값이 나오기도 함)

- ANSI는 없고 Oracle query만 존재함

ORACLE
select     a.컬럼명 ,,,   -- 검색목적 테이블의 alias를 사용
from       테이블명 alias a (검색목적), 테이블명 alias b (비교/조건목적) ,,,
where    조인조건 and 검색조건   
                 -- 조인 조건은 보통 non-equi

                 -- 검색 조건은 비교목적 테이블의 alias를 사용

 

 


# 오늘의 코딩 #

- union과 join을 사용해보잣

 

#union

--emp : 본사, cp_emp4 : 지사

--------------------union : 중복 레코드가 출력되지 않음--------------------
--본사와 지사 사원을 조회 (단, 중복레코드를 조회하지 않아야 함)
select empno, ename, sal, hiredate, deptno
from emp
union
select empno, ename,  sal, hiredate, deptno
from cp_emp4;

#출력 결과#

-> 본사와 지사의 중복 값을 제외한 데이터들이 출력됨!

-> union all을 사용하면 중복 레코드도 출력된당

 


#join

- outer join을 ANSI와 Oracle 문법으로 사용해보장

----------------outer join-----------------
--제조사가 '현대'인 모든 차량의 모델명, 연식, 가격, 옵션을 조회해보자
--주의사항) 조회컬럼에 키가 되는 컬럼을 사용해야 결과를 얻을 수 있음

--<ANSI>
select           cma.maker, cma. model, cmo.car_year, cmo.price, cmo.car_option
from             car_model cmo
right outer join car_maker cma
on               cmo.model = cma.model
where            cma.maker = '현대';

--<Oracle>
select cma.maker, cma. model, cmo.car_year, cmo.price, cmo.car_option
from   car_maker cma, car_model cmo
where  (cmo.model(+) = cma.model) and cma.maker = '현대';

#출력 결과#

-> ANSI보단 Oracle 문법이 사용하기엔 간단하다

-> outer join이라 한쪽 테이블에만 값이 존재하더라도 모든 값이 나오는 것을 확인!

 

'Development > Oracle' 카테고리의 다른 글

[Oracle] alter  (0) 2021.09.29
[Oracle] 제약사항 (Constraint)  (0) 2021.09.28
[Oracle] subquery / Scalar subquery / inline view  (0) 2021.09.24
[Oracle] function(함수)  (0) 2021.09.20
[Oracle] select - where / group by ~ having / order by  (0) 2021.09.19

 subquery 

- 쿼리문 안에 (select) 쿼리문을 정의하는 쿼리문

- create, insert, update, delete, select에서 사용할 수 있음

- 안쪽 쿼리문이 한 행을 조회하는 단수행 서브쿼리(single row subquery)와

   안쪽 쿼리문이 여러 행을 조회하는 복수행 서브쿼리(multi row subquery)를 사용할 수 있음

=> subquery 문이 1행만 조회하는 거면 단수행 서브쿼리(single row subquery)
      여러 행을 조회하는 거면 복수행 서브쿼리(multiple row subquery)

 

 

1) create subquery

- 조회된 결과로 테이블을 복사할 때, 조회된 결과로 비어있는 테이블을 생성할 때

- 제약사항은 복사되지 않으나, not null 조건은 복사됨

- 복수행 subquery

- 비어있는 테이블(구조만)을 생성하기 위해서는 where절에 1=0(항상 거짓)로 기입하면 된당

    > where절에 해당하는 레코드만 검색되는 것이므로!

       (1=1은 항상 참으로 모든 레코드를 조회하고 1= 0은 항상 거짓으로 모든 레코드를 조회 X)

    > 1=1은 dynamic query문을 만들 때 동적 조건을 편하게 붙이기 위해 사용

- 문법) create table 테이블명 as (select ,,,) ; --> 원천 데이터가 조회된 결과로 테이블 만들쟈~

- 설정된 constraints(제약사항)은 user_constraints 테이블에서 확인할 수 있음

**user_constraints 도 data dictionary의 일종, dic objects

> 전체 제약사항 조회 : select * from user_constraints

 

 

2) insert subquery

- 다른 테이블에 존재하는 (또는 같은 테이블의 다른 컬럼) 값으로 insert 작업을 할 때

- 단수행 subquery와 복수행 subquery 사용 가능

   > 복수행 subquery는 정산작업할 때 많이 사용함

- select로 조회하는 컬럼명과 insert하는 컬럼명이 동일해야 함!

- 단수행 문법) insert into 테이블명 (컬럼명,,,) values ( (select,,,) ,,, )

  > 컬럼 하나에 레코드 하나 나와야 함 // Ex) select sal from emp where empno=7788

- 복수행 문법) insert into 테이블명 (컬럼명,,,) (select,,,)

  > 컬럼 여러 개에 레코드 여러 개 나올수있음

 

 

3) update subquery

- 다른 테이블의 컬럼 값으로 현재 테이블의 값을 변경해야 할 때

- 단수행 서브쿼리만 가능 (복수행 서브쿼리 사용하려면 in 씀)

   > =은 하나의 값만 비교할 수 있으므로 in 써야 함

- 문법) update 테이블명 set 컬럼명 = (select,,,) where 컬럼명 = (select,,,)

- update subquery에서 복수행 subquery를 사용하려면 in을 사용하면 됨

  > where empno in (select empno from emp where ename = 'ADAMS' or ename = 'SCOTT');

      또는 where empno in (select empno from emp where ename in ('ADAMS', 'SCOTT'));

 

 

4) delete subquery

- 단수행 서브쿼리만 가능 (복수행 서브쿼리 사용하려면 in 씀)

- 다른 테이블의 컬럼 값으로 현재 테이블의 레코드를 삭제해야 할 때

- 문법) delete from 테이블명 where 컬럼명 = (select,,,)

 

 

5) select subquery

- 단수행 서브쿼리와 복수행 서브쿼리 모두 사용 가능

- 단수행 서브쿼리 : 다른 테이블의 컬럼 값으로 조회, Scalar subquery 사용하여 조회

 

** Scalar subquery

- 조회되는 컬럼의 subquery를 사용하는 것

- 조회된 컬럼의 값으로 다른 테이블에서 조회하는 서브쿼리

- 서브쿼리만 별도로 실행될 수 없음

- 복수행 서브쿼리 : inline view를 사용한 조회 (조회된 결과를 가지고 재조회하는 것)

- 단수행 문법) select 컬럼명 from 테이블명 where 컬럼명 = (select)

- Scalar subquery 문법)

    select 컬럼명, (select 컬럼명 from 테이블명 where 테이블명.컬럼명 = 테이블명.컬럼명) from 테이블명

     >> Scalar 서브쿼리 안에서는 from에 있는 테이블명.컬럼명 먼저 써주고 나중에 전체 테이블명

- 복수행 문법)

  • where절 in : 여러 개의 값에 해당하는 레코드를 조회할 때
      > 문법) where in ( select … )
  • inline view를 사용한 조회 : 조회된 결과를 가지고 재조회할 때 사용
      > 문법) select 컬럼명 from (select ,,, ) where group by ~ 주고싶은거 다 주면 됨
      > 실제 테이블이 아닌 서브쿼리의 검색 결과(inline view)를 사용한 조회
      > 바깥 컬럼명은 실제 컬럼이 아닌 inline view에 의해 조회된 컬럼명을 사용해야 함 (또는 alias)
     

* inline view : select 쿼리에 의해 조회된 결과로 생성된 테이블
 
- 바깥 쿼리문은 inline view를 사용한 검색을 수행하므로 사용할 수 있는 컬럼은

    inline view에 나오는 컬럼만 사용할 수 있음 (컬럼명 동일해야 함, alias면 alias로 조회)

- inline view를 통해 재조회할 때, 안쪽 서브 쿼리에서 조회한 컬럼을 모두 사용할 필요는 없음

- inline view는 같은 쿼리 안에서 inline view를 중복하여 사용할 수 있음

 


# 오늘의 코딩 #

- select subquery를 해보자!

 

#단수행 subquery

-- 부서의 지역이 'DALLAS'인 부서에 근무하는 사원정보 조회
-- 조회컬럼 : 사원번호, 사원명, 부서번호, 연봉, 직무
select empno, ename, deptno, sal, job
from emp
where deptno = (select deptno from dept where LOC = 'DALLAS');

#출력결과#

-> where절의 select subquery의 연산결과로 추출된 deptno을 비교하여 필요한 정보가 출력된다!


#Scalar subquery

-- 사원테이블에서 사원번호, 사원명, 부서번호, 부서명 조회
select empno, ename, deptno,
       (select dname from dept where dept.deptno=emp.deptno) dename
from   emp;

#출력결과#

-> 사원 테이블에는 부서명이 없으나, 부서 테이블과 사원 테이블의 부서번호를 매칭하여 

일치하는 부서번호에 해당하는 부서명을 부서테이블에서 가져온당


#복수행 subquery

-- 사원테이블에서 부서의 인원수가 4명 이상인 부서의 사원정보 조회
-- 조회컬럼 : 사원번호, 사원명, 부서번호, 부서명, 연봉, 입사일
select empno, ename, deptno,
       (select dname from dept where dept.deptno=emp.deptno) dname
       , sal, hiredate
from   emp
where  deptno in (select deptno
			from emp
			group by deptno
			having count(empno) >= 4);

#출력결과#

-> where절에서 도출된 deptno은 복수이므로, in을 사용하여 복수행 subquery를 수행했다!

+ Recent posts