레이블이 Database인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Database인 게시물을 표시합니다. 모든 게시물 표시

SQL 튜닝비법 - 서브쿼리와 함수

  1. 서브 쿼리란? 조인의 또 다른 형태로 하나의 SQL 내에 존재하는 또 다른 SELECT 문을 의미한다.
  2. 서브 쿼리의 위치는 SELECT, FROM, WHERE, ORDER BY 절에서 모두 사용가능하나 GROUP BY 절에서는 사용할 수가 없다.

  3. 메인 쿼리와 서브 쿼리의 관계 : 메인 쿼리는 가장 바깥쪽에서 동작되는 쿼리문이고, 서브 쿼리는 SELECT, FROM, WHERE, ORDER BY 절 내에서 동작되는 쿼리문이다. 서브 쿼리 종류의 따라서 메인 쿼리와 서브 쿼리의 실행 순서가 결정된다.
    1. 예시
      메인 쿼리와 서브 쿼리
      -- 메인 쿼리
      SELECT empno, ename
      FROM emp
      WHERE deptno IN (
      -- 서브 쿼리
      SELECT deptno
      FROM dept
      WHERE dname = 'DEV')
      ;
  4. 서브 쿼리의 종류
    1. NESTED 서브 쿼리 : WHERE 절에서 동작되는 서브 쿼리로 메인 쿼리와의 연결고리가 없이 동작되는 서브 쿼리를 의미한다.
      1. 예시
        NESTED 서브 쿼리
        -- 메인 쿼리
        SELECT empno, ename
        FROM emp
        WHERE deptno = (
        -- NESTED 서브 쿼리
        SELECT deptno
        FROM dept
        WHERE dname = 'DEV')
        ;
      2. 그림
        상황에 따라서 메인 쿼리가 먼저 실행될 수도 있다.
    2. CORRELATED 서브 쿼리 : WHERE 절에서 동작되는 서브 쿼리로 메인 쿼리와의 연결고리가 있어 동작 시에 메인 쿼리보다 나중에 실행되게 되는 서브 쿼리로 메인 쿼리에서 정보를 받아와야 동작이 가능한 서브 쿼리를 의미한다.
      1. 예시
        CORRELATED 서브 쿼리
        -- 메인 쿼리
        SELECT empno, ename
        FROM emp
        WHERE EXISTS (
        -- CORRELATED 서브 쿼리
        SELECT 'X'
        FROM dept
        WHERE dept.deptno = emp.deptno 
        AND dept.dname = 'SALES')
        ;
      2. 그림

    3. Inline View : FROM 절 내에 있는 서브 쿼리를 의미한다.
      1. 예시
        Inline View
        SELECT empno,
                     deptno
        FROM ( -- Inline View
                      SELECT empno,
                                  deptno
                       FROM emp
                     WHERE ename = 'SMITH')
        WHERE empno = '1234'
        ;
    4. SCALAR 서브 쿼리 : SELECT, WHERE, ORDER BY 절 모두에서 사용하며, 단 하나의 데이터와 단 하나의 컬럼을 가져와야하는 서브 쿼리를 의미하며, 함수의 성질을 갖는다.
      1. 예시
        SCLAR 서브 쿼리
        -- 메인 쿼리
        SELECT e.ename,
                     (-- SCALAR 서브 쿼리
                      SELECT d.dname
                        FROM dept d
                      WHERE d.deptno = e.deptno) as dname
                      -- 1 Row, 1 Column
        FROM emp e
        ;

        -- 함수로 생성하여 사용
        CREATE OR REPLACE FUNCTION f_dmn(a_dno IN dept.deptno%TYPE)
        RETURN VARCHAR2
        RESULT_CACHE
        RELIES_ON(dept)
        AS
          h_dnm dept.dname%type := NULL;
        BEGIN
          SELETE dname INTO h_dnm
            FROM dept
          WHERE deptno = a_dno;

          RETURN h_dnm;
        END;
        /

        SELECT ename,
                     f_dnm(deptno) as dname
        FROM emp
        ;
      2. 그림
  5. 함수
    1. 자주 사용하는 함수
      1. 합계 출력하는 함수로 GROUP BY 절에서 사용된다.
        1. ROLLUP() : 괄호 내에 컬럼을 기준으로 합계를 구하는 함수이다.
        2. CUBE() : 괄호 내에 컬럼을 기준으로 합계와 소계를 모두 구하는 함수이다.
        3. GROUPING SETS() : 괄호 내에 컬럼을 기준으로 합계와 소계를 모두 구하는 함수로 ROLLUP(), CUBE() 함수의 기능을 모두 사용 가능하다.
      2. 분석 함수 (Analytical Function)
        1. 구문 형식은 아래와 같다.
          Analytical Function 형식
          SELECT Anlytical_Function (arguments) OVER ([Partition By 컬럼] [Order By 절] [Windowing 절])
          FROM 테이블 명
          WHERE 조건
        2. 구문 형식에 대한 설명은 아래와 같다.
          1. Arguments : 함수에 따라서 0~3개의 인자가 지정된다.
          2. Partition By 절 : 전체 집합을 기준에 의해 소그룹으로 나눈다.
          3. Order By 절 : 어떤 항목에 대한 정렬 기준을 기술한다.
          4. Windowing 절 : 함수에 의해서 제어하고자 하는 데이터 범위를 정의하며, 해당 절에 아무것도 없는 경우 데이터 범위는 전체를 의미한다.
            1. Row를 사용한 범위 선정 방법

            2. Range를 사용한 범위 선정 방법

          5. 함수 종류
            1. ROW_NUMBER() : 순서대로 Row 수를 나타낸다.
            2. RANK() : 순서대로 순위를 매기는 함수로 동일 데이터에 대해서 동일한 순위를 매기며, 그 이후는 떨어진만큼의 순서를 나타낸다. ( 1, 1, 1, 4)
            3. DENSE_RANK() : 순서대로 순위를 매기는 함수로 동일 데이터에 대해서 동일한 순위를 매기며 그 이후는 순서대로 진행한다. (1, 1, 1, 2)
            4. SUM() : 테이블에 대해서 기준별로 누계를 구한다.
            5. RATIO_TO_REPORT() : Partition By 절만 존재하며 기준에 대한 백분율을 구한다.

      참고도서 : 실전사례로 살펴보는 SQL 튜닝비법

SQL 튜닝비법 - 조인

  1. 조인이란? 두 개 이상의 테이블을 연결하여 원하는 데이터를 조회하거나 변경하고 삭제하는 작업을 일컫는다.
  2. 조인의 종류
    1. 조인의 종류는 대상 데이터에 따른 조인 종류와 수행 방식에 따른 조인 종류 두가지로 나누어서 볼 수 있다.
      1. 대상 데이터에 따른 조인 종류
        1. INNER JOIN : 일반적으로 조인으로 불리며, 두 개 이상의 테이블로 부터 조인 조건을 만족하는 데이터만 반환해준다.
          1. 사용 방법
            INNER JOIN 사용법
            SELECT E.NAME, D.DEPT_NAME, D.ADDRESS
            FROM EMP E, DEP D
            WHERE E.DEPTNO = D.DEPTNO
            ;

            SELECT E.NAME, D.DEPT_NAME, D.ADDRESS
            FROM EMP E INNER JOIN DEP D
            ON E.DEPTNO = D.DEPTNO
            ;
        2. OUTTER JOIN : 두 개 이상의 테이블 중에서 기준이 되는 테이블 하나를 선정하여 그 테이블의 데이터는 조인 조건을 만족하지 않아도 반환해준다.
          1. 기준 테이블을 FROM 절을 기준으로 왼쪽 테이블로 선정 시 LEFT OUTTER JOIN, 오른쪽 테이블로 선정 시 RIGHT OUTTER JOIN 이다.
          2. 사용 방법
            OUTTER JOIN 사용법
            -- LEFT OUTTER JOIN
            SELECT E.NAME, D.DEPT_NAME, D.ADDRESS
            FROM EMP E LEFT OUTTER JOIN DEP D
            WHERE E.DEPTNO = D.DEPTNO
            ;
            SELECT E.NAME, D.DEPT_NAME, D.ADDRESS
            FROM EMP E, DEP D
            WHERE E.DEPTNO = D.DEPTNO(+)
            ;

            -- RIGHT OUTTER JOIN
            SELECT E.NAME, D.DEPT_NAME, D.ADDRESS
            FROM EMP E RIGHT OUTTER JOIN DEP D
            WHERE E.DEPTNO = D.DEPTNO
            ;
            SELECT E.NAME, D.DEPT_NAME, D.ADDRESS
            FROM EMP E, DEP D
            WHERE E.DEPTNO(+) = D.DEPTNO
            ;
        3. FULL OUTTER JOIN : 조인이 되는 양쪽 테이블을 모두 기준 테이블로 하여 모든 경우의 수를 반환해준다.
          1. 사용 방법
            FULL JOIN 사용법
            SELECT E.NAME, D.DEPT_NAME, D.ADDRESS
            FROM EMP E FULL OUTTER JOIN DEP D
            ON E.DEPTNO = D.DEPTNO
            ;
        4. CARTESIAN JOIN : 조인 조건 없이 테이블을 조인하여 모든 경우의 수를 반환해준다.
          1. 데이터 복제라는 개념을 활용하기 위해 사용한다.
          2. 불필요한 경우 성능문제를 야기하기 때문에 의도한 것인지 반드시 확인하도록 한다.
          3. 사용 방법
            CARTESIAN JOIN 사용법
            SELECT E.NAME, D.DEPT_NAME, D.ADDRESS
            FROM EMP E, DEP D
            ;
          4. 적용 예시
            적용 예시
            -- 같은 조건의 테이블을 여러번 사용
            SELECT '직군별' AS CLASS, JOB, COUNT(*) AS CNT
            FROM EMP
            GROUP BY JOB
            UNION ALL
            SELECT '부서별' AS CLASS, TO_CHAR(DEPTNO), COUNT(*) AS CNT
            FROM EMP
            GROUP BY DEPTNO
            UNION ALL
            SELECT '총인원' AS CLASS, NULL, COUNT(*) AS CNT
            FROM EMP
            ;

            -- 데이터 복제를 이용
            SELECT
             DECODE(RN, 1, '직군별', 2, '부서별', '총인원') AS CLASS,
             DECODE(RN, 1, JOB, 2, DEPTNO),
             SUM(CNT)
            FROM (SELECT JOB, DEPTNO, COUNT(*) AS CNT
                        FROM EMP
                        GROUP BY JOB, DEPTNO),
                       (SELECT ROWNUM AS RN
                        FROM (SELECT LEVEL FROM DUAL
                        CONNECT BY ROWNUM <= 3))
            GROUP BY RN,
            DECODE(RN, 1, '직군별', 2, '부서별', '총인원'),
            DECODE(RN, 1, JOB, 2, DEPTNO)
            ;
        5. SELF JOIN : 하나의 테이블이 스스로 조인하는 방식으로 순환참조 관계로 표현된 개체를 참조할 때 사용된다.
          1. 사용 방법
            SELF JOIN 사용법
            SELECT E1.EMPNO E2.EMPNO AS MANAGERNO
            FROM EMP E1, EMP E2
            WHERE E1.MANAGERNO = E2.EMPNO
            ;
      2. 수행 방식에 따른 조인 종류
        1. 수행 방식에 따른 조인은 실행 계획으로 확인 가능하다.
        2. 수행 방식에 따른 조인을 확인하기 전에 드라이빙 테이블과 드리븐 테이블에 대해서 알아야 한다.
          1. 드라이빙 테이블 : 기준이 되는 테이블로 조인 시 작업이 선행되는 테이블로 해당 테이블을 기준으로 그 이후의 테이블에 데이터를 매칭하며, Outer Table 이라고도 한다.
          2. 드리븐 테이블 : Outer Table에 의해서 매칭이 되어지는 테이블이며, Inner Table 이라고도 한다.
        3. NESTED LOOP JOIN
          1. 옵티마이저가 드라이빙 테이블을 결정한다.
          2. 드라이빙 테이블로 선정된 테이블의 각 컬럼에 대해서 드리븐 테이블에 연관된 모든 컬럼을 조인한다.
          3. 튜닝 포인트
            1. 테이블 간의 조인 횟수를 최소화 할 수 있도록 구성한다.
            2. 드리븐 테이블의 연결 고리 컬럼에 대해서 인덱스를 반드시 구성한다.
          4. 장점과 단점
            1. 인덱스에 의한 랜덤 액세스에 기반하고 있어 대량의 데이터 처리 시에는 적합하지 않다.
            2. 드라이빙 테이블로는 테이블의 데이터가 적은 마스터 테이블이거나 WHERE 절 조건으로 적절하게 컬럼을 제어할 수 있는 것이어야 한다.
            3. 드리븐 테이블에는 조인을 위한 적절한 인덱스가 반드시 생성되어 있어야 한다.
          5. 조인 횟수를 줄이기 위해서는 테이블 간에 조인되는 순서가 무엇보다 중요하다.
            1. 조인 순서 제어 방법
              1. 조인 순서 제어를 위한 힌트 사용
                1. ORDERED : FROM 절에 기술한 테이블 순서로 제어
                2. LEADING(테이블 명) : 힌트 내에 제시한 테이블이 드라이빙 테이블로 채택
                3. ORDERED 힌트와 LEADING 힌트를 같이 사용 시 LEADING 힌트가 무시된다.
              2. 뷰(View) 활용
              3. 서프레싱(Suppressing) 활용
              4. FROM 절의 테이블 순서 변경 : RBO 에서만 적용 가능하며 CBO에서는 적용되지 않는다.
          6. 연결고리 컬럼에 대한 인덱스의 중요성
            1. 양쪽 모두 인덱스가 있는 경우 두 테이블 중 조회되는 결과가 적은 테이블을 옵티마이저가 선택하여 드라이빙 테이블로 선정한다.
            2. 한쪽만 인덱스가 있는 경우 인덱스가 없는 쪽 테이블을 드라이빙 테이블로 사용한다.
            3. 양쪽 모두 인덱스가 없는 경우 Nested Loops 조인 방식으로 조인이 이루어 지지 않고, HASH JOIN이나 SORT/MERGE JOIN으로 동작한다.
        4. HASH JOIN
          1. 동작 방법 : 읽어 들인 각 테이블의 데이터를 서로 조인하기 위해서 해싱(Hashing)을 이용한 해시 값을 만들어서 조인을 수행한다.
          2. 튜닝 포인트
            1. 드라이빙 테이블을 결정한다.
            2. 각 테이블로 부터 데이터를 읽어 들일 때, 빨리 읽을 수 있도록 한다.
            3. 메모리(HASH_AREA_SIZE)를 최적화 한다.
          3. 장점과 단점
            1. Hash Bucket이 조인 집합에 구성되어 해시 함수 결과를 저장해야 하는데 이러한 처리에는 많은 메모리와 CPU 자원을 소모하게 된다.
            2. 기본적으로  HASH_AREA_SIZE에 지정된 크기만큼의 메모리가 할당되어 사용된다.
            3. 하드웨어 자원이 넉넉한 상황에서는 다른 조인에 비해 보다 효율적인 수행이 가능하나 부족한 상황에서는 다른 조인 방법보다 오히려 느려질 수 있다.
        5. SORT/MERGE JOIN
          1. 수행되는 조건
            1. 연결고리의 컬럼에 인덱스가 전혀 없는 경우 SORT/MERGE JOIN을 수행한다.
            2. 대용량의 자료를 조인해야 함으로써 인덱스 사용에 따른 랜덤 액세스의 오버헤드가 많은 경우 SORT/MERGE JOIN을 수행한다.
          2. 동작 방법
            1. 각 테이블에 대해서 동시에 독립적으로 데이터를 먼저 읽어 들인다.
            2. 읽혀진 각 테이블의 데이터를 조인을 위한 연결 고리(조인 조건으로 연결된 컬럼)에 대해서 정렬을 수행한다.
            3. 정렬이 모두 끝난 후에 조인 작업이 수행된다. 어느 하나가 정렬이 끝나지 않으면 조인 작업을 수행하지 않는다.
          3. 튜닝 포인트
            1. 각 테이블로부터 데이터를 빨리 읽어 들이도록 한다.
            2. 메모리(SORT_AREA_SIZE)를 최적화 한다.
          4. 장점과 단점
            1. 연결고리에 인덱스가 생성되어 있지 않은 경우에 빠른 조인을 위해서 사용된다.
            2. 조인하고자 하는 각 테이블에 대해서 독립적으로 데이터를 읽어 들일 때, 이를 얼마나 빠르게 할 것인가가 중요하다.
            3. 각 테이블로 부터 읽혀진 데이터를 연결고리에 대해 정렬을 수행할 때 이를 얼마나 빠르게 할 것인가가 중요하다.
참고도서 : 실전사례로 살펴보는 SQL 튜닝비법

SQL 튜닝비법 - 인덱스

  1. 인덱스란?  데이터의 고유성을 확인하거나 검색 성능을 향상시키기 위해 사용하는 객체로 책에서 목차 부분에 해당한다.
  2. 인덱스를 사용하는 이유 : 데이터베이스에 저장된 데이터를 빠르게 조회하기 위해서 인덱스를 생성하고 사용하는데 일반적으로 테이블의 전체 데이터 중에서 10~15% 이하의 데이터를 처리하는 경우에 효율적으로 사용이 가능하며 그 이상의 데이터를 처리할 때는 인덱스를 사용하지 않는 것이 더 효율적이다.
  3. 인덱스의 분류
    1. 인덱스 컬럼 값의 유일성 : UNIQUE/NON-UNIQUE
    2. 인덱스를 구성하는 컬럼의 수 : 단일 인덱스/결합 인덱스
      1. 단일 인덱스
        1. 인덱스 내에 컬럼이 하나만 존재하는 형태를 의미한다.
        2. 단일 인덱스의 한계
          1. 인덱스는 기본적으로 정렬을 하게 되는데 특정 데이터를 찾기 위해서 두 개 이상의 테이블에서 찾을 경우 각 테이블의 인덱스를 따라서 여러 번 찾아야 하기 때문에 매우 비 효율적이다.
      2. 결합 인덱스
        1. 인덱스 내에 컬럼이 두 개 이상인 형태를 의미힌다.
        2. 단일 인덱스에서 한 테이블의 인덱스를 찾고 다시 다른 테이블에서 인덱스에 대한 데이터를 찾는 번거로움을 해소해준다.
        3. 위 그림처럼 특정 데이터에 대한 인덱스를 하나로 사용 시에 구조가 간결하게 된다.
        4. 결합 인덱스 컬럼 선택
          1.  WHERE 절에서 AND 조건으로 자주 결합되어 사용되면서 각각의 분포도보다 두 개 이상의 컬럼이 결합될 때 분포도가 좋아지는 컬럼들
          2. 다른 테이블과 조인의 연결고리로 자주 사용하는 컬럼들
          3. 하나 이상의 키 컬럼 조건으로 같은 테이블에서 자주 조회되는 컬럼들
        5. 결합 인덱스 컬럼 순서 결정
          1. 결합 인덱스 구성 시에 Equal로 구성된 경우 범위를 제한하면서 데이터를 찾기 때문에 많이 사용 되거나 분포도가 좋은 컬럼을 우선하게 하여 데이터의 범위를 많이 줄일 수 있다.
          2. 결합 인덱스의 컬럼 순서 결정 조건
            1. WHERE 절 조건에 많이 사용하는 컬럼 우선
            2. Equal(=)로 사용 되는 컬럼 우선 : Equal 로 사용하지 않으면 범위 제한으로 사용 되지 않아 데이터를 많이 줄이지 못한다.
            3. 분포도가 좋은 컬럼 우선
            4. 자주 이용되는 정렬의 순서로 결정
          3. 결합 인덱스 사용 방법
            1. 결합 인덱스 사용
              결합 인덱스 사용법
              EMP_PAY_X1 : (PAY_DAY, PAY_CODE, WORKER_CODE)

              -- 결합 인덱스의 첫번째 컬럼만 사용
              WHERE PAY_DAY = '202010'

              -- 결합 인덱스의 첫번째, 두번째 컬럼 사용
              WHERE PAY_DAY = '202010'
              AND PAY_CODE = '정기급여'

              -- 결합 인덱스 모두 사용
              WHERE PAY_DAY = '202010'
              AND PAY_CODE = '정기급여'
              AND WORKER_CODE = '33139646'
            2. INDEX SKIP SCANNING : 결합 인덱스의 첫번째 컬럼이 WHERE 절에서 제외되어도 두번째 컬럼부터 WHERE의 조건으로 기술된 경우 그 인덱스가 사용된다.
            3. 결합 인덱스 컬럼에 대한 '=' 의 의미
              1. 결합 인덱스에서 '='은 데이터의 범위를 제한 조건으로 사용한다.
              2. 결합 인덱스에서 '='을 사용하지 않으면 체크 조건으로 사용하며, 데이터의 범위가 줄지 않아서 시간이 오래 걸리게 된다.
              3. 인덱스 매칭률 : 인덱스를 구성한 컬럼들이 얼마나 범위 제한 조건으로 사용되는지 나타내는 비율로 식은 아래와 같다.

              4. 결합 인덱스를 사용 시 매칭률은 아래와 같다.
                결합 인덱스 매칭률
                EMP_PAY_X1 : (PAY_DAY, PAY_CODE, WORKER_CODE)

                -- 결합 인덱스의 첫번째 컬럼만 사용 (매칭률 = 1/3)
                WHERE PAY_DAY = '202010'

                -- 결합 인덱스의 첫번째, 두번째 컬럼 사용  (매칭률 = 2/3)
                WHERE PAY_DAY = '202010'
                AND PAY_CODE = '정기급여'

                -- 결합 인덱스 모두 사용  (매칭률 = 3/3 -> 1)
                WHERE PAY_DAY = '202010'
                AND PAY_CODE = '정기급여'
                AND WORKER_CODE = '33139646'
    3. 인덱스의 물리적 구성 방식 : B*Tree/BitMap/Cluster
      1. B*Tree 구조
        1. 밸런스드 트리 인덱스라고 하며, 가장 많이 사용하는 인덱스 구조이고, 인덱스의 데이터 저장 방식이다.
        2. 구성 : Root(기준)/Branch(중간)/Leaf(말단) 노드로 구성된다.
        3. Root 노드는 특정 컬럼으로 인덱스를 생성 시에 컬럼 값들을 정렬하는데 이 때 중간쯤 되는 데이터가 지정된다.
        4. Branch 노드는 Root를 기준을 가지가 되는 부분으로 Leaf 노드에 연결되어 있어 조회하려는 값이 있는 Leaf 노드까지 도달하기 위해 비교/분기해야 될 값들이 저장된다.
        5. Leaf 노드는 인덱스의 키가 되는 데이터와 데이터의 물리적 주소인 ROWID 값을 저장한다.
        6. B*Tree 구조에서는 Leaf 노드단에서 정렬을 한 상태로 존재하게 되는데 해당 구조의 핵심 내용이다.
      2. BitMap
        1. 컴퓨터에서 사용하는 최소 단위인 비트 값을 이용하여 컬럼 값을 저장하고, ROWID를 자동으로 생성한다.
        2. 구성 : 컬럼 값 / START ROWID / END ROWID / BITMAP
        3. 비트맵 인덱스의 특징
          1. UNIQUE INDEX는 생성이 불가능하다.
          2. NULL 값의 저장이 가능하다.
          3. 최대 30개 컬럼까지 생성이 가능하다.
          4. 입력될 값의 종류가 적은 컬럼은 B*Tree 인덱스보다 유용하지만, INSERT, UPDATE, DELETE가 빈번히 발생하는 컬럼이면 비트맵 값의 갱신으로 부하가 집중되어 성능저하가 된다.
      3. Cluster
        1. 클러스터란? 같은 성질의 컬럼을 가지고 있는 테이블들이나 조인 등을 위해 자주 함께 사용 되는 테이블들을 하나의 그룹으로 묶은 객체를 의미한다.
        2. 하나의 클러스터로 묶인 테이블들이 공통적으로 갖게 되는 컬럼을 클러스터 키라고 하고 이 클러스터 키로 만들어진 인덱스가 클러스터 인덱스이다.
  4. 인덱스 선정 절차
    1. 프로그램 개발에 이용된 모든 테이블에 대해서 Access Path 조사 (Access Path : Where 절부터 Order by 절까지를 의미한다.)
    2. 인덱스 컬럼 선정 및 분포도 조사 : 분포도가 높은 컬럼을 선정
    3. Critical Access Path 결정 및 우선 순위 선정 (Critical Access Path : Where 절부터 Order by절까지 조사 시에 자주 사용되는 것을 의미한다.)
    4. 인덱스 컬럼의 조합 및 순서 결정
    5. 시험 생성 및 테스트
    6. 결정된 인덱스를 기준으로 프로그램 반영
    7. 실제 반영
  5. 인덱스 생성 및 변경 시 고려할 사항
    1. 기존 프로그램의 동작에 영향성을 검토한다.
    2. 필요할 때마다 인덱스 생성으로 인한 인덱스 개수의 증가와 이로 인한 DML 작업의 속도를 검토한다.
    3. 개별 컬럼의 분포도가 좋지 않을지라도 다른 컬럼과 결합하여 자주 사용 되고, 결합할 경우에 분포도가 양호하다면 결합 인덱스 생성을 긍정적으로 검토한다.
  6. 인덱스 생성 방법 : CREATE INDEX Index 명 ON Table 명 (Column1, Column2, ...);
  7. 인덱스 확인 방법 : SELECT * FROM ALL_IND_COLUMNS WHERE TABLE_NAME = 'Table 명';
  8. 인덱스 삭제 방법 : DROP INDEX Index 명;
  9. 인덱스 스캔의 원리
    1. 조건을 만족하는 최초의 인덱스 Row를 찾음
    2. Access된 인덱스 Row의 ROWID를 이용하여 테이블에 있는 Row를 찾는다.
    3. 처리 범위가 끝날 때까지 차례대로 다음 인덱스 Row를 찾는다. (2번 반복)
  10. 인덱스 사용
    1. 고유 인덱스의 Equal(=) 검색
    2. 고유 인덱스의 범위(>=, >, <, <=) 검색
    3. 중복 인덱스의 범위(=, LIKE) 검색 (단, LIKE 검색 시 변수 앞에 '%'가 오는 경우는 사용 못 함)
    4. OR, IN 조건
    5. NOT BETWEEN 검색
  11. 인덱스를 사용하지 말아야 하는 경우는 조건에 의한 처리 범위가 넓어져 분포도가 나빠지는 경우가 있는데, 이 때 인덱스 보다는 FULL TABLE SCAN 으로 처리하여 입출력 시에 여러 개의 데이터를 처리하는게 인덱스 사용하는 것보다 효율적이기 때문이다.
  12. 인덱스 사용이 불가능한 경우
    1. 컬럼의 내외부 변형이 발생(External suppressing/Internal suppressing)
      컬럼의 내외부 변형
      EMP_PAY_X1 : (PAY_DAY, PAY_CODE, WORKER_CODE)

      -- 결합 인덱스의 첫번째 컬럼에 외부 변형 발생
      WHERE TO_NUMBER(PAY_DAY) = 202010

      -- 결합 인덱스의 첫번째 컬럼에 내부 변형
      WHERE PAY_DAY = 202010
      -> TO_NUMBER(PAY_DAY) = 202010 내부 변형됨
      AND PAY_CODE = '정기급여'
    2. IS NULL, IS NOT NULL을 사용하여 비교
      IS NULL, IS NOT NULL 사용
      EMP_PAY_X1 : (PAY_DAY, PAY_CODE, WORKER_CODE)

      -- 결합 인덱스의 첫번째 컬럼에 IS NULL 사용
      WHERE PAY_DAY IS NULL

      -- 결합 인덱스의 두번째 컬럼에 IS NOT NULL 사용
      WHERE PAY_DAY = '202010'
      AND PAY_CODE IS NOT NULL
    3. LIKE 검색 시에 변수 앞에 '%' 사용하여 비교
      LIKE 검색 시 변수 앞에 '%' 사용
      EMP_PAY_X1 : (PAY_DAY, PAY_CODE, WORKER_CODE)

      -- 결합 인덱스의 첫번째 컬럼의 변수 앞에 '%' 사용
      WHERE PAY_DAY LIKE '%2010'

      -- 결합 인덱스의 두번째 컬럼의 변수 앞에 '%' 사용
      WHERE PAY_DAY = '202010'
      AND PAY_CODE LIKE '%급여'
    4. 여러 컬럼에 OR 조건 사용
      여러 컬럼에 OR 조건 사용
      EMP_PAY_X1 : (PAY_DAY, PAY_CODE, WORKER_CODE)

      -- 결합 인덱스의 여러 컬럼에 OR 조건 사용
      WHERE PAY_DAY = '202010'
      AND (PAY_CODE = '정기급여' OR
                WORKER_AGE = '30' OR
                WORKER_ADDRESS = '강남구')
    5. 부정형 비교(NOT 연산자 사용)
      부정형 비교
      EMP_PAY_X1 : (PAY_DAY, PAY_CODE, WORKER_CODE)

      -- 결합 인덱스의 첫번째 컬럼에 NOT 연산자 사용
      WHERE PAY_DAY != '202010'

      -- 결합 인덱스의 두번째 컬럼에 NOT 연산자 사용
      WHERE PAY_DAY = '202010'
      AND PAY_CODE != '정기급여'
  13. 옵티마이저에서 인덱스 선택 절차
    1. 특정 테이블에 SQL에 주어진 조건으로 사용할 수 있는 인덱스가 두 개 이상인 경우 조건에 가장 적절한 인덱스를 선택한다.
    2. 옵티마이저의 인덱스 선택시 판단 절차
      1. 주어진 조건에 대한 각 인덱스 별로 매칭률을 계산하여 매칭률이 높은 인덱스를 우선적으로 선택한다.
      2. 인덱스 별 매칭률이 같을 경우 인덱스를 구성하는 컬럼의 개수가 많은 인덱스를 우선적으로 선택
      3. 인덱스 별 매칭률이 같고, 인덱스를 구성하는 컬럼의 개수도 같을 경우는 가장 최근에 생성된 인덱스를 우선적으로 선택한다.
참고도서 : 실전사례로 살펴보는 SQL 튜닝비법

SQL 튜닝비법 - 옵티마이저

  1. 옵티마이저란? DBMS의 두뇌라고 할 수 있으며, 사용자가 실행한 SQL을 해석하고 데이터를 추출하기 위한 실행계획을 수립하는 프로세스이다.
  2. 옵티마이저의 종류
    1. RBO (Rule Based Optimizer)
      1. 처리 방식의 우선 순위를 정해서 앞서는 방식을 채택하여 실행계획을 수립한다.
      2. 처리 방식에 따른 우선 순위
        1. Row ID에 대한 단일 행 실행
        2. Cluster 조인에 의한 단일 행 실행
        3. Hash Cluster Key에 의한 단일 행 실행
        4. Unique Key 또는 Primary Key에 의한 단일 행 실행
        5. Cluster 조인
        6. Hash Cluster Key
        7. Indexed Cluster Key
        8. 결합 컬럼(Composite) 인덱스
        9. 단일 컬럼(Single) 인덱스
        10. 인덱스에 의한 유한 영역(Bounded Range) 검색
        11. 인덱스에 의한 무한 영역(Unbounded Range) 검색
        12. 소트 머지(Sort Merge) 조인
        13. 인덱스로 구성된 컬럼의 최대 또는 최소 처리
        14. 인덱스로 구성된 컬럼의 Order by
        15. 인덱스 없이 전체 태이블 스캔 (FTS : Full Table Scan)
      3. 위 처리 순서 중에서 1부터 15 순으로 채택하도록 한다.
      4. 한계점
        1. 힌트를 사용할 수 없다.
        2. Hash Join을 사용할 수 없다.
    2. CBO (Cost Based Optimizer)
      1. 비용 즉, 옵티마이저가 문장을 수행하는데 걸릴 것이라고 추측한 시간을 최소화 해서 데이터를 빨리 처리하도록 실행계획을 수립한다.
      2. 영향을 미치는 비용 산정 요소 : 각종 통계 정보, Hint, 연산자, Index, Cluster, DBMS 버전, CPU/Memory 용량, Disk I/O 등과 같이 매우 다양한다.
        1. CBO에서 영향을 미치는 비용 산정 요소 중에서 주기적으로 확인이 필요한 통계정보는 가장 효율적인 실행계획을 수립하기 위한 최소 비용을 계산하는데 중요하게 사용된다.
        2. 통계정보는 정기적인 분석 작업을 통해서 확인한다.
          1. 분석작업은 ANALYZE 명령어를 사용하는 방식과 DBMS_STATS 패키지를 이용하는 방법이 있다. 
          2. ANALZE 실행 방법
            ANALYZE 사용법
            ANALYZE TABLE emp COMPUTE STATISTICS;
            : emp 테이블의 전체 내용을 분석한다.

            ANALYZE TABLE emp ESTIMATE STATISTICS
                                                SAMPLE 10 PERCENT;
            : emp 테이블의 10%의 내용만 분석한다.

            ANALYZE TABLE emp ESTIMATE STATISTICS
                                                SAMPLE 5 ROWS;
            : emp 테이블의 5개의 Rows만 분석한다.

            ANALYZE INDEX XINDEX COMPUTE STATISTICS;
            : XINDEX Index의 내용을 분석한다.

            -- ANALYZE 실행 여부 확인
            SELECT TABLE_NAME, NUM_ROWS, LAST_ANALYZED
            FROM USER_TABLES
            WHERE TABLE_NAME IN ('테이블 명')
          3.  DBMS_STATS 패키지 실행 방법
            DBMS_STATS 패키지 사용법
            EXEC DBMS_STATS.GATHER_TABLE_STATS(Owner Name->'Schema_Name', 'Table Name', Estimate_Percent->10, NULL, TRUE/FALSE(Cascade))
            : 특정 테이블에 대한 통계 정보 생성

            EXEC DBMS_STATS.GATHER_TABLE_STATS(Owner Name->'Schema_Name')
            : 특정 스키마에 대한 통계정보 생성
  3. 옵티마이저 모드
    1. initSID.ora라는 파일 내에 OPTIMIZER_MODE로 실행계획을 어느 종류의 옵티마이저로 쓸지, 어느 수준까지 나타낼지, 범위는 어떻게 되는지 등에 따라 실행계획이 달라지게 되는데 이것을 설정하여 최적의 실행계획을 나타내게 된다.
    2. 모드 종류
      1. RULE : RBO으로 최적의 실행계획을 세운다.
      2. CHOOSE : SQL이 실행되는 환경에서 통계 정보를 가져올 수 있으면 CBO, 그렇지 않으면 RBO로 실행계획을 세운다.
      3. FIRST_ROWS : 옵티마이저가 처리할 결과 중 첫 건을 출력하는데 걸리는 시간을 최소화 할 수 있는 실행계획을 세운다.(CBO)
      4. FIRST_ROWS_n : n 건을 출력하는데 걸리는 시간을 최소화 할 수 있는 실행계획을 세우는 것으로 FIRST_ROWS를 보완하기 위한 옵션이다.(CBO)
      5. ALL_ROWS : SQL 실행 결과 전체에 대한 최적화된 실행 계획을 세운다.(CBO)
  4. RBO와 CBO의 실행계획 비교
    1. 예시
      실행 계획에 대한 예시
      SELECT
       E.ENAME,
       D.DNAME
      FROM EMP E,
                 DEPT D
      WHERE E.DEPNO = D.DEPNO
      AND D.DEPNO = 10
      ;
    2. RBO를 이용한 실행계획
      Id
      Operation
      Name
      Rows
      0 SELECT STATEMENT
      3
      1  NESTED LOOPS
      3
      2   NESTED LOOPS
      3
      *3    TABLE ACCESS FULL EMP 1
      *4    INDEX UNIQUE SCAN PK_DEPT 1
      5   TABLE ACCESS BY INDEX ROWID DEPT 1
    3. CBO를 이용한 실행계획
      Id
      Operation
      Name
      Rows
      0SELECT STATEMENT
      3
      1 NESTED LOOPS
      3
      2  TABLE ACCESS BY INDEX ROWIDDEPT1
      *3   INDEX UNIQUE SCANPK_DEPT1
      *4  TABLE ACCESS FULLEMP3
    4. 위와 같이 RBO와 CBO로 수립한 실행계획이 다른 경우, 수립할 실행계획이 동일하게 수정이 필요하며, 이 때 필요한 것이 SQL 튜닝이다.
참고도서 : 실전사례로 살펴보는 SQL 튜닝비법

SQL 튜닝비법 - 실행계획

  1. 실행계획이란? 사용자가 SQL문으로 필요한 데이터를 추출하려고 할 때 어떤 과정으로 작업이 이루어지를 나타내는 작업 절차를 의미한다.
  2. 실행계획을 확인하는 방법
    1. MSSQL의 경우는 쿼리 창에서 오른쪽 마우스를 클릭하게 되면 "예상 실행 계획 표시"를 통해서 볼 수 있다.
    2. Oracle에서는 명령을 통해서 실행계획을 확인해볼 수 있다.
      1. EXPLAIN PLAN : SQL에 대한 실행계획만 확인할 수 있으며, 데이터를 처리하지 않는다.
        EXPLAIN PLAN 사용법
        EXPLAIN PLAN
        SET STATEMENT_ID = 'PLAN_TEST_1' INTO PLAN_TABLE
        FOR
        SELECT
         E.ENAME,
         E.DEPNO,
         D.DNAME
        FROM EMP E,
                   DEPT D
        WHERE E.DEPNO = D.DEPNO
        ;

        -- 실행계획 출력
        SELECT *
        FROM TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE','PLAN_TEST_1','ALL'))
        ;
      2. AUTOTRACE : SQL에 대한 실행계획뿐만 아니라 옵션에 따라서 여러가지 정보를 선택적으로 확인이 가능하며 실행된 데이터도 나타낼 수 있다.
        AUTOTRACE 사용법
        SET AUTOTRACE ON;

        SELECT 
         E.ENAME,
         E.DEPNO,
         D.DNAME
        FROM EMP E,
                   DEPT D
        WHERE E.DEPNO = D.DEPNO
        ;

        -- 실행된 데이터 결과와 실행계획이 모두 출력
      3. 명령 옵션
        1. SET AUTOTRACE ON : SQL 실행 결과를 보여주고, 실행계획과 통계정보를 모두 출력
        2. SET AUTOTRACE ON EXPLAIN : SQL 실행 결과를 보여주고, 실행계획만 출력
        3. SET AUTOTRACE ON STATISTICS : SQL 실행 결과를 보여주고, 통계정보만 출력
        4. SET AUTOTRACE TRACEONLY : SQL 실행 결과는 보여주지 않고 실행계획과 통계 정보 모두 출력
        5. SET AUTOTRACE TRACEONLY EXPLAIN : SQL 실행 결과는 보여주지 않고, 실행계획만 출력
        6. SET AUTOTRACE TRACEONLY STATISTICS : SQL 실행 결과는 보여주지 않고, 통계 정보만 출력
        7. SET AUTOTRACE OFF : 실행계획, 통계정보를 출력해주지 않는다.
  3. 실행계획 분석 방법
    1. 실행계획 읽는 순서
      1. 위에서 아래로 읽어 내려가면서 제일 먼저 읽을 스텝을 찾는다.
      2. 내려가는 과정에서 같은 들여쓰기가 존재하면 무조건 위 -> 아래 순으로 읽는다.
      3. 읽고자하는 스텝보다 들여쓰기가 된 하위 스텝이 존재하면, 가장 안쪽으로 들여쓰기 된 스텝을 시작으로 하여 한 단계씩 상위 스텝으로 읽어 나온다.
    2. 순서에 따른 읽는 순서 확인
      실행계획 읽는 순서 예시
      예시
      Id
      Operation
      Name
      Rows
      Bytes
      Cost (%CPU)
      Time
      0 SELECT STATEMENT


      3(100)
      1  NESTED LOOPS
      1 117 3(0) 00:00:01
      2   TABLE ACCESS BY INDEX ROWID EMP 1 87 2(0) 00:00:01
      3    INDEX UNIQUE SCAN PK_EMP 1
      1(0) 00:00:01
      4   TABLE ACCESS BY INDEX ROWID DEPT 409 12270 1(0) 00:00:01
      5    INDEX UNIQUE SCAN PK_DEPT 1
      0(0)
      실행 순서
      3 -> 2 -> 5 -> 4 -> 1 -> 0

참고도서 : 실전사례로 살펴보는 SQL 튜닝비법

데이터베이스 결과 값 일부 조회 방법

데이터베이스 결과 값 일부 조회
  1. 필요성 : 데이터베이스의 조건에 맞는 결과를 모두 조회할 경우, 데이터베이스 서버에 무리가 갈 수 있기 때문에 일부만 조회해서 확인한다.
  2. 주로 사용하는 SQL 별 사용 방법
    1. MS SQL
      1. SELECT TOP 숫자 | PERCENT 열 이름 FROM 테이블 명 WHERE 조건문
      2. 예시1) SELECT TOP 10 * FROM TEST_TABLE WHERE 1=1
      3. 예시2) SELECT TOP 20 PERCENT * FROM TEST_TABLE WHERE 1=1
    2. My SQL
      1. SELECT 열 이름 FROM 테이블 명 WHERE 조건문 LIMIT 숫자
      2. 예시) SELECT * FROM TEST_TABLE WHERE 1=1 LIMIT 10
    3. Oracle
      1. SELECT 열 이름 FROM 테이블 명 WHERE 조건문 ROWNUM <= 숫자
      2. 예시) SELECT * FROM TEST_TABLE WHERE 1=1 AND ROWNUM <= 10
  3. 사용 결과 예시
    1. 원본 테이블 TEST_TABLE
      사원번호사원명부서명
      1234김일차인사과
      1235이이차연구부서
      1245조삼차생산부서
      2345주사차법무부서
      2345지오차검증부서
    2. 각 사용 시 출력되는 결과 (3개 까지 출력)
      사원번호사원명부서명
      1234김일차인사과
      1235이이차연구부서
      1245조삼차생산부서
      MS SQL : SELECT TOP 3 * FROM TEST_TABLE
      My SQL : SELECT * FROM TEST_TABLE LIMIT 3
      ORACLE : SELECT * FROM TEST_TABLE WHERE ROWNUM <= 3

데이터베이스 프로그래밍 기초

  1. DBMS 기초
    1. DBMS 란?
      1. 정의 : DataBase Management System 의 약자로 데이터베이스를 관리하기 위해서 데이터를 저장, 유지보수하고 검색하는 시스템을 이야기한다. -> CRUD (Create(생성), Retrieve(검색), Update(수정), Delete(삭제))
      2. 목적
        1. 대량의 데이터를 처리한다. (빅데이터보다 작은 단위를 말한다.)
        2. 주로 검색을 사용한다.
        3. 다양한 자료 구조와 검색 구조를 사용해서 주로사용하는 검색을 빠르게 할 수 있도록 하여 검색에 최적화를 한다. (검색의 최적화를 위해서 데이터를 정렬한다.)
    2. DBMS 최적화
      1. DBMS 에서 주로 사용하는 것이 검색 기능으로 이를 최적화하기 위해서 정렬과 인덱스라는 기술을 사용한다.
      2. 정렬
        1. 정의 : 데이터를 빠르게 찾기 위해서 알파벳 또는 숫자 순으로 나열하는 것을 말한다.
        2. DBMS 에서 주로 사용하는 검색을 빠르게 하기 위해서 반드시 정렬 되어 있어야 한다.
        3. 정렬이 되어 있지 않으면, 자료가 어디 있는지 알 수가 없기 때문에 평균적으로 전체 데이터의 절반이 필요하다.
        4. 정렬이 되어 있으면, 자료가 어디 있는지 파악하기가 쉽기 때문에 빠른 시간 안에 찾을 수 있다.
        5. 정렬을 할 때 주로 적은 시간이 사용되는 퀵정렬이나 힙정렬 계열이 주로 사용된다.
      3. 인덱스
        1. 정의 : 데이터가 추가 / 삭제 / 변경될 때마다 특정 위치 예를 들어 한 가운데 / 왼쪽 가운데 / 오른쪽 가운데 값 등을 미리 계산해서 자료를 찾기 쉽게 하는 것으로 사전이나 책에서 목차라고 생각하면 이해가 쉽다.
        2. 인덱스 종류
          1. 이진 검색 (Binary Search)
            1. 데이터를 정렬 후 특정 단어를 검색하는 경우 저장된 정보를 이용해서 단어가 나올 때까지 계속 찾는다.
          2. B-Tree 계열
            1. 이진 검색과 유사하지만 한 번에 비교를 2 번하며, 각 세가지 경우에 따라서 특정 단어를 찾는다.
            2. 작은 값 보다 작은 경우, 큰 값과 작은 값 사이인 경우, 큰 값보다 큰 경우
        3. 인덱스는 데이터가 추가, 수정, 삭제 시에 반드시 갱신을 한다.
    3. DBMS 의 종류
      1. 계층형 데이터베이스
      2. 네트워크형 데이터베이스
      3. 관계형 데이터베이스 (RDBMS)
      4. 객체지향 데이터베이스
      5. 객체관계형 데이터베이스 (ORDBMS)
      6. NoSQL(Not Only SQL)
    4. RDBMS (관계형 데이터베이스)
      1. 정의
        1. 관계형 데이터베이스 시스템이다.
        2. 주로 테이블 기반의 DBMS 로 테이블 - 컬럼 형태의 데이터 저장방식으로 하나의 테이블에 여러 개의 컬럼으로 구성된다.
          예) 학생테이블
          이름 성별 나이 전화번호
          김래원 남자 32 010-1234-1234
          신세경 여자 30 010-5678-1234
          ... ... ... ...
          서지혜 여자 31 010-7890-1234
        3. 테이블과 테이블 간의 연관관계를 이용해 필요한 정보를 구하는 방식이다.
        4. 모델링은 E-R(Entity Relationship) 모델을 사용한다.
      2. 기본 용어
        1. 스키마 (Schema)
          1. DB, 테이블 정의 내역을 의미한다.
        2. SQL 쿼리 (Standard Query Language)
          1. 관계형 DBMS 를 사용하는 전용 질의 언어이다.
          2. 대소문자를 가리지 않는다.
          3. 예) SELECT * FROM STUDENT_TABLE
        3. 테이블 (Table)
          1. 정보들의 묶음 단위이다.
          2. 예) 학교, 학생, 교수, ...
        4. 컬럼 (Column)
          1. 테이블을 구성하는 정보들이다.
          2. 예) 학생 테이블 - 이름, 주소, 전화번호, 나이, 성별, ...
        5. 레코드 (Record)
          1. 테이블에 들어 있는 여러가지 인스턴스 하나하나를 지정
          2. 컬럼에 대한 데이터들을 의미한다.
          3. 예) 학생 테이블 - 이름 : 홍길동, 주소 : 서울시 ..., 전화번호 : 010-1234-1234, 성별 : 남자 ...
          4. 기본키(Primary Key:PK)로 구별 가능하다.
        6. 기본키 (Primary Key:PK)
          1. 테이블에서 하나의 레코드를 지정할 수 있는 하나 이상의 컬럼 집합으로 각 레코드를 구별할 수 있는 유일한 정보이다.
          2. 예) 주민등록번호, 학번, SSN(Social Security Number), ...
        7. 외래키 (Foreign Key:FK)
          1. 어떤 테이블의 기본키가 다른 테이블의 컬럼에 들어 있을 경우를 의미한다.
        8. 도메인 값 (Domain Value)
          1. 각 컬럼에서 나올 수 있는 후보 값을 의미한다.
  2. MySQL 설치 및 제거 방법
    1. MySQL 설치 방법
      1. MySQL 홈페이지로 이동해서 사용하고자 하는 툴을 받아서 설치하는 작업을 진행한다.
      2. MySQL 홈페이지 : https://www.mysql.com/
      3. MySQL 다운로드 경로 : http://dev.mysql.com/downloads/mysql/
    2. MySQL 삭제 방법
      1. Windows
        1. 설치된 툴을 지우는 프로그램 추가/삭제 를 이용해서 삭제하도록 한다.
        2. 설치 시에 필요에 따라서 .NET Framework 4.5.2 를 설치 요구를 할 수 있다.
      2. OS X
        1. 아래 명령어를 차례로 입력하도록 하며, 기존에 사용하던 파일이 지워지므로 반드시 백업을 하고 진행한다.
        2. 명령어
          1. sudo rm /usr/local/mysql
          2. sudo rm -rf /usr/local/mysql *
          3. sudo rm -rf /Library/StartupItems/MySQLCOM
          4. sudo rm -rf /Library/PreferencePanes/My*
          5. rm -rf /Library/PreferencePanes/My*
          6. sudo rm -rf /Library/Receipts/mysql*
          7. sudo rm -rf /Library/Receipts/MySQL*
          8. sudo rm -rf /var/db/receipts/com.mysql.*
      3. OS X 에서 MySQL 설치 후에 World 데이터베이스가 출력되지 않아서 Windows 환경에서 실습 진행
  3. MySQL 기본 사용법
    1. Windows 에서 설치가 마무리가 되면, "C:\Program Files\MySQL\MySQL Server 5.7\bin" 위치를 확인하면 MySQL 에서 사용하는 명령어들이 보이며, 주로 "mysql" 실행 파일을 사용한다.
    2. MySQL 시작하는 방법은 Windows 의 CMD 창을 열어서 위 경로를 이동한다.
    3. CMD 창에서 환경변수 설정해서 바로 사용하는 방법
      1. 내 컴퓨터 마우스 오른쪽 클릭해서 속성을 누른다.
      2. 속성 내에서 아래 그림과 같이 "고급 시스템 설정" 을 누른다.
      3. 시스템 속성에서 "환경 변수" 를 선택하면 아래와 같은 창이 뜬다.
      4. 환경 변수 창에서 아래 시스템 변수부분에 "편집(I)" 버튼을 눌러서 그림과 같이 입력해주고 "확인 " 버튼을 누른다.
      5. 그리고 시스템 변수 내에 "Path" 를 찾아서 편집을 눌러서 "%MySQL_HOME%;" 을 입력한다.
      6. 그 후 모두 "확인" 버튼을 눌러서 창을 닫아준다. (취소 버튼을 누르면 해당 설정이 저장되지 않은 상태로 되지 조심한다.)
      7. CMD 창을 열어서 아래 그림과 같은 메시지가 출력되면 환경변수가 제대로 설정이 된 것이다.
      8. 그 후에 실습을 진행한다.
      9. 실행 방법은 cmd 창에서 "mysql -uroot -p" 를 입력 후 비밀번호를 입력하여 로그인하여 사용
    4. 로그인 후에 "sql>" 프롬프트 창에서 아래 명령어를 입력한다.
      1. show databases; : DB 들의 목록을 표시한다.
      2. use world; : 목록에 표시된 DB 중에 "world" 라는 DB 를 선택한다.
      3. show tables; : World DB 의 테이블 목록을 표시한다.
      4. desc city; : city 테이블의 구조를 표시한다.
      5. select * from city; : city 테이블의 내용을 표시한다. (결과가 많아서 명령어 친 부분은 보이지 않는다.)
  4. SQL(DML)
    1. SQL이란?
      1. SQL은 Structured Query Language의 약자로 데이터베이스에 있는 필요한 정보를 사용할 수 있도록 도와주는 언어이다.
      2. 사용방법이나 문법이 다른 언어(Java, C, C#, VB 등) 보다 단순하여 하나를 배워두면 모든 DBMS에서 사용가능하다.
      3. 대소문자 구별하지 않으나 테이블 내의 데이터 내용은 구별한다.
    2. SQL의 이해
      1. 사용자나 프로그램이 필요한 데이터를 가져오기 위해 SQL을 작성한다.
      2. DBMS가 DB에서 사용자가 작성한 SQL을 통해서 데이터를 가져온다.
      3. 사용자는 SQL을 통해서 가져온 데이터를 볼 수 있다.
      4. 해당 내용은 아래 그림으로 요약할 수 있다.
    3. SQL의 종류
      1. DML(Data Manipulation Language)
        1. 테이블의 데이터를 조작하는 기능
        2. 테이블의 레코드를 CRUD(Create, Retrieve, Update, Delete)
          1. INSERT : 데이터베이스 객체에 데이터를 입력한다.
          2. SELECT : 데이터베이스 객체 안에 데이터를 조회한다.
          3. UPDATE : 데이터베이스 객체 안의 데이터를 수정한다.
          4. DELETE : 데이터베이스 객체에 데이터를 삭제한다.
      2. DDL(Data Definition Language)
        1. DB, 테이블의 스키마를 정의, 수정하는 기능
        2. 테이블 생성, 컬럼 추가, 타이변경, 각종 제약조건 지정, 수정 등
          1. CREATE : 데이터베이스 객체를 생성한다.
          2. SHOW : 등록된 데이터베이스 객체를 조회한다.
          3. DROP : 데이터베이스 객체를 삭제한다.
          4. ALTER : 기존에 존재하는 데이터베이스 객체를 다시 정의한다.
      3. DCL(Data Control Language)
        1. DB나 테이블의 접근권한이나 CRUD 권한을 정의하는 기능
        2. 특정 사용자에게 테이블의 조회권한 허가/금지 등
          1. GRANT : 데이터베이스 객체에 권한을 부여한다.
          2. REVOKE : 이미 부여된 데이터베이스 객체 권한을 취소한다.
    4. CRUD(Create, Retrieve, Update, Delete)의 이해
      1. DML에서 CRUD 이해
        1. Create에 해당하는 DML은 INSERT로 새로운 레코드를 추가한다. 사용방법은 "INSERT INTO 추가할 레코드 내용"
        2. Retrieve에 해당하는 DML은 SELECT로 조건을 만족하는 테이블의 레코드를 찾아서 조회해준다. 사용방법은 "SELECT * FROM 조회할 테이블 명"
        3. Update에 해당하는 DML은 UPDATE로 조건을 만족하는 테이블의 레코드를 수정한다. 사용방법은 "UPDATE 수정할 테이블 명 SET 수정할 내용"
        4. DELETE에 해당하는 DML은 DELETE로 조건을 만족하는 테이블의 레코드를 삭제한다. 사용방법은 "DELETE FROM 삭제할 테이블 명"으로 DELETE 사용 시에 반드시 조건을 지정해야하며 그렇지 않으면 모든 레코드가 지워진다.
    5. 쿼리 결과 중복 제거(DISTINCT)
      1. DML의 SELECT문의 결과값에서 특정 컬럼만 출력할 경우, 중복된 값들이 나오는 경우에 이를 제거해서 표시하는 기능
      2. 사용방법 : SELECT DISTINCT 컬럼명1, 컬럼명2, ... FROM 테이블 명 WHERE 조건절
      3. 적용 그림은 다음과 같다.
    6. 논리연산자(AND, OR, NOT, IN, BETWEEN)
      1. SELECT문의 조건절에 논리 조건을 적용하는 연산자
      2. 사용방법 : SELECT * FROM 테이블 명 WHERE (NOT) 조건1 AND/OR 조건2, ...
      3. AND, OR, NOT 과 관련된 결과 그림은 다음과 같다.
        1. AND 결과
        2. OR 결과
        3. NOT 결과
        4. IN 결과
        5. IN 과 = 의 차이
          1. Where 절에서 = 은 관계연산자로 특정 컬럼의 값이 지정한 값과 같은 결과만 출력한다.
          2. Where 절에서 IN은 =, OR을 한 결과와 같다, IN의 경우는 = 과는 다르게 다중입력이 가능하다. ex) IN ('KOR', 'USA')
        6. BETWEEN 결과
    7. 결과 정렬(ORDER BY)
      1. SELECT문의 결과값을 특정한 컬럼을 기준으로 오름차순/내림차순으로 정렬한다.
      2. 기본 값은 오름차순이며, 내림차순은 ORDER BY 컬럼명 DEESC 로 표현한다.
      3. 정렬 전 테이블
      4. 오름차순으로 정렬한 테이블
      5. 내림차순으로 정렬한 테이블
    8. 결과 값 일부 조회
      1. 결과값 일부조회하는 LIMIT(ROWNUM, TOP)
      2. SQL 쿼리 결과가 너무 크면 전체화면에서 모두 나타내지 못해서 잘리는 경우가 발생하거나 상위 몇 번째까지만 보고 싶을 경우에 사용한다.
      3. 비표준 기능으로 오라클에서는 ROWNUM, SQLServer 에서는 TOP으로 사용된다.
      4. 사용 시에 다음과 같은 결과를 얻을 수 있다.
    9. 집합 함수(Aggregation Function)
      1. 테이블의 전체 레코드를 대상으로 특정 컬럼을 적용해서 한 개의 값을 리턴하는 함수
      2. 사용함수 종류 : Count(), Avg(), Sum(), Min(), Max(), First(), Last, ...
        1. Count 결과
        2. Sum 결과
        3. Avg 결과
        4. Min 결과
        5. Max 결과
      3. 기타 유용한 함수
        1. LENGTH() : 레코드의 문자열 컬럼의 글자 수를 리턴한다.
        2. MID() : 문자열의 중간부분을 리턴한다.
        3. UPPER()/LOWER() : 문자열을 대문자/소문자로 리턴한다.
        4. ROUND() : 레코드의 숫자 컬럼 값을 반올림해서 리턴한다.
    10. Join
      1. 서로 다른 테이블을 공통 컬럼을 이용해서 합치는 테이블 연산을 말한다.
      2. 조인의 결과는 이전 테이블의 컬럼 수와 동일한다.
      3. 조인 시에 각 테이블의 컬럼을 구분하기 위해서 테이블1.컬럼1, 테이블2.컬럼1 이런 식으로 구분을 한다.
      4. 사용 방법 : SELECT * FROM 테이블1 Join 테이블2 on 테이블1, 2에 대한 조건문
      5. Join의 종류
        1. INNER Join : 조인 시에 NULL 값을 허용하지 않으며 NULL 값인 경우 제외하고 결과를 출력한다.
        2. LEFT Join : 조인 시에 왼쪽 테이블의 NULL 값을 포함해서 결과를 출력한다.
        3. RIGHT Join : 조인 시에 오른쪽 테이블의 NULL 값을 포함해서 결과를 출력한다.
        4. Full Join : 조인 시에 NULL 값을 허용해서 결과를 출력하는데 MySQL에서는 지원하지 않는다.
    11.  ALIAS
      1. SQL 쿼리 결과 생성 시에 컬럼 명에 대한 별도의 명칭을 붙이는 기능이다.
      2. 조인 시에 많이 사용된다.
      3. 사용 방법 : SELECT 테이블1.컬럼1 AS 별명1, ..  FROM 테이블1
    12. 뷰(VIEW)
      1. SQL 쿼리의 결과 테이블을 임시 테이블로 저장해서 사용하는 용도로 사용하며, 그 용도가 끝나면 명시적으로 삭제해야 한다.
      2. 사용방법 : CREATE VIEW 뷰 이름 AS SELECT ...
    13.  SELECT INTO와 INSERT INTO
      1. 뷰의 기능과 동일하게 테이블을 생성한 후에 바로 결과 테이블을 저장할 수 있고, 동일한 테이블을 생성한 후에 INSERT 를 이용해서 결과 테이블을 저장할 수 있는 방법이 있다.
      2. 테이블을 생성한 후에 바로 테이블을 저장하는 방법 : CREATE TABLE 테이블명 SELECT * FROM 테이블 명 -> SELECT INTO
      3. 테이블을 생성한 후에 그 테이블에 저장하는 방법 : INSERT INTO 테이블명1 SELECT * FROM 테이블2 ... -> INSERT INTO
    14. CASE ... WHEN ... END
      1. SQL의 조건문에 해당하며, IF/ELSE 와 동일하다고 생각하면 된다.
      2. 사용방법 : CASE WHEN 조건값 1 THEN ... WHEN 조건값2 THEN... ELSE... END
      3. 사용 시 주의점은 CASE 조건문을 모두 작성 후에 END를 붙여주어서 조건문의 끝을 알려주도록 한다.
    15. Like 검색
      1. Like 는 검색하려는 키워드를 모두 알지 못할 때 일부문자를 사용해서 해당 패턴에 맞는 레코드들을 찾아줄 떄 사용한다.
      2. 사용방법 : SELECT * FROM 테이블 WHERE 컬럼명 LIKE 패턴 (와일드 카드인 %, _ 를 사용한다.)
      3. LIKE 검색 시에 OR 같은 논리연산을 하지 않도록 한다. DB에 부담을 줄 수 있기 때문이다.
      4. %를 이용한 LIKE검색
      5. _를 이용한 LIKE 검색
    16. NULL 값과 NULL 함수
      1. 레코드 중에 NULL 값을 허용할지 여부는 컬럼명 IS NULL 을 이용해서  허용하고, IS NOT NULL을 이용해서 허용하지 않는다.
      2. NULL 함수는 집합 함수 등을 이용할 때 레코드 중에 NULL 값을 제외할 지 NULL 인 경우 처리해주는 함수가 있다.
        1. MySQL : IFNULL(컬럼명, 처리할 값) 
        2. SQL Server : ISNULL(컬럼명, 처리할 값)
        3. 오라클 : NVL(컬럼명, 처리할 값)
    17. Group by와 Having
      1. Group by는 집합함수를 같이 사용해서 그룹별 연산 시에 적용한다. 예를 들어 국가코드가 일치하는 값의 개수를 구할 때 사용한다.
      2. Having 은 그룹별 연산 시에 조건을 추가할 때 사용한다. 별다른 조건이 없다면 생략해서 사용되기도 한다.
      3. Group by, Having 사용방법 : SELECT 컬럼명, 집합함수(컬럼명) FROM 테이블 GROUP BY 컬러명 Having 조건절
    18. 서브쿼리
      1. 쿼리 내에 또 다른 쿼리 문이 있는 형태이다.
      2. 서브쿼리는 메인 쿼리에 포함되는 관계이다.
        1. () 를 사용해서 감싸서 구분하도록 한다.
        2. 서브쿼리에선 ORDER BY를 사용할 수 없다.
      3. 서브쿼리 종류
        1. 단일행(Single Row) 서브쿼리
          1. 결과가 레코드 하나로 된 서브쿼리이다.
          2. 일반 연산자(=, >, <, ...) 사용
          3. 사용 예) SELECT Count(*) FROM CITY WHERE CountryCode = (select code from country where name='South Korea'); 또는 SELECT NAME, POPULATION FROM CITY WHERE POPULATION > (select avg(Population) from city where countrycode='KOR') ORDER BY POPULATION DESC;
        2. 다중행(Multi Row) 서브쿼리
          1. 결과가 레코드 여러개로 된 서브쿼리이다.
          2. 다중행 연산자(IN, ALL, ANY, EXISTS) 사용
            1. ALL 은 여러 개의 레코드의 AND 효과를 가지며 가장 큰 값 보다 큰 값들을 나타낸다. (Population > ALL(select population ...))
            2. ANY 는 여러 개의 레코드의 OR 효과를 가지며 가장 작은 값보다 큰 값들을 나타낸다. (Population > ANY(select population ...))
            3. IN
              1. 결과 값 중에 존재여부를 나타내는 의미한다.
              2. 전체 레코드를 스캔해서 존재하면 TRUE, 존재하지 않으면 FALSE로 표시한다.
            4. EXIT
              1. 결과 값 중에 존재여부를 나타내는 의미로 존재여부만 확인하고 스캔하지 않아서 IN 보다 속도가 빠르다.
              2. 존재여부만 확인해서 존재하면 TRUE, 존재하지 않으면 FALSE로 표시한다.
        3. 다중 컬럼(Multi Column) 서브쿼리
          1. 결과가 컬럼 여러 개인 서브쿼리
          2. 단일 행이면서 다중 컬럼인 경우가 있고, 다중 행이면서 다중 컬럼인 경우가 있다.
    19. 집합연산
      1. 각 종 집합연산을 지원하며, 합집합(UNION), 교집합(INTERSECT), 차집합(MINUS), ...
      2. MySQL에선 합집합만 지원한다.
      3. 교집합과 차집합은 IN 등 별도의 연산으로 대체되어서 사용된다.
      4. 합집합에는 UNION과 UNION ALL 두 가지 형식으로 지원된다.
        1. UNION은 두 쿼리의 결과 값을 합쳐서 리턴하는 것으로 두 쿼리의 형식이 동일해야한다.
        2. UNION ALL은 중복을 허용하는 UNION으로 조건은 UNION 과 동일하게 두 쿼리의 형식이 동일해야한다.
  5. SQL(DDL)
    1. 스키마 정의
      1. DDL(Data Definition Language)로 데이터베이스와 테이블을 CRUD(Create, Retrieve, Update, Delete)하는 것을 의미하며, 테이블에 대한 정보는 메타데이터(Metadata)로 데이터 사전에 저장, 관리된다.
      2. 데이터베이스 생성방법 : CREATE DATABASE 데이터베이스 명;
      3. 테이블 생성방법 : CREATE TABLE 테이블 명(컬럼명 데이터타입(크기), ...);
    2. 자료형
      1. 데이터베이스를 표현하기 위해서 사용되는 데이터의 형태로 정수형, 실수형, 문자열, 시간 등으로 표현된다.
      2. 정수형(부호있음/부호없음)
        1. 부호가 있거나 또는 부호가 없는 정수 형태의 숫자를 의미한다.
        2. TINYINT(-128 ~ 127 / 0~ 255)
        3. INT(-21억 ~ 21억 / 0~ 43억)
        4. BIGINT(-9경 ~ 9경 / 0 ~ 18경)
      3. 실수형(길이, 소수점 이하 자리수)
        1. 소수점이 있는 형태의 숫자를 의미한다.
        2. FLOAT(size, d)
        3. DOUBLE(size, d)
        4. DECIMAL(size, d)
      4. 문자열
        1. 영문, 한글, 일본어 등 문자를 의미한다.
        2. CHAR 고정길이 문자열(최대 255자)
        3. VARCHAR 가변길이 문자열(최대 255자)
      5. TEXT문자열
        1. 문자열보다 긴 길이의 글자를 의미한다.
        2. TEXT(최대 65,535자)
        3. MEDIUMTEXT(최대 16,777,215자)
        4. LONGTEXT(최대 4,294,967,295자)
      6. BLOB(Binary Large Object)
        1. 바이너리 형태를 의미한다.
        2. BLOB(최대 65,535바이트)
        3. MEDIUMBLOB(죄대 16,777,215바이트)
        4. LARGEBLOB(최대 4,294,967,295바이트)
      7. 시간
        1. 시간을 나타내는 것을 의미한다.
        2. DATE(YYYY-MM-DD)
        3. TIME(HH:MI:SS)
        4. DATETIME(YYYY-MM-DD HH:MI:SS)
        5. TIMESTAMP(YYYY-MM-DD HH:MI:SS)
    3. 제약조건
      1. 데이터를 입력할 때의 제약 조건을 걸어서 해당되지 않는 데이터는 입력되지 않도록 한다.
      2. NOT NULL: 데이터가 NULL 값을 받아들이지 않는다.
      3. UNIQUE: 테이블에 동일한 값이 입력되어 있을 경우 받아들이지 않는다.
      4. PRIMARY KEY: 기본키 제약조건으로 기본키에 해당하는 값은 NOT NULL과 UNIQUE 제약조건을 동시에 만족해야한다.
      5. FOREIGN KEY: 외래키 제약조건으로 다른 테이블에서 기본키로 동작하고 있는 값을 공유하고 있다면, 참조 무결성을 유지해야한다는 제약 조건으로 다른 테이블에서 참조가 되고 있는 값은 같이 유지가 되거나 같이 없어져야한다.
      6. CHECK: 입력값을 확인한다. (예: Age >= 0), MySQL에서는 지원되지 않는다.
      7. DEFAULT: 컬럼 값이 입려되지 않으면 기본값을 입력한다.
      8. AUTO INCREMENT: 레코드가 증가하면 자동으로 증가되도록 한다.
    4. 중복정보 제거
      1. 테이블 간에 중복되는 정보가 있다면, 하나의 테이블에서 수정이 일어났을 때 해당하는 테이블을 모두 찾아서 수정이 필요하고, 유지보수에 어려움이 있어서 동일한 정보를 여러 테이블이 아닌 하나의 테이블에서 관리하도록 한다.
      2. 중복정보 제거를 위해서 정규형을 사용하여 중복을 제거한다.
    5. 정규형
      1. 정규형이란? 데이터베이스에서 중복을 제거하기 위해서 사용하는 테이블의 규칙이다.
      2. 제 1 정규형: 나눌 수 있을 만큼 쪼개도록 한다.
      3. 제 2 정규형: 테이블의 컬럼들이 기본키와 직접 연관되는 컬럼만으로 구성한다.
      4. 제 3 정규형: 컴럼들 간의 종속관계가 있으면 안된다.
      5. BCNF 정규형: 결정자이면서 후보키가 아닌 것을 제거한다.
      6. 제 4 정규형: 다치 종속 제거로 특정 A가 결정되었을 때, 여러 개의 결정될 수 있는 B가 존재하는 것을 의미하며, 간단한 예로 한 과목이 결정되었을 때, 그 과목을 다룰 수 있는 교재가 여러개인 것으로 생각할 수 있다.
      7. 제 5 정규형: 조인 종속성을 이용하는 것으로 모든 조인 종속이 후보키를 통해서만 만족하는 것을 의미한다.
      8. 관련 링크 : https://blog.naver.com/o_oloveo/220204342144
    6. 참조무결성
      1. 외래키에만 적용되는 규칙으로 외래키를 참조하면 원래 테이블에 해당 레코드 값이 반드시 존재해야한다.
      2. 만약 원래 레코드를 삭제하려면 참조하는 외래키 값을 먼저 NULL로 만들거나 지운 후에 원래 레코드를 삭제하도록 하는 순서가 발생한다.
      3. 외래키 참조 관계가 있을 경우 레코드 추가/삭제 시에 선후관계가 발생한다.
    7. 스키마 수정
      1. 이미 생성된 스키마에 대해서 수정할 경우 사용한다.
      2. 크게 테이블 컬럼 추가, 삭제, 수정과 제약 조건 추가, 삭제, 수정으로 나뉜다.
      3. 테이블 컬럼 추가, 삭제, 수정
        1. 테이블 컬럼 추가: ALTER TABLE 테이블 명 ADD 컬럼영 데이터 타입 
        2. 테이블 컬럼 삭제: ALTER TABLE 테이블 명 DROP COLUMN 컬럼영
        3. 테이블 컬럼 수정: ALTER TABLE 테이블 명 CHANGE 컬럼영 new_컬럼명 데이터타입(컬럼명 변경)
        4. 테이블 컬럼 테이터타입 수정: ALTER TABLE 테이블 명 MODIFY 컬럼영 데이터 타입(컬럼타입 변경)
      4. 제약조건 추가, 삭제, 수정
        1. 기본키 제약 조건 추가: ALTER TABLE 테이블 명 ADD PRIMARY KEY (컬럼명)
        2. 기본키 제약 조건 삭제: ALTER TABLE 테이블 명 DROP PRIMARY KEY
        3. UNIQUE 제약조건 추가: ALTER TABLE 테이블 명 ADD UNIQUE(컬럼명)
        4. UNIQUE 제약조건 제약 명 같이 추가: ALTER TABLE 테이블 명 ADD CONTRAINT 제약명 UNIQUE(컬럼명1, 컬럼명2)
        5. UNIQUE 제약조건 삭제: ALTER TABLE 테이블 명 DROP UNIQUE 제약 명
        6. 외래키 제약조건 추가: ALTER TABLE 테이블 명 ADD FOREIGN KEY (컬럼명) REFERENCES 원테이블명(원컬럼명)
        7. 외래키 제약조건 삭제: ALTER TABLE 테이블 명 DROP FOREIGN KEY 컬러명
        8. 테이블 명 수정: ALTER TABLE 테이블 명 RENAME new_테이블 명
        9. CHECK 제약조건 추가: ALTER TABLE 테이블 명 ADD CHECK 조건
        10. CHECK 제약조건 조건 명 같이 추가: ALTER TABLE 테이블 명 ADD CONSTRAINT 조건명 CHECK (조건절)
        11. CHECK 제약조건 삭제: ALTER TABLE 테이블 명 DROP CHECK 조건 명
        12. DEFAULE 제약조건 추가: ALTER TABLE 테이블 명 ALTER 컬럼명 SET DEFAULT 기본 값
        13. DEFAULT 제약조건 삭제: ALTER TABLE 테이블 명 ALTER 컬럼명 DROP DEFAULT
    8. 스키마 삭제
      1. 생선된 스키마에 대해서 삭제할 경우 사용한다.
      2. 크게 데이터베이스 삭제와 테이블 삭제가 있다.
      3. 데이터베이스(DB) 삭제
        1. DROP DATABASE 데이터베이스 명: 데이터베이스 삭제
      4. 테이블 삭제
        1. DROP TABLE 테이블 명: 테이블 삭제, 내용과 테이블 전체 삭제
        2. DELETE * FROM 테이블 명: 레코드를 하나씩 지우지만, 테이블 스키마는 유지된다.
        3. TRUNCATE TABLE 테이블 명: 테이블 내용만 지움, 테이블 스키마는 유지, 전용 명령어이다.
  6. SQL(DCL)
    1. 권한 설정
      1. DCL(Data Control Language)
        1. 권할 및 역할을 설정하는 언어이다.
        2. 등록된 사용자에게 특정 테이블에서 특정 쿼리만 사용할 수 있도록 권한을 설정한다. 즉 특정 테이블에 대한 CRUD(Create/Retrieve/Update/Delete) 권한 설정을 의미한다.
          1. 권한 부여(Grant) / 권한회수(REVOKE)로 나눈다.
          2. 주로 DBA(DataBase Administrator) 가 설정한다.
        3. 예제
          1. 특정 사용자에게 모든 권한을 주는 예제 : grant all on *.* to 특정 사용자 명@localhost identified by '비밀번호'
          2. 특정 사용자에게 World DB에 대한 검색/추가 권한을 주는 예제: grant select, insert on world.* to 특정 사용자 명@localhost identified by '비밀번호'
          3. 특정 사용자에게 World DB의 city 테이블의 도시명의 업데이트 권한만 주는 예제: grant update(Name) on world.city to 특정 사용자 명@localhost identified by '비밀번호'
    2. 역할 설정
      1. 개별 테이블에 대한 CRUD 권한을 사용자별로 설정하는 설정되어 경우의 수는 테이블 수 X 사용자 수의 조합으로 생긴다.
      2. 조합의 수가 많아지기 때문에 역할 별로 권한 설정하고 사용자에게 역할을 부여한다.
      3. 사용자가 여러 개의 역할을 가지는 것이 가능하다.
      4. MySQL에는 ROLE 관련 명령이 지원 안된다.
      5. 사용방법
        1. 역할 생성: CREATE ROLE 역할명;
        2. 역할에 대한 권한 설정: GRANT CRUD ON 테이블명 TO 역할명;
        3. 사용자에게 역할 부여: GRANT 역할 TO 사용자명;
    3. MySQL 원격접속 설정
      1. 권한 설정 및 역할 설정을 통해서 MySQL을 원격 접속권한 설정을 주어서 서버에 접근 가능하도록 설정할 수 있다.
      2. 설정 방법은 아래 링크를 참고한다: https://pjt3591oo.github.io/blog/database/2017/05/03/abou_mysql_remote_connect.html
  7. SQL Advanced
    1. INDEX
      1. 인덱스란? 검색을 빠르게 도와주는 자료구조를 의미하며, 주로 B 트리 계열이다.
      2. 기본키는 자동으로 인덱스 설정된다.
      3. 인덱스 ON/OFF를 통해서 검색속도 차이를 체감하며 보통 100만, 1000만 이상의 대용량 데이터 검색을 할 때 영향을 많이 받는다.
      4. 조인 시에도 영향을 준다.
      5. 인덱스 추가 방법
        1. CREATE INDEX 인덱스 명 ON 테이블 명(컬럼명)
        2. CREATE INDEX 인덱스 명 ON 테이블 명(컬럼명1, 컬럼명2, ...)
        3. CREATE UNIQUE INDEX 인덱스 명 ON 테이블 명(컬럼명)
      6. 인덱스 삭제 방법
        1. ALTER TABLE 테이블 명 DROP INDEX 인덱스 명
      7. 인덱스명 지정방법: 테이블_컬럼명_INDEX
    2. 메타데이터(Meta Data)
      1. 개념 : 데이터를 위한 데이터로 DB, 테이블의 스키마에 대한 정보를 저장하는 테이블이다.
      2. 종류
        1. 데이터 사전(Data Dictionary) : Information_schema 데이터베이스에 저장
          1. 데이터베이스의 정보를 저장한다.
          2. 시스템 카탈로그(System Catalog)라고도 한다.
          3. 일반적으로 읽기 전용 정보이다.(Read-only)
        2. 데이터 디렉토리(Data Directory)
          1. DBMS의 모든 데이터가 저장된 디렉토리(폴더)이다.
          2. DB를 저장하거나 로그를 저장한다.
        3. 오라클, MSSQL 모두 동일하게 Information_schema 데이터베이스를 가지고 있다.
    3. Character Set
      1. 데이터베이스의 문자 인코딩 정보로 메타 데이터의 일종이다.
      2. 문자열인 VARCHAR, CHAR의 값을 저장할 때 사용하는 기본정보이다.
      3. DB/테이블 별로 별도 설정이 가능하다.
    4. Collation
      1. 데이터를 검색하거나 정렬할 때 사용하는 정보이다.
      2. 정렬 시에 대소문자 구분여부도 결정한다.
        1. ci가 붙으면 대소문자 구분하지 않고, ci가 붙이 않으면 대소문자를 구분한다.
        2. 예) utf8_general_ci 는 utf8로 된 일반문자의 대소문자를 구분하지 않는다.
      3. 대표적인 문자셋인 UTF-8 Collation 지정방법
        1. utf8_general_ci
        2. utf8_unicode_ci
    5. 스토리지 엔진
      1. 개념 : 데이터베이스엔진이라고도 하며, DBMS가 데이터를 CRUD할 때 사용하는 기본 구성요소를 의미한다.
      2. 대표적으로 MyISAM, InnoDB, Aria, Falcon 등이 있다. (관련링크 : 데이터베이스_엔진)
        1. InnoDB - 트랜젝션 지원, 업데이트에 용이, 줄단위로 락, 복구가 용이, 동시처리서능이 높아 대부분 많이 사용
        2. MyISAM - 상대적으로 높은 성능으로 속도가 빠름, 읽기에 용이, 테이블단위 락
    6. 데이터베이스 백업, 복원
      1. 데이터베이스 백업
        1. 특정 시점에서 데이터베이스 상태를 별도의 파일로 저장하는 방법이다.
        2. 백업 방법
          1. 전체 데이터베이스 백업
            1. mysqldump -u아이디 -p --all-databases > 덤프파일명.sql
            2. 예) mysqldump -uroot -p --all-databases > dump.sql
          2. 특정 데이터베이스 백업
            1. mysqldump -u아이디 -p --databases DB명 > 덤프파일명.sql
            2. 예) mysqldump -uroot -p --databases world> dump.sql
          3. 특정 테이블 백업(데이터 포함)
            1. mysqldump -u아이디 -p DB명 테이블명 > 덤프파일명.sql
            2. 예) mysqldump -uroot -p world city> dump.sql
          4. 스키마만 백업
            1. mysqldump -u아이디 -p --no-data DB명 테이블명 > 덤프파일명.sql
            2. 예) mysqldump -uroot -p --no-data world city> dump.sql
          5. 데이터만 백업
            1. mysqldump -u아이디 -p --no-create-info DB명 테이블명 > 덤프파일명.sql
            2. 예) mysqldump -uroot -p --no-create-info world city> dump.sql
      2. 데이터베이스 복원
        1. 특정 시점에서 저장한 데이터베이스 파일을 가져와서 사용하는 방법이다.
        2. 복원의 경우 백업을 어떻게 했느냐에 따라서 데이터가 복원이 될 수도 있고, 스키마만 복원이 될 수 있다.
        3. 복원 방법
          1. 전체 데이터베이스 복원
            1. mysql -u아이디 -p < 파일명
            2. 예) mysql -uroot -p < dump.sql
          2. 특정 데이터베이스 복원
            1. mysql -u아이디 -p DB명 < 파일명
            2. 예) mysql -uroot -p world < dump.sql
          3. 특정 테이블 복원
            1. mysql -u아이디 -p DB명 테이블명 < 파일명
            2. 예) mysql -uroot -p world city < dump.sql
    7. 데이터베이스 로그
      1. 로그란? 통상 로그는 현재 프로그램이 어떻게 동작하고 있는지에 대한 정보를 담고 있으며, 데이터베이스에서는 운영상황 즉, 데이터베이스, 테이블의 조회, 추가, 수정 등에 대한 정보들을 저장한다.
      2. 로그의 종류
        1. 에러로그(Error Log) : Query 에러에 관련된 메시지를 저장한다.
        2. 일반로그(General Log) : 전체 쿼리에 대한 메시지를 저장한다.
        3. 슬로우 쿼리 로그(Slow Query Log) : 설정된 시간 이상을 소요한 쿼리에 대해서 저장한다.
        4. 이진 로그(Binary Log)/릴레이 로그(Relay Log) : 쿼리를 수행하면서 쌓는 로그로 복제에서 사용하고, 시점 복구등을 수행하는 역활을 한다.
    8. 데이터 파티셔닝/샤딩
      1. 데이터 파티셔닝(Partitioning)
        1. 데이터들을 저장한 DBMS 레벨을 분할한다. ex) P1, P2, ...
        2. DBMS 내부에서 분할이 발생해 사용자는 사용하는데 변화를 느끼지 못한다.
        3. 제약사항
          1. 테이블단위 연산이 힘들어진다.
          2. 외래키(FK)의 효용문제
        4. 이점
          1. 데이터 전체 검색 시 필요한 부분만 탐색해 성능 증가
          2. 전체 데이터를 손실할 가능성이 줄어듦
          3. 파티션별 백업/복구 가능
          4. 파티션 단위로 I/O 분산가능으로 업데이트 성능 향상
        5. 방식
          1. 파티션을 나눌 기준을 정해서 나누는 범위(Range)
          2. 해시함수를 파티션별로 크기를 비슷하게 나누는 해시(Hash)
          3. 특정한 컬럼을 기준으로 하는 리스트(List)
          4. 1~3번을 두 가지 정도로 합치는 컴포지트(Composite)
      2. 샤딩(Sharding)
        1. 데이터들을 저장한 DBMS 외부에서 분할 / 응용레벨에서 구별해야 한다.
        2. DBMS 외부에서 분할이 발생해 사용자가 그에 맞게 대응이 필요하다.
    9. 데이터베이스 복제
      1. 정의 DBMS의 내용을 마스터/슬레이브 관계를 설정하여 동일한 DBMS를 여러개 생성한다.
      2. 마스터에서는 추가, 수정, 삭제가 이루어진다.
      3. 슬레이브에서는 검색만 이루어진다.
      4. 데이터베이스 복제로 인해서 검색 성능이 향상된다.
      5. 복제 방법
        1. 로그기반 복제(Binary Log)
          1. Statement Based : SQL문장복제, SQL에 따라 결과가 달라지질 수 있다.
          2. Row Based : SQL에 따라 변경된 라인만 기록하는 바식으로 데이터가 많이 변경된 경우 데이터가 커진다.
          3. Mixed 위 두 방식을 혼합한다.
    10. Full Text Search
      1. 컬럼 내용 전체를 단순 문자열로 검색하는 방법으로 LIKE 검색을 여러번 사용할 경우, DB에 부담을 주기 때문에 생겨난 기능
      2. MySQL에서 Full Text Search 방식
        1. 자연어 검색
          1. 형식 : where match(컬럼명) against('검색어 또는 검색문장')
          2. 검색의 정확도는 as score로 확인 가능
          3. 결과는 검색 정확도에 따라 내림차순으로 정렬
        2. 불린 검색
          1. 형식 : where match(컬럼명) against('검색어*' -제외단어 in boolean mode)
          2. 검색의 정확도로 정렬하는 기능은 없고, 연산자를 이용한 구문 검색 가능
          3. 연산자
            1. + : 필수 단어
            2. - : 제외 단어
            3. * : 부분 단어
    11. Bulk Insert
      1. 테이블에 Insert를 여러 번 할 수 있도록 하는 기능
      2. INSERT 문을 실행하는 경우 인덱스가 있는 테이블은 한 번 실행할 때마다 인덱스 작업을 해야한다.
      3. Bulk Insert를 사용하면 INSERT 문을 여러 개 입력한 후에 마지막에 인덱스 작업을 할 수 있게 가능하다.
      4. 인덱스 정지/실행 명령어
        1. 인덱스 정지 : ALTER TABLE  테이블명 DISABLE KEYS;
        2. 인덱스 재실행 : ALTER TABLE  테이블명 ENABLE KEYS;
      5. 방식
        1. 기존 INSERT 문에 VALUES(...) VALUES(...) ... VALUES(...)를 여러개 입력하는 방식
        2. 파일로 덤프하는 방식
          1. SQL 문을 이용한 방법 : mysqldump -u아이디 -p DB명 테이블명 > 덤프파일명.sql
          2. CSV(Comma Seperated Value) 파일을 이용한 방법
            1. 아래 명령어를 차례로 입력
            2. LOAD DATA INFILE '파일 경로' INTO TABLE 테이블명 FIELDS TERMINATED BY ‘\t’ ENCLOSED BY ‘”’ ESCAPED BY ‘\\’ LINES STARTING BY ‘’ TERMINATED BY ‘\n’
            3. CSV 파일 생성방법 : SELECT * FROM 테이블명 INTO  OUTFILE '파일 경로'
        3. 주의점
          1. CSV 파일을 이용하는 방법은 보안 문제로 인해서 특정 디렉토리에서만 사용하게 제한한다. (secure-file-priv=path 옵션)
          2. Bulk Insert 사용 시 반드시 인덱스 정지하고, 명령어를 입력하고 난 후에 인덱스를 재실행하도록 한다.