기타 오브젝트 ORACLE


1. 뷰
 테이블이나 다른 뷰를 기반으로 생성한 가상 테이블
 로우와 컬럼으로 구성
 실제 데이터를 가지고 잇지 않은 가상 테이블
 뷰의 기반이 되는 테이블이나 뷰를 원본 테이블이라고 한다.
 테이블과 마찬가지로 dml가능
 뷰에 수행한 변경 내용은 원본테이블에 적용
 보안의 강화/ 쿼리의 간결화가 유일이점

2. 머티얼라이즈드뷰
 구체화된 뷰
 인터널 테이블에 실제 데이터를 가지고 잇음
 변경도니 내용을 실제 테이블에 반영하려면 리프레시를 수행
 실제 테이블에 쿼리를 수행할 필요가 없음
 리프레시가 빈번하게 수행되면 부하가 증가
 인터널 테이블의 저장공간이 필요

3. 시퀀스 
 유일한 값이 연속되는 숫자를 생성
 트랜젝션의 롤백이 발생해도 시퀀스는 되돌아가지 않음

4. 시노님
 오브젝트 별칭
 보안성과 조작성 향상을 위해 사용

Oracle 인덱스 ORACLE


1. 인덱스 구조
 테이블의 로우에 엑세스하는것을 효율화
 컬럼 값을 가진 로우의 rowid를 알 수 있음
 인덱스를 생성하면 where절이 포함도니sql을 효율적으로 처리
 하나의 테이블에 만들 ㅅ수 있는 인덱스의 수에는 제한이 없음
 하나의 테이블에 만들 수 있는 인덱스의 수에는 제한이 없음
 사용하지 않는 인덱스나 잘못된 컬럼으로 구성된 인덱스는 디스크 공간을 낭비하고 성능의 저하를 가져올 수 있음
 데이터 분포로 인덱스 생성여부를 판단할 수 있다.
->딕셔러니뷰 확인(all_tables, all_tab_columns)

인덱스가 유리하지 않을때 (효율적이지 않을때)
 1. 컬럼의 효율성이 좋지않다고 판단.
 2. 인덱스를 통해 추출하는 데이터의 양이 많을 때
 3. 테이블의 데이터를 처리할 대 랜덤 엑세스 시 발생하는 어쩌구

인덱스의 종류
 1. B-tree인덱스(Balnanced)
확장성이 뛰어남
일반적으로 인덱스에서 키값을 찾는데 두세번의 I/O만 수행
양방향 linked list
인덱스 키 - Row가 1:1대응임
Unique인덱스 - 인덱스 키 값에 RowID를 추가하지 않는다.
Non-Unique 인덱스 - 인덱스 키 값에 RowID 추가 > 결과적으로 유니크하지 않은 Entry는 존재 하지 않음
Height : 루트 블록 > 리프 블록으로 이동하는데 필요한 블록 수
B level : 브랜치 블록 단계 숫자
인덱스 키 압축 : 복합 컬럼 인덱스의 중복 제거
 공간이 절약되지만 비용이 증가한다.
 I/O는 줄어들고 CPU이용률은 증가함
 이전보다 더 많은 인덱스 엔트리가 버퍼 캐시에 존재하여 적중률은 올라가지만 블록 획득을 위한 경합이 증가하여 CPU사용이 늘어난다.
리버스키인덱스 : 블록의 경합을 줄이기 위해 사용
내림차순 인덱스 : 인덱스를 역순으로 읽음
 2. 비트맵 인덱스
하나의 컬럼 값을 하나의 비트에 대응
and,or,not 과 같은 논리 연산을 사용하는 경우 유리
하나의 인덱스 엔트리에 많은 로우에 대한 포인터를 가지고 있음
전체 데이터에 비해 값의 종류가 겆ㄱ은 데이터에 유리
읽기는 유리하지만 쓰기는 적절하지 않음
비트맵 조인 인덱스 : 일반적인 인덱스와 달리 다른 테이블의 컬럼을 이용한 인덱싱이 가능
 3. 함수기반 인덱스
인덱스를 만들 때 컬럼 값 대신 지정한 함수의 결과가 저장
계산된 컬럼에 인덱스를 생성하여 사용하는 것
구현하기 쉽고, 효과를 즉시 할 수 있다.
기존 로직이나 질의를 전혀 바꾸지 않고 수행속도 개선가능
사용자 정의 함수를 적용할 때 성능 향상 효과가 뛰어남
권한에 시스템 파라미터 또는 세션 파라미터의 설정이 필요함
선택적 유일성이 구현 가능하다 > 제약조건 처리시 사용

 4. 어플리케이션 도메인 인덱스 
확장형 인덱스
데이터베이스에서 아직 제공되지 않는 인덱스 유형을 만들 때 사용
공개된 API사용하여 구현가능

인덱스 추가
 뷰에서도 인덱스가 사용되는가 ? > 뷰에 정의된 테이블에 대해 사용
 null과 인덱스는 함께 사용되는가 ? > null저장 : 비트맵인덱스 클러스터 비트리 인덱스 / null 저장 안함 : 비트리 인덱스
 참조키에는 인덱스가 생성되어야 하는가 > 부모테이블의 기본키를 수정할 때 자식 테이블에 걸리는 
 인덱스 공간은 재사용 되는가? > 인덱스 블록이 완전히 비워지면 재사용됨
    공간을 줄이지 않으니 피룡시 리빌트 해줘야함
 가장변별력이 있는 요소가 선두에 와야하는가 ? > 상관 없음 , 인덱스 키 압축시에는 유리함
 
인덱스 사용안하는 경우(못하는 경우)
 조건절의 컬럼이 인덱스 선투컬럼을 안쓰는 경우
 컬럼에 함수를 사용하는 경우
 숫자값 만을 가지는 문자 컬럼에 인덱스 생성한 경우
 로우 수를 셀 때와 같이 테이블 풀 스캔이 유리한 경우
 옵티마이저가 인덱스가 효과적이라고 판단하지않을 때
 오랫동안 통계정보를 수집하지 않은 경우



Oracle PL/SQL pipelined에 대해



CREATE TABLE typetbl(m1 NUMBER, m2 NUMBER)
/

CREATE OR REPLACE PACKAGE pkg IS
TYPE tbl_rec IS TABLE OF typetbl%ROWTYPE;
END;
/

CREATE OR REPLACE FUNCTION PTF(limit IN NUMBER)
RETURN pkg.tbl_rec PIPELINED
AS
  x typetbl%ROWTYPE;
BEGIN
  FOR i IN 1 .. limit LOOP
  x.m1 := i;
  x.m2 := i+1;
  PIPE ROW(X);
  END LOOP;
END;
/
--test Query
select * from TABLE(ptf(1000)) where m1 = 500
/
--ex) Pipeline함수를 통한 테이블 생성
create table test_pl as select * from table(ptf(500));

select * from test_pl;

Oracle의 Obejct ORACLE

오라클에서 말하는 오브젝트(객체)에 대해서 알아보자

1. table
 - 유효한값을 저장하기위한 객체
실제데이터관리를 할때 select만이아닌 삽입 변경 삭제등을 위한 객체생성시 table이 효율적임

2. index
 - 어떠한 테이블의 데이터와 주소값을 동시에 지니고 있는 객체
일부쿼리에대해 성능을 개선해준다. 자료의 빠른 검색을할때 사용한다.
UNIQUE 나 PRIMARY KEY사용시 index가 자동으로 생성된다

3. view
 - 어떠한 테이블의 제한적 조건으로 보여주는 테이블 객체
실체가없다(Logicall) 실제데이터관리를 할때 select만을 위한 객체생성시 view가 효율적임

4. sequence
 - 유일(UNIQUE)한 값을 생성해주는 오라클 객체이다.
시퀀스를 생성하면 기본키와 같이 순차적으로 증가하는 컬럼을 자동적으로 생성 할 수 있다.
보통 PRIMARY KEY 값을 생성하기 위해 사용 한다.
메모리에 Cache되었을 때 SEQUENCE 값의 액세스 효율이 증가 한다.
SEQUENCE는 테이블과는 독립적으로 저장되고 생성된다. 따라서 하나의 SEQUENCE를 여러 테이블에서 쓸 수 있다.

5. synonym
 - 오라클 객체(테이블, 뷰, 시퀀스, 프로시저)에 대한 대체이름(Alias)를 말하며, 실질적으로 그 자체가 객체가 아니라 객체에 대한 직접적인 참조 이다.




파일 입출력의 효과적인 방법 JAVA

★ 들어가며 
 선임개발자로부터 숙제가 들어왔다. 효과적인 파일 입/출력 프로그램을 만들어보라는 것이었다. 지금까지 자바를 이용한 파일 입출력은 그저 스트림을 이용해 연결하고, 아웃풋스트림을 이용해 붙여넣을 공간만 넣으면 알아서 척척 해내는 찍어 내기 식의 프로그램을 코딩해왔다.... 이 기회에 빠른 입출력을 위한 고민을 하게 됐고 지금 이 글이 그 실마리를 제공할 것으로 보인다.

Language: JAVA

Importpackage : java.nio


1.    요구사항 확인

-      파일 입/출력(복사)

-      커맨드입력을 통한 파일 복사

n  복사할 대상선택 : 경로를 포함한 파일명 입력

n  붙여넣을장소 선택 : 디렉토리 선택

-      예외 발생 시 예외 메시지 출력


2.    제약사항

-      1.5G 이상 복사 불가

 

3.    구조

-      Commend클래스

n  해당 프로그램의기본 명령어 실행

u  Ex> c:/Develop/test/test.jpg

u  Ex> c:/Develop/test

-      FileStream 클래스

n  선택한 파일과붙여넣을 경로의 디렉토리를 파일스트림에 연결한다.

-      FileCopy 클래스

n  NIO패키지의 채널을 이용하여 파일 복사 및 붙여넣기를 실행한다.


4.    Code

A.     Commend 클래스

public class Commend {

     

      public Stringinput(String cmd) {

             Scannerscanner = new Scanner(System.in);

             if(cmd.equals("sourceFile")){

                     System.out.print("복사할 대상을 입력하세요 : ");

             }elseif(cmd.equals("targetDirectory")) {

                     System.out.print("붙여넣을 경로를 입력하세요 : ");

             }else {

                     System.out.println("잘못된 명령어 입니다.");

             }

             return scanner.next();

}

 

B.     FileStream 클래스

public class FileStream {

      privateFileInputStream fis = null;

      privateFileOutputStream fos = null;

      private StringfileName = null;

      private Filefile = null;

     

      publicFileInputStream setFis(String sourceFile) throws Exception{

             file =new File(sourceFile);

             fileName=sourceFile.substring(sourceFile.lastIndexOf("/")+1,sourceFile.length());

             try {

                     if(file.isFile()){

                             fis= new FileInputStream(file);

                     }else{

                             thrownew Exception("FileInputStream exception : sourceFile(File notexist)");

                     }

             }catch(Exceptione) {

                     System.out.println(e.getMessage());

             }

             returnfis;

      }

     

      publicFileOutputStream setFos(String targetDirectory) throws Exception{

             try {

                     Filetemp = new File(targetDirectory);

                     fileName= System.currentTimeMillis()+fileName;

                     if(temp.isDirectory()){

                             fos= new FileOutputStream(targetDirectory+"/"+fileName);

                     }else{

                             thrownew Exception("FileOutputStream exception : targetDirectory(Directory notexist)");

                     }

             }catch(Exceptione) {

                     if(e.getMessage().equals("null")){

                             System.out.println("FileStream()Exception : NullPointException");

                     }

             }

             returnfos;

      }

     

      public voidclose() {

             try {

                     if(fos!=null){

                             fos.close();

                     }

             }catch(Exceptione) {

                     System.out.println("FileStreamclose() Exception : "+e.getMessage());

             }

             try {

                     if(fis!=null){

                             fis.close();

                     }

             }catch(Exceptione) {

                     System.out.println("FileStreamclose() Exception : "+e.getMessage());

             }

      }

      public StringgetFileName() {

             returnfileName;

      }

     

      publicFileInputStream getFis() {

             returnfis;

      }

}

 

C.     FileCopy 클래스

public class FileCopy {

      

       public Stringcopy(String sourceFile, String targetDirectory) {

             

              FileStreamfs = new FileStream();

             

              FileChannelfileInput = null;

              FileChannelfileOutput = null;

              StringfileName =sourceFile.substring(sourceFile.lastIndexOf("/")+1,sourceFile.length());

              System.out.println(sourceFile+ " / " + targetDirectory + " / " +fileName);

              longstart = System.currentTimeMillis();

             

                     

              try {

                      fileInput= fs.setFis(sourceFile).getChannel();

                      fileOutput= fs.setFos(targetDirectory).getChannel();

                     

                      ByteBufferbuff = ByteBuffer.allocateDirect(fs.getFis().available());

                     

                      fileInput.read(buff);

                      buff.flip();

                      fileOutput.write(buff);

                     

              }catch(Exception e) {

                      System.out.println("FileStreamExcepiont() : "+e.getMessage());

              }finally{

                      fs.close();

                      close(fileInput);

                      close(fileOutput);

              }

             

              System.out.println((System.currentTimeMillis()-start)/1000);

              return"파일복사가 완료 되었습니다.";

       }

       private voidclose(Closeable obj) {

              try {

                      if(obj!= null) {

                              obj.close();

                      }

              }catch(Exceptione) {

                       

              }

       }

}

 

5.    개선사항

A.    요구사항을 정확히 확인 후 설계한다.

B.     설계 후 코드 작성에 돌입한다.

C.     객체화(모듈화)하여작성한다.

D.  대용량 파일을 처리하기위해선 스트림에 연결된 파일을 분할하여 처리 할필요가 있으며, ByteBuffer의 put과 get을 이용해 가능할 것으로 보인다.


1