62일: Oracle - index, 제약조건, 번호, join, rownum

Jiwontwopunch·2022년 2월 11일
0

국비기록

목록 보기
62/121
post-thumbnail

2022.02.11.Fri.

✍ 복습

DB

인덱스

  • cluster 인덱스 : 책으로 치면 목차. 인덱스와 데이터의 순서가 일치(하나만 존재가능) → 기본키
  • non-cluster 인덱스 : 책으로 치면 찾아보기. 인덱스와 데이터의 순서가 일치하지 않는다.

테이블을 만들 때 제약 조건

개체무결성

  • 기본 키는 필수입력이고 중복 불가능, cluster 인덱스 생성
  • 가장 많이 검색할 컬럼을 기본 키로 설정
  • 복합키를 기본키로 지정하려면 테이블 레벨만 가능하다. 복합 기본키는 인덱스가 컬럼 순서대로 만들어진다. 첨부파일이라면 : constraint attachment_pk primary key (글번호, 첨부파일번호) 글번호를 찾아야만 첨부파일번호를 인덱스를 타고 검색할 수 있다. 하나의 예로 select*from 첨부파일 where 첨부파일번호=? → 인덱스를 탈 수 없다.

참조무결성

  • 둘 이상의 테이블을 함께 검색하려면 join 작업이 필요
    select*from emp, dept; 56개 → 가능한 조합을 모두 출력 emp가 14명, 부서가 4개 → 가능한 모든 조합 출력해서 56이 출력
  • jion을 하려면 두 테이블 사이에 연결고리가 있어야만 한다. → 외래키
    select*from emp, dept where emp.deptno=dept.depno;
  • 부서 테이블의 기본키를 사원 테이블이 참조하고 있다라고 한다면, 1:N 에서 1인 쪽의 기본키를 N쪽에서 읽어간다. 1:1이라면 아무쪽이나 한쪽을 다른쪽에서 읽어간다.

번호

단순히 행을 식별하기 위해 사용

  • 중간에 숫자가 비어있어도 상관없다 → sequence를 사용
  • 중간에 번호가 비면 안된다 → select max(bno)+1 from 게시판;

JOIN

  • 테이블의 설계가 잘못되면 운영할 때 이상 현상(anormaly)이 발생 : 삽입 이상, 삭제 이상, 갱신 이상
  • 이유 : 하나의 테이블에 서로 다른 정보를 마구 모아놨다. → 테이블을 분리해야 한다. → 정규화 작업 → 조인이 필요
  • 테이블에 문제가 있으면 테이블을 분리 → 정규화 normalization
  • 정규화를 하면 테이블의 개수가 늘어난다.
  • 정규화를 하면 테이블의 개수가 늘어난다 → 여러 테이블에서 검색하는 join 작업이 필요
  • 조건이 없으면 행의 개수(cardinality)는 곱셈(cross join)

조인할 때는 반드시 조건이 있어야 한다 → 두 테이블 간에 공통 컬럼이 필요(외래키)

1:N에서 1인 쪽의 기본키를 N인 쪽이 참조한다.

JOIN의 종류

  • cross join : 두 테이블 사이에 조건이 없는 경우에 발생하는 비극..절대 발생하면 안 된다.
  • inner join : 두 테이블에서 조건이 성립하는 경우만 출력
    - equi join : 조건이 =
    - 비 equi join : 조건이 =가 아니다
    Q. gogak 테이블과 gift 테이블을 조인해 고객번호, 고객명, 포인트, 상품을 출력하시오.
    select g1.gno, g1.gname, g1.point, g2.gname from gogak g1 inner join gift g2 on g1.point between g2.g_start and g2.g_end;
    Q. 10번 부서 사원들의 사번, 이름, 급여, 급여등급
    급여등급은 salgrade → 범위로 조인하려면 비동등 조인
    select e.empno, e.ename, e.sal, s.grade from emp e inner join salgrade s on e.sal between s.losal and s.hisal where e.deptno=10
    Q. DALLAS에 근무하는 사원들의 사번, 이름, 급여등급을 출력하시오.
    hint1. A,B, C 세 테이블이 있을 때 조건은 2개(A와 B, A와 C)
    hint2. 조건이 지정되지 않은 테이블은 cross join
    select * from emp e inner join dept d on e.deptno=d.deptno inner join salgrade s on e.sal between s.losal and s.hisal;
  • outer join : 조건이 성립하지 않는 경우도 출력
  • self join : 자신과 자신을 조인(ex 상품카테고리)
    self 조인을 왜 사용하나? 학생이 있고 반장이있다. 반장도 학생이다. 사원이 있고 관리자가 있다. 관리자도 사원이다.
    select * from category major, category minor where minor.parent=major.ccode;

    Q. emp에서 사번,이름, 관리자 번호, 관리자 이름을 출력하시오.
    select emp.empno, emp.ename, manager.empno, manager.ename from emp, emp manager where emp.mgr=manager.empno;
    Q.관리자인 사원을 출력하시오.
    select distinct m.* from emp e, emp m where e.mgr=m.empno; select distinct m.* from emp e inner join emp m on e.mgr=m.empno

inner join, equi join

조인할 때 테이블의 교집합을 뽑아내는 조인은 inner join(내부조인), inner join 중에 조건이 =인 조인을 equi join(동일조인, 동등조인)이라고 한다.

오라클 비표준 조인
select * from emp e, dept d where e.deptno=d.deptno;
SQL 표준 조인
select * from emp e inner join dept d on e.deptno=d.deptno;

JOIN 정리

교수                  학생
교수번호  이름         학생번호   이름      지도교수번호
   1    양미진         111      홍길동        1
   2    김길동         122      전우치        1
                      113      임꺽정       null

cross join은 발생하면 안된다.
inner join : 교수와 학생간에 관계를 만족하는 행만 출력, 행개수 6
select * from 교수, 학생 where 학생.지도교수번호=교수.교수번호
outer join : 관계를 만족하지 않아도 출력

  • 왼쪽 외부 조인 : 교수를 다 출력
  • 오른쪽 외부 조인 : 학생은 다 출력
  • full outer join : 양 쪽 모두 다 출력

<오라클 기준>
inner join에서 비교를 =로 하는
select * from emp, dept where emp.deptno=dept.deptno;
inner join에서 비교를 =로 하지 않는
select * from emp, salgrade where emp.sal between salgrade.losal and salgrade.hisal;
right outer join → (+)를 왼쪽에 붙인다.
select * from emp, dept where emptno(+)=dept.deptno;
left outer join → (+)를 오른쪽에 붙인다.
select * from dept, emp where dept.deptno=emp.deptno(+);

  • 조인을 하려면 양 테이블 사이에 공유하는 컬럼이 있어야 한다. → 참조하는 컬럼(외래키)

  • 참조하는 값, 즉 외래키의 값이 null은 가능

  • 내부 조인을 하다 보면 조건을 만족하지 못하는 행들이 사라진다. 이때 외부조인으로 바꿔줘야 한다.

  • 오라클 외부조인과 sql 표준 외부조인의 차이
    : 오라클은 full outer join이 불가능

rownum : 행번호(오라클이 만드는 가상 컬럼)

select * from emp where rownum=1; 은 출력되나 rownum=2는 출력되지 않는다. 왜?
where는 조건절이라 rownum=1 현재 첫 번째글이 출력된다. (하지만 우리는 현재 값을 알 수 없다) 첫 번째행은 버리게 된다. 다 1이다.

rownum은 1등이 있어야 2등이 있고, 2등이 있어야 3등이 있다.그래서 rownum의 경우 조건을 걸때는 select * from emp where rownum<=2; 이런식으로 작성해야 한다.

0개의 댓글