db

http://blog.naver.com/hanorom?Redirect=Log&logNo=100003734568

 

 

http://blog.naver.com/hanorom?Redirect=Log&logNo=100003734568 <--요걸 응용 하면.. select 처리를 유연하게 할수 있을듯!!

 

was

http://blog.naver.com/PostView.nhn?blogId=leeyoon0607&logNo=70089532141&parentCategoryNo=52&categoryNo=&viewDate=&isShowPopularPosts=true&from=search

 

볼 내용이 상당히 많음!

 

아 글고.. 원격(remote)자원을 내 로컬에서 사용하는 것처럼.. 편히 쓸수 있게 하는 인터페이스가..머였드라?

java naming directory interface 인가?  요게 내부적으로 rmi를 래핑한거였나?? 아.. 기억이 잘 안난다...;;

 

http://blog.naver.com/kookh1?Redirect=Log&logNo=120202342605

조금 어려운 개념은.. 인터페이스 클래스와 구현클래스의 분리, 클라측에 인터페이스 클래스 정보만 노출하고

실제 구현 클래스의 정보는 클라의 요청시 직렬화 해서 넘겨줌. 클라는 인터페이스를 통해.. 내부 구현은 몰라

도 다형성(rtti.. 동적 바인딩)을 통해 실제 원격 객체의 서비스를 사용이 가능..

 

이걸 간단히 래핑한게.. 자바의 네이밍 디렉토리 인터페이스인듯~ 실제 안써봐서 모름;;

 

 

by givingsheart 2014. 1. 9. 14:28
심심해서 예전에 전혀 감을 못잡았던.. 머지소트 조인을 찾아보다 찾은 블로그;; (db.. 묵혀둬서 미안하다;;)

http://blog.naver.com/thesot?Redirect=Log&logNo=70130988563



웹 해킹관련.. (이것은 나~중에..)



(추가)

DB를 포기해야 한다. 혼자서 모든걸 할수가 없다. 이러다간 죽도 밥도 안된다.

by givingsheart 2014. 1. 2. 09:39


1.db드라이버님께 커넥션 얻기
2.커넥션님으로부터 쿼리객체 얻기
3.쿼리에 세팅
4.쿼리 발송
5.(blocking)리절트셋 얻기 or 익셉션
6.감사한 마음으로 리절트셋님, 쿼리 객체님 , 커넥션 객체님 bye
7.내 app에서 편하게 쓸라면
List<object[]> records=new ArrayList<object[]>();
while(resultSet.next())
{    
int cols = resultSet.getMetaData().getColumnCount(); <--metadata가 포인트!(패킷다루기
 ) 예전에.. 전체 집합에서 특정 조건에 해당하는 집합을 리턴하는 메서드를 만들때.. 방법이 1.조건
에 맞는 집합의 크기를 센후, 리턴할 집합을 할당후, 다시 전체를 조회하면서 리턴할 집합에 값을
넣기, vs 2.내가 1이 신경질나서 연결리스트로 리턴할 집합을 할당후.. 걍 추가.. (당근 성능 떨어
짐.)  vs 3.위의 방법 처럼 메타 데이터 사용!  vs 4.db 내장 프로시저를 사용.. ex) select
count(column_pk) from tableName 해서 레코드의 수를 알아내고 그만큼 할당.. 퍼포먼스는
어떤지 모르겠음.
    Object[] arr = new Object[cols];
    for(int i=0; i<cols; i++){
      arr[i] = resultSet.getObject(i+1);
    }    
records.add(arr);
}

8.로우(레코드=인스턴스=Object[]) 단위로 쉽게 관리가 가능

9.감사한 마음으로 종료 bye





by givingsheart 2014. 1. 2. 09:26

조인을 할때 where절에서 1. 특정 칼럼(인덱스..pk,중복키,결합키등 조건을 지정.. 우선순위는 점조건->선분조건)을 정함으로서 

dmbs가 해당 테이블에서 어떠한 로우에 엑세스해서 임시메모리에 올릴지 알려줘서 dbms가 실제 파일 데이터를 엑세스할 범위를 좁히고 , 2.추출된 임시 테이블의 로우(or인스턴스들) 에 대해 조인을 할 부모 테이블 전체(모든 row) 조회할때, 해당 컬럼의 값을 조건 연산자로 추가(일반적으로 교집합 AND) 해줌으로서 내가 전달 받을 결과인 n개의 테이블에서 추출한 교집합 resultset를 만들어 내는것!

(ex) 직원 테이블을 자식 테이블로 해서 뒤에 지정할 조건에 일치하는 모든 직원의 사번과 이름을 가져오는데  .. 조건1.부서가
 "경리부"일인 모든 직원들에 대해(직원테이블과 부서테이블의 AND 교집합인 임시 테이블.. 해당 부서 테이블에 엑세스할때도 인
덱스정보(fk가 pk이냐..uk이냐..중복키이냐에 따라 다양한 결과 발생) -> 조건2. 조건 1에서 추출한 임시 테이블에 대해 연봉이 "5000만원" 이상일것(직급,호봉별로 연봉이 정해져 있다면 연봉 테이블이 존재할테고.. 테이블을 어떻게 설계했느냐에 따라 다를테지만, 또한 1에서 추출한 임시 테이블에 대해 AND 교집합)


*************************************************
인덱스를 결정한다에 대해 고민을 더 해보자.. 

예를 들어
파일에 dataMatrix[ROW][COL] 이 있을때..

해당 데이터를 어떻게 접근해야 디스크 i/o 효율이 좋을까? 행단위 , 열단위?
for(int row = 0; row < rows.size; row++) <-- 엑세스 단위로서 outter
    for(int col = 0; col < cols.size; col++) <-- 엑세스 단위로서 inner
        data = dataMatrix[row][col];    VS  data = dataMatrix[col][row]; 

위의 고민이 테이블간 조인에서 outter, inner 의 결정에 따른 퍼포먼스적 고민이라 생각한다.

(etc)
배열의 경우는 생성한 인스턴스들의 주소가 물리적으로 연결된 자료구조이지만, 연결리스트의 경운 인스턴스 간에 
물리적으로는 제각각의 위치이지만, 논리적으로 연결된 자료구조이며, 맵,셋등의 계열은 인스턴스 간에 물리적으로 
제각각의 위치이지만, 그것이 저장된 실제 주소를 배열로서(인덱스) 관리하는 자료구조이며, 트리의 경우(이진 밸런스의 경우)
엔 배열 자체의 시작점 -> 종료점(0~50000인덱스)까지 해당 index를 찾는 접근 방법이 아닌, 내가 찾는 인덱스가 
31234 라면   0~25000까지의 노드, 25000~50000까지의 노드중 우측 노드로 분할 정복하여 다음 단계(재귀)
에서는 25000~37500까지의 노드, 37500~50000까지의 노드중 좌측 노드로 분할 정복하여 다음 단계(재귀)
에서는 25000~31250까지의 노드, 31250~37500까지의 노드중 좌측 노드로 분할 ...(생략) 

식으로 자료의 양이 많아질경우 퍼포먼스가 자료의 수에 대해 log 자료의 수 로서 일정 값에 수렴하게 된다. (로그 = 루트의
개념 vs 지수 = 제곱근의 개념)


******************************************************

파일에 대한 엑세스를 최소화 한다는 것에 대해 고민을 해보자.

파일을 읽어와 메모리에 적재할때 i/o최소화를 통한 효율 상승을 위해 인접 블럭 단위로 크게 읽어와 메모리에 적재한다.

이 개념은 resultSet을 만들때 selete 절을 어떻게 구성할 것이며, from절에서 조인하려는 테이블에 대해 제한 조건을 줄것
이며, where 절에선 from절에서 추출한 임시 테이블에 AND 서브쿼리의 결과를 통해 얻어진 

추후 생각나면 정리.. 급한일 생김 -_-;


by givingsheart 2014. 1. 2. 09:09
java로 생각한 초간단 조인의 개념 

Class 직원
{
int id;
int department_id;
String name; 
직원(int id){ this.id = id;}
void setDeparment_id(int department_id){ this.department_id = department_id; } <-- null 허용 + agreegation아 아닌, 
                                                                                                                     association 이기에 setter
}

컨테이너 클래스 직원List
ArrayList<직원> list직원 =  new ArrayLsit<직원>(100);

for(int id=0; id<list직원.size; id++)
list.append( new 직원(id, (int)(Math.rand()*10 + 1) );  //유일한 직원 인스턴스 생성해서 컨테이너에 추가


Class 부서
{
int id;
String address; 
부서(int id){ this.id = id;}
}

컨테이너 클래스 부서List
ArrayList<부서> listB =  new ArrayLsit<부서>(10);

for(int id=0; id<list부서.size; id++)
list.append( new 부서(id));   //부서 종류별 유일한 인스턴스 생성해서 컨테이너에 추가


컨테이너 클래스 list직원이 컨테이너 클래스 list부서에 대하여
참조할수 있는 필드(fk = department_id)를 바탕으로 비교 연산을 수행한다.

=이중 반복문

Set<Entry<직원이름,부서주소>> set = new Set<Entry<직원이름,부서주소>>();  //리절트셋

for(직원 a : list직원)    <-- from 절 
                (1) 개념 간단화를 위해 생략
      for(부서 b : list부서)  <-- from 절
         if( a.departmet_id == b.id)  <-- where 절 중 equal 비교 연산    <-- 만약 요 조건절이.. 유일키(uk)가 아닐경우.. 
                                                                                                  리스트 생성후 한번 더 루프
          set.add( a.name + b.address) ; <-- 여기가 select 절에서 선언한 리절트셋 형태
                                                
      (1)물론 요 라인에서 selete절에 포함시킨 내가 얻어올 컬럼들 1~컬럼수 만큼 반복문이 포함될테고..
          if( a.id == 3) <-- 이건 selete절에서 인라인 쿼리(특정 조건에 맞는 로우를 추출)인가를 사용햇을때 일테고.. 
                              3번 직원(물론 모든직원을 검색할지, 특정 3번 직원을 검색할지는.. 상황따라)       
      (2)카티션 곱이란..
      if(a.departmet_id == b.id) 가 빠졋을 경우..  직원의 인스턴스(row=레코드) 갯수 * 부서의 인스턴스(row=레코드) 갯수만큼의
      return 결과가 발생함.  return 결과는 resultSet 개념이고.. 

이게 중첩 루프 조인인듯 하고..(아님 말고 -_-;) 그 외에 해쉬 조인, 머지 소트 조인의 경우는 아직 모르겟다 ;;
일단 해쉬는 문자열등 긴 데이터를 ->(가급적 중복안되는) 짧은 숫자로 사상시키는 건데..
머지 소트는 기억 진짜 안남;; 

selete 쿼리에서.. selete 절의 의미는! 테이블도, 컬럼도, 조건도 뭣도 아닌.. 말 그대로 dbms에게 파일에서 메모리로 읽어올
타입(리절트셋 테이블)에 대한 선언이며, 또한 dbms 에게 리턴할 값에 xx 작업 명령을 한다는 의미인것 같다.

from 절은 실제 파일에 접근할 위치를 지정하는 것이고
where 절은 접근한 파일들에 대해 조건(제약=추출)을 거는 것이고..

왜 selete만 dql 이고,.. 그외에 insert , update, delete 는 dml인지를 이해해야한다! ddl은 논외


그럼으로 아래의 코드는 이해되어야 한다.

insert /*+ append */ into t1 
  아래는 values 대신 .. 서브 쿼리를 사용한다.
  select  rownum,    <-- selete 절은 내게 리턴할 결과 값의 형태(templet)에 대해 내가 지정할수 있는 구문.
  mod(rownum, 1000),      <-- 1000으로 나눈 나머지
  floor((rownum-1)/1000),   <-- 소숫점 버리기: 로직이 멋짐.. 예전 floor 할때 + 좌로 시프트하고 + 0.5 한후에 
                                                                                           우측으로 시프트하고 (int)로 형변환 했던 방법
  lpad('x', 1000, 'x')  <-- LPAD 함수설명 LPAD함수는 문자열이 일정 길이(byte)가 될 때까지 왼쪽에 특정 문자를 덧붙인다.
                                     구문 LPAD(char1,n, [,char2] ) 
  from   <-- from 절이 실제로 파일의 물리적 주소에 접근할 위치 지정
    all_source a1, all_source a2 
       where rownum <= 1e6;     <-- 물리적 주소에 접근해서 메모리(selete절)로 읽어들일지 말지의 조건문이지만
                                              당연하게도 카티션 곱이 일어난다.
****************************************************


(etc)쿼리 최적화 관한 오라클 문서

*******************************************************
오늘 오라클 내장 메서드를 배우던중에..

의문점이. 데이터에 대한 조회 업무 외의 작업인.. 데이터 가공 to_char(format) to_date(format)

등의 업무가.. dbms의 몫인가?  db에 요청하는 app측의 몫인가에 대한 의문이었다.

이건 거의 예전에 프로젝트했던.. word 객체가 .. 다형적 타입의 format 객체를 주입받아(stratergy= 동적으로
객체의 행동을 바꿔줄수 있음.. 인터페이스는 그대로)패턴..  자신의 print에서 {format.printf(msg) 처럼 포맷 
객체에게 일을 시키는 느낌인데} 

또한 위의 느낌은.. jsp 페이지에서 ejb 또는 사용자 정의 태크or jsp 내장 태그를 이용해..
프리젠테이션과 비지니스를 분리하는 것과 같은 느낌 아닌가???

하여간.. 아직 책임영역.. dbms가 자신의 존재 이유인..데이터의 관리에 과연.. 프리젠테이션 처리가 필요할지에 
대한 위의 의문은 안풀렸고... <-- 선생님 말씀으론 가급적 내장 함수 안쓰고  app가 가공하는게 낫다고 하심!


*************************************************************************
(etc)오라클이 제공하는 사용자 정의 함수의 장점 설명..



SELECT 절에 붙는 논리적 테이블(hdd가 아닌 메모리)인 리절트셋 = 값에 대해서.. (char_to()등으로 표현까지 정해줄수있다)
FROM 절은 접근할 물리적 테이블을 지정할수 있는 키워드 이고(cf:DUAL 은 더미 테이블.. 의미 없다)
WHERE 절은 물리적 테이블에 대한 접근 조건이랄까? .. 한마디로 hdd에 대해 memory로 가져올 조건을 지정할수 있고

그외에 아래는 값들의 집합의 표현을 어떻게 지원할 것인지에 대한 것들..
GROUP BY 절은 위에 WHERE 절을 통해 추출할 SELETE 뒤의 논리적 테이블에 대해서.. 그것을 특정 컬럼에 대해서
그룹화해서 논리적 테이블을 구성하겠다는 키워드이고..
HAVAING 의 경우 그룹 메서드를 통해 추출한 그룹화된 값들에 대해  논리 조건등을 추가로 설정할 수 있는 키워드



*************************************************************

조인의 경우..

 SELECT e.first_name, e.last_name, e.salary, d.department_name
      FROM hr.employees e, hr.departments d
       WHERE d.department_name IN ('Marketing', 'Sales')
       AND e.department_id = d.department_id;
       
    이 쿼리의 플랜은 
      ------------------------------------------------------------------------------------------------
      | Id  | Operation                    | Name              | Rows  | Bytes | Cost(%CPU)| Time      |
      -------------------------------------------------------------------------------------------------
      |   0 | SELECT STATEMENT             |                   |    19 |   722 |     3   (0)| 00:00:01 |
      |   1 |  NESTED LOOPS                |                   |       |       |            |          |
      |   2 |   NESTED LOOPS               |                   |    19 |   722 |     3   (0)| 00:00:01 |
      |*  3 |    TABLE ACCESS FULL         | DEPARTMENTS       |     2 |    32 |     2   (0)| 00:00:01 |
      |*  4 |    INDEX RANGE SCAN          | EMP_DEPARTMENT_IX |    10 |       |     0   (0)| 00:00:01 |
      |   5 |   TABLE ACCESS BY INDEX ROWID| EMPLOYEES         |    10 |   220 |     1   (0)| 00:00:01 |
      -------------------------------------------------------------------------------------------------
 
      Predicate Information (identified by operation id):
      ---------------------------------------------------
         3 - filter("D"."DEPARTMENT_NAME"='Marketing' OR "D"."DEPARTMENT_NAME"='Sales')
         4 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")


***************************************************************
아참. 깜박했는데. DBMS의 경우 일반적으로 제일 잦은 연산인 데이터에 대한 빠른 접근 = 조회
를 위해.. 자료 구조중 이진트리(b tree) 형식으로 접근 주소 인덱스 테이블을 구성하는듯 하다. 
(밸런스드 형태..) (물론 각각의 데이터들의 실제 메모리상 위치야 제각각 일테지만..주소만 인덱스를 사용해
트리형태로 구성해주면.. ok지~)

그렇기에 서치가 빠르고, 아.. 머리가 안돌아간다.. 나중에 좀 더 생각해볼것! 
(인덱스의 이해, 조건절을 제대로 구성한 다는 것이 어떠한 의미일지에 대해..)

내가 원하는 결과를 얻기위해 특정 테이블을 선택하고.. 다른 n개의 테이블을 조인해야 할때..

테이블을 조인하는 '순서'에 따라.. fatorial(n) 의 경우의 수가 발생하고
각 테이블마다 인덱스 사용의 true/false에 따라.. 2의 n승의 경우의 수가 발생하고
조인 방식의 종류인.. 해쉬조인,중첩루프조인,머지소트 조인;;; 에 따하 3의 n승의 경우의 수가 발생한다고
한다.. OTL 


1.인덱스 접근 방식
    (1) range 스캔 (possible duplicated column key)
    (2) unique 스캔 (pk,uk.. 영어도 못하는데.. 걍 한글로 쓰자 -_-;)
    (3) full 스캔
    (4) fast full 스캔
    (5) skip 스캔 (!=)
    (6) min/max 스캔
    (7) index Join


(etc)http://prayyou.egloos.com/viewer/1799600   이해가 안간다.. 속상하다 ㅠㅠ

보통 매우 큰 인덱스를 Range/Full/Skip scan을 한 후 테이블 Access를 수항하면, 엄청난 양의 Single Block Read가 발생합니다. 

클러스터링 Fact에 따라, 
Index Leaf Block 의 Rowid 갯수에 따라 Table lookup 발생하면서 Table Block Read가 발생합니다. (내 예측이 맞았는듯.. 인덱스는 이진 트리로 구성하고..거기에 실제 파일 데이터를 연결 리스트or 리스트

형식으로 배치한듯..)
순차적 수행 플랜의 경우, 쿼리 성능은 Single Random table Read가 얼마나 빠른가에 좌우 되었습니다.

만약 단일 블록 하나를 읽는데 5ms 이 필요하다면, 1000 block을 읽는데 약 5초 정도가 소요됩니다. 
다만 여기에서도 
스토리지 시스템이 동시 IO 요청을 처리할 수 있으며, 최종 사용자 세션이 필요한 블록을 동시에 수행하는 어떤 방법이나, 병렬로 처리할 수 잇따면
OS와 스토리지와의 연결 상에서 부하가 될 수 있겠지만 사용자는 더 짧은 시간에 결과를 받아 볼 수 있습니다.



오라클은 어떻게 IO를 최적화했는가?

현재까지 제가 아는 한, 오라클은 12.1 버전 이전에서도 몇가지 교묘한 방법으로 IO를 다루어 왔습니다. 아래는 그 몇몇가지 방법입니다.

- Nested Loop Join 에해서 오라클에 사용자에 대한 몇가지 전략이 사용됨 : NL-Join Batching 과 Table Access를 Join 밖으로 이동시켰습니다.

     --NL-JOIN Batching (http://docs.oracle.com/cd/E11882_01/server.112/e41573/optimops.htm#PFGRF94642)
     
     
11g에서는 Physical IO의 지연을 감소시키기 위하여 NL Join 에 대한 새로운 방식을 소개합니다. 
     Table Block 이나, index Block이 Buffer Cache에 존재하지 않지만, Join 에 필요한 경우 Physical IO가 필요합니다. 
     오라클 데이터베이스 11g는 한번에 하나씩 처리하는 대신 여러 Physical IO 요청을 묶어 Vector IO를 사용하여 처리할 수 있습니다.

     


이전 버전의 Exeution Plan에서 한 line으로 나타났던 Nested Loop Join의 Row source가 두번의 Nested Loop Join Row source로 나타나게 되었습니다. 
     이 경우, Oracle 데이터베이스는 첫번째 NL Join Row source를 Inner 쪽 인덱스와 Outer 쪽 Table에 Join 으로 할당합니다. 
     두번째 Row Source는 index에 저장된 Rowid를 포함한 첫번째 join 결과 set과 Inner 쪽 Table사이의 Join 에 할당합니다.
     
     즉, 
     SELECT e.first_name, e.last_name, e.salary, d.department_name
      FROM hr.employees e, hr.departments d
       WHERE d.department_name
 IN ('Marketing', 'Sales') <-어제 봤던 부분..  IN(a or b)키워드= 풀스캔..
       AND e.department_id = d.department_id;
       
    이 쿼리의 플랜은 
      ------------------------------------------------------------------------------------------------
      | Id  | Operation                    | Name              | Rows  | Bytes | Cost(%CPU)| Time      |
      -------------------------------------------------------------------------------------------------
      |   0 | SELECT STATEMENT             |                   |    19 |   722 |     3   (0)| 00:00:01 |
      |   1 |  NESTED LOOPS                |                   |       |       |            |          |
      |   2 |   NESTED LOOPS               |                   |    19 |   722 |     3   (0)| 00:00:01 |
      |*  3 |    TABLE ACCESS FULL         | DEPARTMENTS       |     2 |    32 |     2   (0)| 00:00:01 |
      |*  4 |    INDEX RANGE SCAN          | EMP_DEPARTMENT_IX |    10 |       |     0   (0)| 00:00:01 |
      |   5 |   TABLE ACCESS BY INDEX ROWID| EMPLOYEES         |    10 |   220 |     1   (0)| 00:00:01 |
      -------------------------------------------------------------------------------------------------
 
      Predicate Information (identified by operation id):
      ---------------------------------------------------
         3 - filter("D"."DEPARTMENT_NAME"='Marketing' OR "D"."DEPARTMENT_NAME"='Sales')
         4 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
         
         
         
        로 수행됩니다. 

   이 경우, HR.department Table의 row 는 첫 번째 Join의 Outer Side로되며, 첫번째 Join의 Inner Side는 Index EMP_DEPARTMENT_IX가 됩니다.
      첫 번째 Join 의 결과집합은 다시 두번 째 Join 의 Outer Side가 되며, Hr.Employee Table은 Inner Side가 됩니다. 
      
   이전 버전의 실행계획과 동일하게 표시되는, 두번째 Join row source가 할당되지 않는 경우는 다음과 같습니다. 
      - Inner Side에서 필요한 모든 컬럼이 Index 상에 있어 Table Access가 필요없는 경우. 이 경우, Oracle은 오직 한번만 Join 한다 <--이게 핵심인듯하다. 조인을 위해 첫번째 선택해주는 인덱스에 대해 loop를 돌 필요가 없다면..
그만큼 퍼포먼스상 이익이 있다.  => 자주 사용될 테이블을 미리 만들어 둔다는게 이런 의미였구나..  특정 직원에 대한 연봉 정보를 자주 조회할 도메인일때 이것을 직원테이블에서 id와 이름 + 특정 조건 으로 새롭게 테이블을 구성해두면.. 나중에 이것을 
급여 테이블과 조인 연산시에.. 이중 반복문이 아닌, 단일 반복문이 될것이다. selete *(아스타리스크)를 사용하도록 노력할?
것!  .. 물론 쓸데 없는 데이터를 파일에서 읽어오게 되면.. 그 성능 하락이 더 크다... 외부 i/o는 적을수록 빠른것! (선생님의 
명언!!!)
 
      - 이전 버전과 Row 의 순서가 다르게 리턴될 수 있다. 따라서, Oracle DB가 특정한 순서로 Row를 추출해야 되는경우, 예를 들어, Order by Sort를 제거할 필요가 있을경우
        기존의 NL Join 방식을 사용할 수 있다.
      - OPIMIZER_FEATURES_ENABLE 초기 파라메터가 11g 이전 버전으로 set 되어 있는 경우, 기존의 NL Join 을 수행한다. 


http://prayyou.egloos.com/viewer/1799600



*******************************************************************

statement vs preparestatement


http://translate.googleusercontent.com/translate_c?depth=1&hl=ko&prev=/search%3Fq%3Dstatement%2Bvs%2Bpreparedstatement%26newwindow%3D1%26espv%3D210%26es_sm%3D93&rurl=translate.google.co.kr&sl=en&u=http://stackoverflow.com/questions/3271249/difference-between-statement-and-preparedstatement&usg=ALkJrhg7XYWCDIhZNBVwbSd1ll4UI_YUqg



DiverManger.getConnection() 에서 하는 짓..


//  Worker method called by the public getConnection() methods.
    private static Connection getConnection(
        String urljava.util.Properties infoClassLoader callerCLthrows SQLException {
        /*
         * When callerCl is null, we should check the application's
         * (which is invoking this class indirectly)
         * classloader, so that the JDBC driver class outside rt.jar
         * can be loaded from here.
         */
        synchronized(DriverManager.class) {
          // synchronize loading of the correct classloader.
          if(callerCL == null) {
              callerCL = Thread.currentThread().getContextClassLoader();
           }
        }
        if(url == null) {
            throw new SQLException("The url cannot be null""08001");
        }
        println("DriverManager.getConnection(\"" + url + "\")");
        // Walk through the loaded registeredDrivers attempting to make a connection.
        // Remember the first exception that gets raised so we can reraise it.
        SQLException reason = null;
        for(DriverInfo aDriver : ) {
            // If the caller does not have permission to load the driver then
            // skip it.
            if(isDriverAllowed(aDriver.drivercallerCL)) {
                try {
                    println("    trying " + aDriver.driver.getClass().getName());
                    Connection con = aDriver.driver.connect(urlinfo);
                    if (con != null) {
                        // Success!
                        println("getConnection returning " + aDriver.driver.getClass().getName());
                        return (con);
                    }
                } catch (SQLException ex) {
                    if (reason == null) {
                        reason = ex;
                    }
                }
            } else {
                println("    skipping: " + aDriver.getClass().getName());
            }
        }
        // if we got here nobody could connect.
        if (reason != null)    {
            println("getConnection failed: " + reason);
            throw reason;
        }
        println("getConnection: no suitable driver found for "url);
        throw new SQLException("No suitable driver found for "url"08001");
    }


by givingsheart 2014. 1. 2. 09:08

구분했습니다. 감사합니다 (__ )


리절트셋의 별칭을 줄수 있다는 게.. 참 행복합니다. 
읽어오려는 테이블의 칼럼 명이 아주 그지 같이 길고 복잡할때.. 리절트셋으로 받아와서
간단한 n, s 등으로 접근할 수 있겠네요 (^^ )// (아니면 말고..)

SELECT name n, salary s FROM employee e, department d 
WHERE e.salary > '30000' AND d.department_name = '법무부' AND e.name LIKE('_길_')
ORDER BY e.name ASC

결과의 값은 n , s 란 필드(컬럼명)로서 행,렬 데이터 입니다.

프롬절의 별칭의 경운.. 조건절(where)에서 편하게 쿼리문 만들라고 하는 것이겟죠.. 위에처럼..
+ 테이블 n개 이상 조인시 selete 하려는 칼럼명이 중복될 수 있다. 네임스페이스를 지정하는
느낌이랄까? 뭐 그런듯하다~~ 아 글고 아래 문서에서 보듯.. 디비가 넘겨준 ResultSet을 
row,colomn 별로 접근할땐.. 별칭보단, 인덱스(배열 연산자)로 접근하는게 성능이 더 빠르다는
말이 있다. 글고 일반적으로 컬럼은 내가 원하는 데이터를 지정했을테니.. 조회의 경우
로우(=클래스의 인스턴스를 표현하는 데이터 집합) 단위로 하게 될텐데.. 이경우엔 
컨테이너 인터페이스가 제공하는 .. 반복자~ 이터레이터를 쓰는게 코드가 더 이쁘다. ㅎㅎㅎ

***************************************
(etc)컨테이너 접근 방법에 따른 퍼포먼스
int k = arr.size for(int i=0; i<k, i++ ) 요런 접근과 향상된 포문 for(int i : arr)  접근과 while(it.hasNext)
it.next() 의 퍼포먼스의 경우.. 일반적으론 첫번째가 가장 빠르겠지만, 컴파일러의 최적화를 통해서
3번째 이터레이터 쓰는게 제일 좋다는 문서도 봣었음!


***************************************
리절트셋 명세:

java.sql 
인터페이스 ResultSet

모든 슈퍼 인터페이스:
Wrapper
기존의 서브 인터페이스의 일람:
CachedRowSet , FilteredRowSet , JdbcRowSet , JoinRowSet , RowSet , SyncResolver , WebRowSet

<ins style="font-family: Gulim; font-size:12pt; line-height: normal; display: inline-table; border: none; height: 90px; margin: 0px; padding: 0px; position: relative; visibility: visible; width: 728px;"><ins id="aswift_0_anchor" style="display: block; border: none; height: 90px; margin: 0px; padding: 0px; position: relative; visibility: visible; width: 728px;"></ins></ins>
<pre>public interface ResultSet
extends Wrapper
</pre>

데이타베이스의 결과 세트를 나타내는 데이터의 테이블로, 일반적으로, 데이타베이스에 조회하는 문장을 실행하는 것에 의해 생성됩니다.

ResultSet 객체는, 커서가 데이터의 현재의 행을 지시하도록(듯이) 유지합니다. 초기 상태에서는, 커서는 최초의 행의 선두에 배치됩니다. next 메소드에 의해, 커서는 다음의 행으로 이동합니다. next 는,ResultSet 객체에 그 이상행이 없는 경우에 false 를 돌려주므로,while 루프에 사용해 결과 세트를 반복 처리 할 수가 있습니다.  

디폴트의 ResultSet 객체는 갱신 불가로, 커서는 순서 방향에게만 나아갑니다. 따라서 이 객체는, 최초의 행으로부터 마지막 행으로 향해 1 회만 실행할 수 있습니다. 스크롤 또는 갱신, 혹은 그 양쪽 모두가 가능한 ResultSet 객체를 생성할 수 있습니다. con 가 유효한 Connection 객체인 다음의 코드 fragment는, 스크롤 가능해 외로 행해진 갱신을 반영하지 않는 결과 세트, 및 갱신 가능한 결과 세트의 작성 방법을 나타내고 있습니다. 다른 옵션에 대해서는,ResultSet 의 필드를 참조해 주세요.

Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);ResultSet rs = stmt.executeQuery("SELECT a, b FROM TABLE2");// rs will be scrollable, will not show changes made by others,// and will be updatable 
아래 java 도큐의 resultset 명세중.. '렬명' 이 alias(별칭) 과 동일한 의미.
ResultSet 인터페이스는, 현재의 행으로부터 렬치를 취득하는 getter 메소드 (getBoolean,getLong 등)를 제공합니다. 값은, 열의 인덱스 번호나 렬명의 어느 쪽인지를 사용해 취득할 수 있습니다. 일반적으로은 열인덱스를 사용하는 (분)편이 효과적입니다. 열은 1 으로부터 순서에 번호 붙이고 됩니다. 이식성을 최대한으로 꺼내기 (위해)때문에, 각 행내의 결과 세트의 열은 왼쪽에서 오른쪽의 순서에 읽혀 각 행은 1 회만 읽히도록(듯이) 합니다.

getter 메소드에서는, JDBC 드라이버가 기본적인 데이터를 getter 메소드로 지정된 Java 형으로 변환해, 적절한 Java 의 값을 돌려줍니다. JDBC 스펙에는,ResultSet getter 메소드로 가능한 SQL 형으로부터 Java 형에의 매핑을 나타내는 테이블이 있습니다.  

getter 메소드에의 입력으로서 사용되는 렬명에서는, 대문자와 소문자는 구별되지 않습니다. 렬명으로 getter 메소드가 불려 가 복수의 열이 같은 이름을 가지는 경우는, 최초로 일치하는 열의 값이 돌려주어집니다. 렬명의 옵션은, 결과 세트로 생성되는 SQL 쿼리로 렬명이 사용되는 경우에 사용되도록(듯이) 설계되고 있습니다. 쿼리로 명시적으로 명명되지 않는 열의 경우에는, 열번호를 사용하는 것이 가장 좋은 방법입니다. 렬명을 사용하는 경우, 프로그래머는 목적의 열을 일의에 가리키는 것을 보증하도록 주의해 주세요. 이것은, SQL AS 절을 사용해 실현될 수 있습니다


by givingsheart 2014. 1. 2. 09:02
1)
select idx,level from char_info where idx in (select no from user where no='298110' or no='4187793')
 
=> 원하는 것은 유저테이블의 no(pk) 가 298110  또는 4187793 인 레코드를 찾아서.. 캐릭터정보 테이블의 index(pk)
와 일치하는 유저 테이블 no를 찾는것...? 맞나???

2)
select idx,level from char_info where idx in ('298110','4187793')

저런 쿼리경우 서브 쿼리 해서 tmp 사용하시는것보단.. 그냥 아래쪽으로 쓰는게 빠르죠.. =>아마 임시 테이블 복사가(메모리) 
이뤄지는듯 하다.  string 작업 할때 += 연산 해줄때 퍼포먼스 떨어지는 것과 유사

아니면.. 

3)select idx,level from char_info a, (select no from user where no='298110' or no='4187793') <-인라인
쿼리...=메모리에 올린 사본 데이터 = 물리x 논리적 테이블 = 리절트셋 b 

하여튼 1 vs 3의 차이점은 in() 이라는 키워드 이고..
아래 답글들을 보면.. in()의 경우 해당 조건을 확인위해 테이블 로우 풀스캔(전체 조회)이 일어나는듯하다.


지훈형님이 말씀하신 쿼리 튜닝의 개념인듯하다.. 중요하니까 신경써야함..!!


어렵고도 어려운~  (아래는 ms sql 포럼.. 오라클 개발자 포럼도 찾아봐야할듯.. 나~중~에)

http://www.mysqlkorea.co.kr/gnuboard4/bbs/board.php?bo_table=community_03&wr_id=2917



아래는 오라클 개발자 포럼




selete 사용시 주의할점


(추가)
DB 테이블 최적화(설계단 문제) , 쿼리 최적화 또한.. 쉬운 분야가 아니다. 맛만 보았다. 


by givingsheart 2014. 1. 2. 09:01
********************************************************
내가 약 20분 삽질한 constraint 두개 이상쓰기..

create table employee(
employee_no number(3),
salary varchar2(50),
...
department_no number(3),

constraint employee_pk primary key (employee_no),  //칼럼은 괄호()로 .. 추가로 제약조건 주고 싶으면.. 콤마 ,로  []아님
constraint department_fk foreign key (department_no) references department (department_no) <-- 여기에 delete cascade
)


create table employee(
employee_no number(3),
name varchar2(50) not null,
position varchar2(50) not null,
salary number not null,
department_no number(3) null,  <-- 신입사원이라면 소속부서가 아직 결정 안되었을수 있음으로!
constraint employee_pk primary key (employee_no),
constraint department_fk foreign key (department_no)
references department (department_no) on delete cascade  <--요 정의는 자식 테이블이 참조하고 있기 때문에 부모테이
블을 삭제(drop)할수 없다는 정의! data define language  + 구분할 개념.. 부모테이블 전체가 아닌, 테이블의 행(레코드)를
삭제할 경우 자식테이블의 참조 값도 없어짐.

내 예측엔 on delete cascade로 ddl 했을때 참조되는 부모 테이블을 변경시 , 자식테이블의 컬럼(fk)만 비워질 것이라 
생각했는데.. 결과는 삭제한 fk를 갖고 있던 자식 테이블의 모든 레코드가 삭제 되었다!  아래는 테스트 코드

CREATE TABLE DEPARTMENT(
DEPARTMENT_NO NUMBER(3,0),
DEPARTMENT_NAME VARCHAR2(50) NOT NULL,
LOCATION VARCHAR2(50),
CONSTRAINT DEPARTMENT_PK PRIMARY KEY (DEPARTMENT_NO)
);

INSERT INTO department VALUES(1,'영업부','강남구 논현동')
INSERT INTO department VALUES(2,'인사부','강남구 역삼동')
INSERT INTO department VALUES(3,'법무부','강남구 삼성동')
INSERT INTO department VALUES(4,'전략기획및 개발','강남구 삼성동')



create table employee(
employee_no number(3),
name varchar2(50) not null,
position varchar2(50) not null,
salary number not null,
department_no number(3) null,
constraint employee_pk primary key (employee_no),
constraint department_fk foreign key (department_no)
references department (department_no) on delete cascade
)

INSERT INTO employee 
VALUES(1,'장호','부장','5000000000',4)

INSERT INTO employee(employee_no,name,position,salary,department_no)
VALUES(2,'홍길동','사원','500',4)

INSERT INTO employee(employee_no,name,position,salary,department_no)
VALUES(3,'강길동','사원','500',4)

DELETE FROM department WHERE department_no = 4

SELECT * FROM employee


아래의 경우 drop table department; 했을 경우 실패했으나 ,, drop table department cascade constraint; 로 지워줄수있음.
물론 테이블의 삭제가 일반적인 일은 아님.(데이터가 다 날아감으로)


흠.. 직원 a씨는 인사부서 였는데.. 인사부(human resource)가 사라졌다면.. 직원 a씨의 전체 정보를 삭제할까? 
아니면 컬럼만 삭제할까?


구분할 개념
테이블 생성시.. 제한 조건(constraint)로 foregn key references 부모 테이블 (칼럼이름) on delete cascade 의 경우
참조 무결성을 위해 부모 테이블의 드랍에 제한을 거는 것이고..

drop table 부모테이블 cascade constraint 의 경우는.. 자식 객체의 fk 칼럼의 레퍼런스(참조)속성을 날려버린다는
의미 같음. (해당 칼럼을 삭제하진 않을듯함?)

)

*************************************************************




http://blog.naver.com/kookh1?Redirect=Log&logNo=120192625407



ALTER TABLE MEMBERINFO MODIFY(ID NUMBER(6,0) NOT NULL);  <-- 요놈도 괄호 삽질 ㅠㅠ

alter table에 대해서..


key의 타입(super,candiate,primaty,alter...) 과 무결성에 대해

****************************************************
 pk는 not null 과 unique 를 포함하는 개념!

흑.. 완전 짜증..

create table memberinfo(
id number(6,0), //pk 인덱스니까 검색빠르게 문자열보단.. 숫자로 줬는데 흑;;
pw varchar2(10) not null,
name varchar2(20),
constraint memberinfo_pk primary key (id)   <--- id를 ()로 안감싸서 한참 삽질 ㅠㅠ  <--요이유가. 한번에 여러 필드에
                                                                    제약조건(constraint primary key 를 적용할수 있기에.. ()로 식별이 
                                                                    필요한듯.. constraint memberinfo_pk primary key(id, pw, name) 요렇게..
                                                                    물론 실전이라면.. id = pk , nickName = pk, 주민번호 = pk 요런식 이겟지만..
) ;  <-- ;는 해도 되고 안해도 되고..



er 모델링, 클래스 모델링, 또.. 모델 드라이븐 디자인...









//2013-12-19  쿼리 가지고 놀기


SELECT * FROM MEMBERINFO;

SELECT NAME PW FROM MEMBERINFO;
SELECT NAME FROM MEMBERINFO WHERE ID = 'id3';
UPDATE MEMBERINFO SET NAME ='나길동' WHERE ID = 'id2';

UPDATE MEMBERINFO SET ID =5 WHERE NAME = '마길동';

INSERT INTO memberinfo VALUES(4,'하길동','비번66')

INSERT INTO MEMBERINFO(ID,NAME) VALUES('id5','5');
INSERT INTO MEMBERINFO values('id4','라길동','4');
DELETE FROM MEMBERINFO WHERE ID = 'id4';

ALTER TABLE MEMBERINFO DROP COLUMN ID;
ALTER TABLE MEMBERINFO DROP CONSTRAINT ID_PK;

ALTER TABLE MEMBERINFO ADD(ADDRESS VARCHAR2(50));
ALTER TABLE MEMBERINFO MODIFY (ADDRESS VARCHAR2(100));
ALTER TABLE MEMBERINFO ADD CONSTRAINT ID NUMBER PRIMARYKEY;

ALTER TABLE MEMBERINFO ADD PRIMARY KEY(ID NUMBER(6,2));

ALTER TABLE MEMBERINFO MODIFY (ID NUMBER(6,0)[PRIMARY KEY]);

ALTER TABLE MEMBERINFO ADD(ID2 NUMBER CONSTRAINT PRIMARY KEY);

ALTER TABLE MEMBERINFO MODIFY (ID NUMBER);

DROP TABLE MEMBERINFO2;
CREATE TABLE MEMBERINFO2(ID NUMBER(6,0) PRIMARY KEY, PW VARCHAR2(20), NAME VARCHAR2(20));

ALTER TABLE MEMBERINFO2 MODIFY(ID NUMBER(6,0) NOT NULL);

DROP TABLE DEPARTMENT;

CREATE TABLE DEPARTMENT(DEPARTMENT_NO NUMBER(3,0) PRIMARY KEY, DEPERTMENT_NAME VARCHAR2(50) NOT NULL,
LOCATION VARCHAR2(50));


DELETE FROM department WHERE department_no = 4  



drop table employee

CREATE TABLE DEPARTMENT(
DEPARTMENT_NO NUMBER(3,0),
DEPARTMENT_NAME VARCHAR2(50) NOT NULL,
LOCATION VARCHAR2(50),
CONSTRAINT DEPARTMENT_PK PRIMARY KEY (DEPARTMENT_NO)
);

INSERT INTO department VALUES(1,'영업부','강남구 논현동')
INSERT INTO department VALUES(2,'인사부','강남구 역삼동')
INSERT INTO department VALUES(3,'법무부','강남구 삼성동')
INSERT INTO department VALUES(4,'전략기획및 개발','강남구 삼성동')

UPDATE department SET location = '제주도 성남시'
UPDATE department SET department_name = '전략기획' WHERE department_no = 4
UPDATE department SET location = '논현동' WHERE department_no = 1;
UPDATE department SET location = '역삼동' WHERE department_no = 2;
UPDATE department SET location = '삼성동' WHERE department_no = 3;
UPDATE department SET location = '동동' WHERE department_no = 4;

INSERT INTO department(department_no,department_name,location) VALUES(5,'')

SELECT * FROM department
SELECT * FROM department ORDER BY department_no ASC

create table employee(
employee_no number(3),
name varchar2(50) not null,
position varchar2(50) not null,
salary number not null,
department_no number(3) null,
constraint employee_pk primary key (employee_no),
constraint department_fk foreign key (department_no)
references department (department_no) on delete cascade
)

INSERT INTO employee 
VALUES(1,'장호','부장','5000000000',4)

INSERT INTO employee(employee_no,name,position,salary,department_no)
VALUES(2,'홍길동','사원','500',4)

INSERT INTO employee(employee_no,name,position,salary,department_no)
VALUES(3,'강길동','사원','30000',4)

INSERT INTO employee(employee_no,name,position,salary,department_no)
VALUES(4,'나길동','ㄹㅇㄹㅇ','3004400',3)

INSERT INTO employee(employee_no,name,position,salary,department_no)
VALUES(5,'다길동','ㄷㄷ','3003300',2)

INSERT INTO employee(employee_no,name,position,salary,department_no)
VALUES(6,'라길동','ㅂㅂ','6630000',1)

INSERT INTO employee(employee_no,name,position,salary,department_no)
VALUES(7,'길동','ㅂㅂ','66320000',3)

INSERT INTO employee(employee_no,name,position,salary,department_no)
VALUES(8,'길동이','ㅂㅂ','66000',3)


DELETE FROM department WHERE department_no = 4

SELECT * FROM employee WHERE department_no IN(1,3) ORDER BY name ASC
SELECT * FROM employee WHERE department_no NOT IN(1,3) ORDER BY name ASC

SELECT * FROM employee WHERE department_no IN(1,3) ORDER BY department_no ASC

SELECT * FROM employee WHERE name LIKE('%동')
SELECT * FROM employee WHERE name LIKE('%동%')
SELECT * FROM employee WHERE name LIKE('길%')
SELECT * FROM employee WHERE name LIKE('__동')
SELECT * FROM employee WHERE name LIKE('__') ORDER BY salary DESC
SELECT * FROM employee WHERE name LIKE('%') ORDER BY salary DESC
SELECT * FROM employee WHERE name LIKE('_동') 

SELECT * FROM employee WHERE name NOT LIKE('_동')


글고 조인 연산시.. 테이블의 별칭을 줄수 있다. 왜냐면 네임스페이스 처럼
이름 식별을 위해서~ 글고 뒤에 오더정렬을 안해주면 입력 순서가 유지가 안된다.
그럼으로 이를 통해 dbms가 데이터를 저장하는 방식이 map<pk,Object data~~> 임을 
유추할수 있다. 검색 속도 증가를 위한 인덱싱이란 무얼까? 
SELECT * FROM employee e, department d <--불필요한 정보까지 싸그리 가져온 경우
WHERE e.salary > '300600' AND d.department_name = '법무부' AND e.name LIKE('_길_')
ORDER BY e.name ASC
아참.. where 조건절을 ()로 묶어줄 수 있다.
SELECT e.name FROM employee e, department d 
WHERE e.salary > '30000' AND d.department_name = '법무부' AND e.name LIKE('_길_')
ORDER BY e.name ASC


SELECT * FROM employee

alter table employee modify(department_no number(3) foreign key);


(추가)난 여전히 학원 과정(아주 얕게 RDB 수업 & JDBC를 활용한 CRUD 테스트 실습)과는 별개로
공부및 추가 학습을 하고 있다. (오라클 DBMS 아키텍처및 각종 쿼리와 최적화, 테이블 설계, 정규화
비정규화등..) RDB도 제대로 이해를 못하고.. 빅데이터를 알게 되었다.(대용량 DB 아니다)


by givingsheart 2014. 1. 1. 16:45

목표:웹 -> db 를 통한 초 간단 회원 관리 프로그램

 

세부목표 1. 빈클래스 만들기

             2. db핸들러 클래스 만들기(현재 여기서 - 사용자가 빈의 종류, 연결 db정보,사용할 쿼리를 입력받아

                config 파일을 만들수 있게 awt를 이용해 간단한 툴을 만들다가.. 괜히 복잡해짐.

             3. 오라클 11에 생성및 연동 성공했고 테이블 스페이스, 테이블도 만들어둠. (오라클 문법에 대한 공부 필요)

                (웹을 통해선 아니지만, 콘솔 창에서 테스트용으로 엔트리 하나 (아뒤,비번,이름) 추가 성공 !!!!!!!!

                   INSERT INTO test1 values('id1','pw1','hon');  happy!!!!)

 

현재 계정:park 비번:111111 테이블 스페이스:park 권한:dba -_-;;  그외 각종 인서트,업데이트등등

                 만들어둔 테이블:test1

                 db이름: park

                 db url: jdbc:oracle:thin:@localhost:1521:park

                 

 

             중요!! 명령문은 대문자로 쓸것! 문자열은 ' ' 로 처리!! 칸 띄우기 조심!!!!

 

?? 테이블 스페이스가 다른데 테이블 명이 중복된다고 나옴 ;;; 기존 테이블 없애야 하나???

//1.테이블 스페이스 변경

//2.해당 테이블 드랍

 

http://onmay.tistory.com/12

 

https://www.linux.co.kr/superuserboard/view.html?code=oracle&id=312&position=&start=380

 

 

http://blog.naver.com/seotaji?Redirect=Log&logNo=80199911545 (앞페이지에 오라클 12c 설치및 계정생성 포함;;)

 

 

 

 컬럼으로 테이블 찾기

 

select TABLE_NAME from ALL_TAB_COLUMNS where COLUMN_NAME='컬럼이름';

 

 

네이버에서 "대용량 데이터베이스솔루션 1 " 책

 

 

(etc) spring

 

http://kekedie.tistory.com/66

by givingsheart 2014. 1. 1. 15:38
| 1 |