안녕하세요.

출간 서평 이벤트에 당첨되었습니다.

좋은 기회 주셔서 감사합니다 :)

 

DBian "평생 필요한 데이터 분석" 책을 읽고 난 후 서평입니다.

 

책이 출판되기 전에 DBian 포럼 카페의 전문가 컬럼에서 SQL_QUANT를 흥미롭게 봤었습니다.

증권회사의 DB 테이블 구조를 살펴볼 수 있었기 때문입니다.

학생 시절, 금융 관련 공부를 했었던 저에겐 흥미로운 주제였습니다.

(해당 DB를 다룰 경험이 없었기 때문에 궁금했습니다.)

 

 "맛있는 요리를 위해서는 훌륭한 요리사와 좋은 식자재가 필요합니다."

책을 읽으며 기억나는 구문입니다.

가치 있는 데이터 분석을 위해서는 노련한 SQL 개발자와 좋은 데이터가 있어야 한다는 내용이었는데요.

이처럼 책의 데이터 소스는 실제 과거 데이터를 제공하고 있어서 실습하기 정말 좋았습니다.

 

Mysql 기반으로 책의 설명이 진행됩니다. (DBian 카페에 오라클 실습 버전도 있습니다.)

1~5장까지 주식을 주제로 초보자도 쉽게 따라할 수 있도록 SQL 문법을 다루는 내용이었고,

6장은 연별재무 데이터를 기반으로 데이터 분석하는 내용이었습니다.

7장은 골든크로스, 영업이익 증가한 종목 찾기, 거래량 급등 종목, 계절성 분석 등 주식 데이터를 활용하는 내용입니다.

증권사의 조건검색 기능이 이러한 패턴으로 적용이 되겠구나 라는 생각이 들었습니다.

 

Mysql 과 주식 관련 데이터를 실습해 볼 수 있는 좋은 책이었습니다.

좋은 책 출판해 주셔서 감사합니다.

 

 

 

1. SQL*Plus에서 확인방법

: 아래의 쿼리는 toad나 오렌지등 다른 툴에서는 사용할 수 없다.

 

SHOW PARAMETER 파라미터명;

show parameter NLS_LENGTH_SEMANTICS;

 

2. toad나 오렌지, SQL Developer에서는 데이터 딕셔너리인 시스템 뷰에서 조회를 할 수 있다.

 

SELECT name, type, value
  FROM SYS.V_$PARAMETER
 WHERE name = '파라미터명';
 
SELECT NAME, TYPE, VALUE
  FROM SYS.V_$PARAMETER
 WHERE NAME IN('TEMP_UNDO_ENABLED', 'UNDO_MANAGEMENT', 'UNDO_RETENTION', 'UNDO_TABLESPACE');

프런트에서 자바스크립트 디버깅할 때 아래와 같이 진행한다.

(html은 디버그 안되고 javascript 디버그 할 때 사용)

 

1. tomcat start(일반 모드)

 

2. 개발자 도구를 실행하여 디버깅하고 싶은 Javascript 파일을 연다. (컨트롤 + p)

 

3. 해당 파일에서 확인하고 싶은 부분을 breakpoints 를 찍는다.

 

4. 해당 breakpoints를 찍은 기능이 실행되도록 화면에서 실행한다.

 - F8 : 다음 breakpoint 로 이동

 

(서버 재시작 왜했었지..? 캐시 날리고 했었는데..)

 

5. 해당 변수값을 확인 및 수정할 수 있다.

 

6. html 화면 변수값을 수정해서 입력할 수 있다.

 - $0.value

자바 소스에서 디버깅을 할 때 아래와 같이 진행한다.

 

1. 디버깅 하고 싶은 자바 소스에서 줄번호 더블 클릭하여 breakpoints를 찍는다.

 

2. tomcat Debug mode 로 start

 

3. breakpoints 를 찍은 소스 부분이 실행될 때, 해당 변수들의 value 확인 가능함.

 - 변수들의 value 확인이 가능하고, 메소드의 결과는 확인할 수 없다.

 - F8 : 다음 breakpoint 로 이동

 

4. 메소드 결과 확인하는 방법

 - breakpoint 찍은 라인에 메소드 결과를 확인하고 싶은 경우 해당 메소드를 아래 사진과 같이 입력하면 결과(false)를 확인 할 수 있다.

 

클러스터 인덱스, 넌클러스터 인덱스

클러스터 인덱스 : Oracle에서 IOT(Index Organized Table)와 동일한 개념이다.

넌클러스터 인덱스 : Oracle에서 일반 인덱스(Non-unique Index)와 동일한 개념이다.

 

참고로 오라클에서는 상대적으로 IOT를 잘 사용하지 않는다.

 

※ 클러스터 인덱스 설명 URL : https://leechun.tistory.com/41?category=983198

 

Oracle Index 종류

단일 인덱스(Single column Index) : 인덱스에 하나의 컬럼만 사용

결합 인덱스(Composite Index) : 인덱스에 두 개 이상의 컬럼을 사용

 

PK 속성은 단일 인덱스로 구성할 수 있고, 결합 인덱스로 구성될 수 있다.

 

Oracle Index 분류

유니크 인덱스(Unique Index) : 인덱스 구성 컬럼들 값에 중복을 허용하지 않는다.

비유니크 인덱스(Non-unique Index) : 인덱스 구성 컬럼들 값에 중복을 허용한다.

 

PK 제약 조건으로 컬럼을 선택한다면, 무조건 유니크 인덱스가 구성된다.

 

Oracle Index 물리적인 구조

B*트리 인덱스 : 트리 형태의 자료 구조를 사용함 (대부분 B*트리 사용함)

비트맵 인덱스 : 값의 종류가 많지 않은 컬럼에 사용함

 

Oracle 파티션 된 Index 구분

글로벌 인덱스

로컬 인덱스

 

Oracle 제약사항 조회
SELECT DECODE(A.CONSTRAINT_TYPE,  'P', 'Primary Key',  'R', 'Foreign Key', 
             'C', 'Table Check',  'V', 'View Check',  'U', 'Unique',  '?') AS "유형"
     , SUBSTRB(A.CONSTRAINT_NAME, 1, 25) AS CONSTRAINT_NAME
     , B.POSITION
     , SUBSTRB(B.COLUMN_NAME, 1, 25) AS COLUMN_NAME
  FROM DBA_CONSTRAINTS A
     , DBA_CONS_COLUMNS B
 WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
-- AND A.OWNER = 'MAFCCC'
   AND A.TABLE_NAME = UPPER('테이블 이름')
 ORDER BY  1, 2, 3;

Oracle에서 성능 개선을 위해 실행계획을 사용한다.

아래와 같이 실행계획은 예상 실행계획과 실제 실행계획 방법을 살펴보자

 

예상 실행계획

Toad, Orange와 같은 Tool에서는 "ctrl+e" 눌러서 예상 실행계획을 편하게 확인하는 경우가 있으나 자세한 정보를 보기 위해서는 아래와 같이 따라한다.

 

SELECT * FROM T_ORD WHERE ORD_SEQ = 4;

위 쿼리를 예상 실행계획으로 실행하고 싶은 경우엔 아래와 같이 실행한다.

 

-- 실행계획 만들기
EXPLAIN PLAN FOR
SELECT * FROM T_ORD WHERE ORD_SEQ = 4;

-- 실행계획 확인하기
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());

위와 같이 쿼리 2문장을 순서대로 각각 실행하면 아래와 같이 예상 실행계획 결과가 나온다.

 

PLAN_TABLE_OUTPUT
 
-----------------------------------------------------------------------------
| Id  | Operation                   | Name     | Rows  | Bytes | Cost (%CPU)|
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |          |     1 |    44 |     2   (0)|
|   1 |  TABLE ACCESS BY INDEX ROWID| T_ORD    |     1 |    44 |     2   (0)|
|*  2 |   INDEX UNIQUE SCAN         | PK_T_ORD |     1 |       |     1   (0)|
-----------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access("ORD_SEQ"=4)
-- Id : 실행계획의 오퍼레이션 ID (구분자, 순서아님)
-- Operation : 해당 단계에 수행한 작업 내용
-- Name : 해당 단계에 작업을 수행한 대상 오브젝트(테이블 또는 인덱스)
-- Rows : 해당 단계 수행 시 조회될 예상 데이터 건수
-- Bytes : 해당 단계까지 사용될 예상 데이터양(누적)
-- Cost (%CPU) : 해당 단계까지 사용될 예상 비용(누적)

 

실제 실행계획
SELECT *
  FROM T_ORD T1
     , M_CUS T2
 WHERE T1.CUS_ID = T2.CUS_ID
   AND T1.ORD_DT >= TO_DATE('20170101','YYYYMMDD')
   AND T1.ORD_DT < TO_DATE('20170201','YYYYMMDD')
   AND T2.CUS_GD = 'A';

위 쿼리를 실제 실행계획으로 실행하고 싶은 경우엔 아래와 같이 실행한다.

 

1번 : 실제 실행계획 만들기(hint 추가)

SELECT /*+ GATHER_PLAN_STATISTICS */
       *
  FROM T_ORD T1
     , M_CUS T2
 WHERE T1.CUS_ID = T2.CUS_ID
   AND T1.ORD_DT >= TO_DATE('20170101','YYYYMMDD')
   AND T1.ORD_DT < TO_DATE('20170201','YYYYMMDD')
   AND T2.CUS_GD = 'A';

 

2번 : 실제 실행계획을 만든 SQL의 SQL_ID찾아내기

SELECT T1.SQL_ID ,T1.CHILD_NUMBER ,T1.SQL_TEXT
  FROM V$SQL T1
 WHERE T1.SQL_TEXT LIKE '%GATHER_PLAN_STATISTICS%'
 ORDER BY T1.LAST_ACTIVE_TIME DESC;

 

3번 : 실제 실행계획 조회하기(각자의 SQL_ID, CHILD_NUMBER를 사용할 것)

SELECT *
  FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('3ykn80uy9n32d',0,'ALLSTATS LAST'));

 

위와 같이 1~3번 쿼리를 순서대로 실행하면 아래와 같이 실제 실행계획 결과가 나온다.

PLAN_TABLE_OUTPUT
SQL_ID  3ykn80uy9n32d, child number 0
-------------------------------------
SELECT /*+ GATHER_PLAN_STATISTICS */        *   FROM T_ORD T1      , 
M_CUS T2  WHERE T1.CUS_ID = T2.CUS_ID    AND T1.ORD_DT >= 
TO_DATE('20170101','YYYYMMDD')    AND T1.ORD_DT < 
TO_DATE('20170201','YYYYMMDD')    AND T2.CUS_GD = 'A'
 
Plan hash value: 3240201901
 
-----------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |       |      1 |        |    101 |00:00:00.01 |      12 |       |       |          |
|*  1 |  HASH JOIN         |       |      1 |    170 |    101 |00:00:00.01 |      12 |   779K|   779K| 1234K (0)|
|*  2 |   TABLE ACCESS FULL| M_CUS |      1 |     60 |     60 |00:00:00.01 |       7 |       |       |          |
|*  3 |   TABLE ACCESS FULL| T_ORD |      1 |    252 |    146 |00:00:00.01 |       5 |       |       |          |
-----------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - access("T1"."CUS_ID"="T2"."CUS_ID")
   2 - filter("T2"."CUS_GD"='A')
   3 - filter(("T1"."ORD_DT"<TO_DATE(' 2017-02-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND 
              "T1"."ORD_DT">=TO_DATE(' 2017-01-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss')))
-- Starts : 해당 단계를 수행한 횟수
-- E-Rows : 해당 단계의 예상 데이터 건수
-- A-Rows : 해당 단계의 실제 데이터 건수
-- A-Time : 해당 단계까지 수행된 실제 시간(누적)
-- Buffers : 해당 단계까지 메모리 버퍼에서 읽은 블록 수(논리적 IO 횟수, 누적)
-- Reads : 해당 단계까지 디스크에서 읽은 블록 수(물리적 IO 횟수, 누적)
-- OMem : SQL 처리를 위해 사용한 메모리 수치
-- 1Mem : SQL 처리를 위해 사용한 메모리 수치
-- Used-Mem : SQL 처리를 위해 사용한 메모리 수치

끝.

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

Orange, Toad 에서 Parameter 확인 방법  (0) 2022.04.13
Oracle INDEX  (0) 2022.03.10
CONNECT BY LEVEL  (0) 2021.12.31
ORA-12899: value too large for column, 오라클 문자열 길이 구하기  (0) 2021.12.14
TRUNC(값, 옵션)  (0) 2021.11.04

어릴적 친구들과 피시방에 모여 다람쥐 잡던 그때 기억나시나요? 바람의 나라는 시간이 지나도 늘 다시 생각나더라구요 그때마다 전 바람인사이드에 들어가 추억을 회상해요!

https://www.baraminside.com

클러스터형 인덱스

- 인덱스를 생성할 때는 데이터 페이지 전체를 다시 정렬한다.
- 대용량의 데이터를 강제로 다시 클러스터 인덱스를 생성하는 건 조심
- 인덱스 자체가 데이터 페이지이다. 인덱스 자체에 데이터가 포함
- 비클러스형 인덱스 보다 검색 속도는 더 빠르다. 하지만 데이터의 입력/수정/삭제는 느리다.
- 테이블에 한 개만 생성할 수 있다.

 

넌 클러스터형 인덱스
- 별도의 페이지에 인덱스를 구성한다.
- 검색 속도는 느리지만, 데이터의 입력,수정,삭제가 더 빠르다.
- 남용할 경우에는 시스템 성능을 떨어뜨리는 결과를 가져온다.

Primary Key라고 하는 것은 논리적인 개념 PK constraint는 물리적인 개념 다른 레코드와 구분짓는 식별자 역할을 하는 중요한 컬럼이므로 데이터는 중복을 허용해서는 안 되고(unique), null값을 허용해서도 안됨 Table 생성시 PK에 자동적으로 유니크 인덱스가 생성 됩니다.

 

PK 와 Unique index 차이점

PK는 not null

유니크 Index는 null 허용

'DB > MSSQL' 카테고리의 다른 글

data type  (0) 2020.12.01

CONNECT BY LEVEL 은 연속적인 숫자를 조회할 때 사용한다.

 

1~10 까지 숫자 조회
SELECT LEVEL AS NO
  FROM DUAL
CONNECT BY LEVEL <= 10;

결과 : 

 

2021년 1월~12월까지 조회
SELECT '2021년 ' || LPAD(LEVEL, 2, 0) || '월' AS DT
  FROM DUAL
CONNECT BY LEVEL <= 12

결과 : 

 

특정 날짜 구간 조회
SELECT TO_DATE('20200701', 'YYYYMMDD') + (LEVEL-1) AS DT 
  FROM DUAL 
CONNECT BY LEVEL <= (TO_DATE('20200717', 'YYYYMMDD') - TO_DATE('20200701', 'YYYYMMDD')) + 1  -- 17

결과 : 

04-1 뷰 라우터

1. 라우팅 : 웹 페이지 간의 이동 방법, 싱글 페이지 애플리케이션(SPA)에서 주로 사용함
 *SPA : 페이지를 이동할 때마다 서버에 웹 페이지를 요청하여 새로 갱신하는 것이 아니라 미리 해당 페이지들을 받아 놓고 페이지 이동 시에 클라이언트의 라우팅을 이용하여 화면을 갱신하는 패턴을 적용

2. 뷰 라우터 : 뷰에서 라우팅 기능을 구현할 수 있도록 지원하는 공식 라이브러리
 <router-link to="URL 값"> : 페이지 이동 태그. 화면에서는 <a>로 표시되며 클릭하면 to에 저장한 URL로 이동
 <router-view> : 페이지 표시 태그. 변경되는 URL에 따라 해당 컴포넌트를 뿌려주는 영역 

3. $mount() API : el 속성과 동일하게 인스턴스를 화면에 붙이는 역할

4. 네스티드 라우터(Nested Router) : 라우터로 페이지를 이동할 때 최소 2개 이상의 컴포넌트를 화면에 나타낼 수 있음
 - 상위 컴포넌트 1개에 하위 컴포넌트 1개를 포함하는 구조

5. 네임드 뷰 : 특정 페이지로 이동했을 때 여러 개의 컴포넌트를 동시에 표시하는 라우팅 방식

 

04-2 뷰 HTTP 통신

 - 뷰에서 ajax를 지원하기 위해 뷰 리소스와 액시오스 라이브러리가 있음

1. 뷰 리소스 : 2016년 말에 에반이 공식적인 지원을 중단하기로 한 라이브러리 (아직 계속 사용 가능)
 - this.http.get() : 뷰 리소스에서 제공하는 기능으로 HTTP GET 요청을 서버에 보내고 특정 데이터를 받아온다.

2. 액시오스(axios) : 뷰 커뮤니티에서 가장 많이 사용되는 HTTP 통신 라이브리러리이다. Promise 기반의 API 형식이 다양하게 제공되어 별도의 로직을 구현할 필요가 없다
 1) axios.get('URL주소').then().catch() 

     : 해당 URL 주소에 대해 HTTP GET 요청을 보낸다. 서버에서 보낸 데이터를 정상적으로 받아오면 then() 안에 정의한 로직이 실행, 오류가 발생하면 catch()에 정의한 로직이 수행
  2) axios.post('URL주소').then().catch()  

       : 해당 URL 주소에 대해 HTTP POST 요청을 보내고 위에서 살펴본 내용과 동일함
  3) axios({옵션 속성})   

       : HTTP 요청에 대한 자세한 속성들을 직접 정의하여 보낼 수 있음 

'Vue.js' 카테고리의 다른 글

3장. 인스턴스 & 컴포넌트  (0) 2021.12.12

+ Recent posts