printf("ho_tari\n");

ep.25 DBMS 연동 프로그램 구축 본문

두산 로보틱스 부트캠프 ROKEY/DevOps 교육

ep.25 DBMS 연동 프로그램 구축

호타리 2024. 8. 9. 14:06

2024.8.9

 

MySQL에서 지원하는 데이터 형식의 종류
◦ 문자 데이터 형식

◦ 날짜와 시간 데이터 형식

◦ 기타 데이터 형식

◦ LONGTEXT, LONGBLOB
⚫ LOB(Large Object, 대량의 데이터)을 저장하기 위해 LONGTEXT, LONGBLOB 데이터 형식 지원
⚫ 지원되는 데이터 크기는 약 4GB의 파일을 하나의 데이터로 저장 가능

변수의 사용
◦ Workbench를 재시작할 때까지는 계속 유지, Workbench를 닫았다가 재시작하면 소멸

데이터 형식과 형 변환
◦ 데이터 형식 변환 함수
⚫ CAST( ), CONVERT( ) 함수를 가장 일반적으로 사용
⚫ 데이터 형식 중에서 가능한 것은 BINARY, CHAR, DATE, DATETIME, DECIMAL, JSON, SIGNED INTEGER, TIME, UNSIGNED INTEGER

◦ 암시적인 형 변환
⚫ CAST( )나 CONVERT( ) 함수를 사용하지 않고 형이 변환되는 것

MySQL 내장 함수
◦ 내장 함수
⚫ 흐름 함수, 문자열 함수, 수학 함수, 날짜/시간 함수, 전체 텍스트 검색 함수, 형 변환 함수, XML 함수, 비트 함수, 보안/압축 함 수, 정보 함수, 공간 분석 함수, 기타 함수 등

◦ 제어 흐름 함수
⚫ 프로그램의 흐름 제어
⚫ IF (수식, 참, 거짓)
⚫ 수식이 참 또는 거짓인지 결과에 따라서 2중 분기

⚫ IFNULL(수식1, 수식2)
⚫ 수식1이 NULL이 아니면 수식1이 반환되고 수식1이 NULL이면 수식2가 반환

⚫ NULLIF(수식1, 수식2)
⚫ 수식1과 수식2가 같으면 NULL을 반환, 다르면 수식1을 반환
⚫ CASE ~ WHEN ~ ELSE ~ END
⚫ CASE는 내장 함수는 아니며 연산자(Operator)로 분류
⚫ 다중 분기에 사용되므로 내장함수와 함께 알아두자

◦ 문자열 함수
⚫ 문자열 조작, 활용도 높음
⚫ ASCII (아스키 코드),
⚫ 문자의 아스키 코드값 반환
⚫ CHAR(숫자)
⚫ 숫자의 아스키 코드값에 해당하는 문자 반환

⚫ BIT_LENGTH(문자열), CHAR_LENGTH(문자열), LENGTH(문자열)
⚫ 할당된 Bit 크기 또는 문자 크기 반환
⚫ CHAR_LENGTH( )는 문자의 개수 반환
⚫ LENGTH( )는 할당된 Byte 수 반환

⚫ CONCAT(문자열1, 문자열2,…), CONCAT_WS(구분자, 문자열1, 문자열2,…)
⚫ CONCAT( ) : 문자열을 이어줌
⚫ CONCAT_WS( ) : 구분자와 함께 문자열을 이어주는 역할

⚫ ELT(위치, 문자열1, 문자열2, …), FIELD(찾을 문자열, 문자열1, 문자열2, …), FIND_IN_SET (찾을 문자열, 문자열 리스트), INSTR(기준 문자열, 부분 문자열), LOCATE(부분 문자열, 기준 문자열)
⚫ ELT( ) : 위치 번째에 해당하는 문자열 반환
⚫ FIELD( ) : 찾을 문자열의 위치를 찾아 반환, 없으면 0
⚫ FIND_IN_SET( ) : 찾을 문자열을 문자열 리스트에서 찾아 위치 반환
⚫ 문자열 리스트는 콤마(,)로 구분되어 있고 공백이 없어야 함
⚫ INSTR( )는 기준 문자열에서 부분 문자열 찾아 그 시작 위치 반환
⚫ LOCATE( )는 INSTR( )와 동일하지만 파라미터의 순서가 반대

문자열 함수
⚫ FORMAT(숫자, 소수점 자릿수)
⚫ 숫자를 소수점 아래 자릿수까지 표현, 1,000단위마다 콤마 표시해 줌
⚫ BIN(숫자), HEX(숫자), OCT(숫자)
⚫ 2진수, 16진수, 8진수의 값을 반환
⚫ INSERT(기준 문자열, 위치, 길이, 삽입할 문자열)
⚫ 기준 문자열의 위치부터 길이만큼 지우고 삽입할 문자열 끼워 넣음

⚫ LEFT(문자열, 길이), RIGHT(문자열, 길이)
⚫ 왼쪽 또는 오른쪽에서 문자열의 길이만큼 반환

⚫ UPPER(문자열), LOWER(문자열)
⚫ 소문자를 대문자로, 대문자를 소문자로 변경
⚫ LPAD(문자열, 길이, 채울 문자열), RPAD(문자열, 길이, 채울 문자열)
⚫ 문자열을 길이만큼 늘린 후에 빈 곳을 채울 문자열로 채움

⚫ LTRIM(문자열), RTRIM(문자열)
⚫ 문자열의 왼쪽/오른쪽 공백을 제거, 중간의 공백은 제거되지 않음
⚫ TRIM(문자열), TRIM(방향 자를_문자열 FROM 문자열)
⚫ TRIM(문자열)은 문자열의 앞뒤 공백을 모두 없앰
⚫ TRIM(방향 자를_문자열 FROM 문자열) 에서 방향은 LEADING(앞), BOTH(양쪽), TRAILING(뒤) 으로 표시

⚫ REPEAT(문자열, 횟수)
⚫ 문자열을 횟수만큼 반복
⚫ REPLACE(문자열, 원래 문자열, 바꿀 문자열)
⚫ 문자열에서 원래 문자열을 찾아서 바꿀 문자열로 바꿈

⚫ REVERSE(문자열)
⚫ 문자열의 순서를 거꾸로 바꿈

⚫ SPACE(길이)
⚫ 길이만큼의 공백을 반환
⚫ SUBSTRING(문자열, 시작위치, 길이) 또는 SUBSTRING(문자열 FROM 시작위치 FOR 길이)
⚫ 시작위치부터 길이만큼 문자를 반환, 길이가 생략되면 문자열의 끝까지 반환

⚫ SUBSTRING_INDEX(문자열, 구분자, 횟수)
⚫ 문자열에서 구분자가 왼쪽부터 횟수 번째까지 나오면 그 이후의 오른쪽은 버림
⚫ 횟수가 음수면 오른쪽부터 세고 왼쪽을 버림

◦ 수학 함수
⚫ ABS(숫자)
⚫ 숫자의 절댓값 계산
⚫ ACOS(숫자), ASIN(숫자), ATAN(숫자), ATAN2(숫자1, 숫자2), SIN(숫자), COS(숫자), TAN(숫자)
⚫ 삼각 함수와 관련된 함수 제공
⚫ CEILING(숫자), FLOOR(숫자), ROUND(숫자)
⚫ 올림, 내림, 반올림 계산
⚫ CONV(숫자, 원래 진수, 변환할 진수)
⚫ 숫자를 원래 진수에서 변환할 진수로 계산
⚫ DEGREES(숫자), RADIANS(숫자), PI ( )
⚫ 라디안 값을 각도값으로, 각도값을 라디안 값으로 변환, PI( )는 3.141592 반환
⚫ EXP(X), LN(숫자), LOG(숫자), LOG(밑수, 숫자), LOG2(숫자), LOG10(숫자)
⚫ 지수, 로그와 관련된 함수 제공

⚫ MOD(숫자1, 숫자2) 또는 숫자1 % 숫자2 또는 숫자1 MOD 숫자2
⚫ 숫자1을 숫자2로 나눈 나머지 값을 구함
⚫ POW(숫자1, 숫자2), SQRT(숫자)
⚫ 거듭제곱값 및 제곱근을 구함
⚫ RAND( )
⚫ RAND( )는 0 이상 1 미만의 실수 구함
⚫ ‘m<= 임의의 정수 < n’를 구하고 싶다면 FLOOR(m + (RAND( ) * (n-m) ) 사용
⚫ SIGN(숫자)
⚫ 숫자가 양수, 0, 음수인지 판별, 결과는 1, 0, -1 셋 중에 하나 반환
⚫ TRUNCATE(숫자, 정수)
⚫ 숫자를 소수점을 기준으로 정수 위치까지 구하고 나머지는 버림

◦ 날짜 및 시간 함수

⚫ ADDDATE(날짜, 차이), SUBDATE(날짜, 차이)
⚫ 날짜를 기준으로 차이를 더하거나 뺀 날짜 구함
⚫ ADDTIME(날짜/시간, 시간), SUBTIME(날짜/시간, 시간)
⚫ 날짜/시간을 기준으로 시간을 더하거나 뺀 결과를 구함
⚫ CURDATE( ), CURTIME( ), NOW( ), SYSDATE( )
⚫ CURDATE( ) : 현재 연-월-일
⚫ CURTIME( ) : 현재 시 : 분 : 초
⚫ NOW( ), SYSDATE( ) : 현재 ‘연-월-일 시 : 분 : 초
⚫ YEAR(날짜), MONTH(날짜), DAY(날짜), HOUR(시간), MINUTE(시간), SECOND(시간), MICROSECOND(시간)
⚫ 날짜 또는 시간에서 연, 월, 일, 시, 분, 초, 밀리초 구함

⚫ DATE( ), TIME( )
⚫ DATETIME 형식에서 연-월-일 및 시 : 분 : 초만 추출
⚫ DATEDIFF(날짜1, 날짜2), TIMEDIFF(날짜1 또는 시간1, 날짜1 또는 시간2)
⚫ DATEDIFF( )는 날짜1-날짜2의 일수를 결과로 구함
⚫ DAYOFWEEK(날짜), MONTHNAME( ), DAYOFYEAR(날짜)
⚫ 요일(1:일, 2:월~7:토) 및 1년 중 몇 번째 날짜인지 구함
⚫ LAST_DAY(날짜)
⚫ 주어진 날짜의 마지막 날짜를 구함

⚫ MAKEDATE(연도, 정수)
⚫ 연도에서 정수만큼 지난 날짜 구함
⚫ MAKETIME(시, 분, 초)
⚫ 시, 분, 초를 이용해서 ‘시 : 분 : 초’의 TIME 형식 만듦
⚫ PERIOD_ADD(연월, 개월수), PERIOD_DIFF(연월1, 연월2)
⚫ PERIOD_ADD( )는 연월에서 개월만큼의 개월이 지난 연월 구함
⚫ PERIOD_DIFF( )는 연월1-연월2의 개월수 구함
⚫ QUARTER(날짜)
⚫ 날짜가 4분기 중에서 몇 분기인지를 구함
⚫ TIME_TO_SEC(시간)
⚫ 시간을 초 단위로 구함

◦ 피벗(Pivot) 이란?
⚫ 한 열에 포함된 여러 값 출력, 이를 여러 열로 변환하여 테이블 반환식 회전, 필요하면 집계까지 수행

JSON 데이터
◦ JSON (JavaScript Object Notation)이란?
⚫ 웹과 모바일 응용프로그램 등과 데이터 교환하기 위한 개방형 표준 포맷
⚫ 속성(Key) 과 값(Value)으로 쌍을 이루며 구성
⚫ JavaScript 언어에서 파생
⚫ 특정한 프로그래밍 언어에 종속되어 있지 않은 독립적인 데이터 포맷
⚫ 포맷이 단순하고 공개되어 있기에 거의 대부분의 프로그래밍 언어에서 쉽게 읽거나 쓸 수 있도록 코딩 가능
⚫ MySQL 5.7.8부터 지원
⚫ MySQL 8.0에서는 인라인 패스라 불리는 → 연산자 및 JSON_ARRAYAGG(), JSON_OBJECTAGG(), JSON_PRETTY(), JSON_STORAGE_SIZE(), JSON_STORAGE_FREE(), JSON_MERGE_PATCH()등의 함수가 추가됨

조인(Join)
◦ 조인
⚫ 두 개 이상의 테이블을 서로 묶어서 하나의 결과 집합으로 만들어 내는 것
⚫ 종류 : INNER JOIN, OUTER JOIN, CROSS JOIN, SELF JOIN
◦ 데이터베이스의 테이블
⚫ 중복과 공간 낭비를 피하고 데이터의 무결성을 위해서 여러 개의 테이블로 분리하여 저장
⚫ 분리된 테이블들은 서로 관계(Relation)를 가짐
⚫ 1대 다 관계 보편적

INNER JOIN(내부 조인)
◦ 조인 중에서 가장 많이 사용되는 조인
⚫ 대개의 업무에서 조인은 INNER JOIN 사용
⚫ 일반적으로 JOIN이라고 얘기하는 것이 이 INNER JOIN 지칭

⚫ JOIN만 써도 INNER JOIN으로 인식함

OUTER JOIN(외부 조인)
◦ 조인의 조건에 만족되지 않는 행까지도 포함시키는 것

◦ LEFT OUTER JOIN
⚫ 왼쪽 테이블의 것은 모두 출력되어야 한다로 이해
⚫ 줄여서 LEFT JOIN으로 쓸수있음
◦ RIGHT OUTER JOIN
⚫ 오른쪽 테이블의 것은 모두 출력되어야 한다로 이해

CROSS JOIN(상호 조인)
◦ 한쪽 테이블의 모든 행들과 다른 쪽 테이블의 모든 행을 조인시키는 기능
◦ CROSS JOIN의 결과 개수 = 두 테이블 개수를 곱한 개수

◦ 테스트로 사용할 많은 용량의 데이터를 생성할 때 주로 사용
◦ ON 구문을 사용할 수 없음
◦ 대량의 데이터를 생성하면 시스템이 다운되거나 디스크 용량이 모두 찰 수 있어 COUNT(*) 함수로 개수만 카운트

SELF JOIN(자체 조인)
◦ 자기 자신과 자기 자신이 조인한다는 의미

UNION / UNION ALL / NOT IN / IN
◦ 두 쿼리의 결과를 행으로 합치는 것

IF…ELSE
◦ 조건에 따라 분기
⚫ 참 / 거짓 두가지만 있기에 2중 분기
◦ 한 문장 이상 처리되어야 할때 BEGIN.. END로 묶어주기

⚫ 부울 표현식 부분이 참이면 SQL문장들1 수행 / 거짓이면 SQL문장들2 수행

CASE
◦ 조건에 따라 분기
⚫ 다중 분기
⚫ 조건에 맞는 WHEN이 여러 개더라도 먼저 조건이 만족하는 WHEN 처리됨
⚫ SELECT문에서 많이 사용됨
⚫ 점수로 성적을 판단하는 경우처럼 여러 단계로 분기 될 때 사용

WHILE과 ITERATE/LEAVE
◦ WHILE문
⚫ 다른 프로그래밍 언어의 WHILE과 동일한 개념
⚫ 해당 부울식이 참인 동안에 계속 반복되는 반복문

⚫ ITERATE문을 만나면 WHILE문으로 이동해서 비교를 다시함
⚫ 다른 프로그래밍 언어의 Continue와 동일한 개념
⚫ LEAVE문을 만나면 WHILE문을 빠져 나옴
⚫ 다른 프로그래밍 언어의 Break와 동일한 개념

오류 처리

⚫ 액션
⚫ 오류 발생 시에 행동 정의
⚫ CONTINUE와 EXIT 둘 중 하나 사용, CONTINUE가 나오면 제일 뒤의 ‘처리할_문장’ 부분이 처리
⚫ 오류조건 : 어떤 오류를 처리할 것인지를 지정
⚫ MySQL의 오류 코드 숫자가 오거나 SQLSTATE‘상태코드’, SQLEXCEPTION, SQLWARNING, NOT FOUND등이 올 수 있음
⚫ 처리할_문장
⚫ 처리할 문장이 여러 개일 경우에는 BEGIN…END로 묶어줌

동적 SQL
◦ PREPARE문
⚫ SQL문을 실행하지는 않고 미리 준비만 해놓음
◦ EXECUTE문
⚫ 준비한 쿼리문 실행
⚫ 실행 후에는 DEALLOCATE PREFARE로 문장 해제

테이블 만들기
◦ SQL로 테이블 생성
⚫ 열린 창을 모두 닫고 쿼리 창을 연다.
⚫ 앞의 실습에서 사용한 tabledb을 삭제하고 다시 생성
⚫ DROP DATABASE tabledb;
⚫ CREATE DATABASE tabledb;

⚫ usertbl 생성

⚫ buytbl 생성

제약 조건
◦ 제약 조건(Constraint) 이란?
⚫ 데이터의 무결성을 지키기 위한 제한된 조건 의미
⚫ 특정 데이터를 입력 시 어떠한 조건을 만족했을 때에 입력되도록 제약

⚫ 데이터 무결성을 위한 제약조건
⚫ PRIMARY KEY 제약 조건
⚫ FOREIGN KEY 제약 조건
⚫ UNIQUE 제약 조건
⚫ CHECK 제약 조건(MySQL 8.0.16부터 지원)
⚫ DEFAULT 정의
⚫ NULL 값 허용

데이터 무결성을 위한 제약 조건
◦ 기본 키(Primary Key) 제약 조건
⚫ 기본 키(Primary Key) 란?
⚫ 테이블에 존재하는 많은 행의 데이터를 구분할 수 있는 식별자
⚫ 중복이나 NULL값이 입력될 수 없음

⚫ 기본 키로 생성한 것은 자동으로 클러스터형 인덱스 생성
⚫ 테이블에서는 기본 키를 하나 이상 열에 설정 가능

◦ 외래 키(Foreign Key) 제약 조건
⚫ 두 테이블 사이의 관계 선언하여 데이터의 무결성 보장해주는 역할
⚫ 외래 키 관계를 설정하면 하나의 테이블이 다른 테이블에 의존
⚫ 외래 키 테이블이 참조하는 기준 테이블의 열은 반드시 Primary Key이거나 Unique 제약 조건이 설정되어 있어야 함
⚫ 외래 키의 옵션 중 ON DELETE CASCADE 또는 ON UPDATE CASCADE
⚫ 기준 테이블의 데이터가 변경되었을 때 외래 키 테이블도 자동으로 적용되도록 설정

◦ UNIQUE 제약 조건
⚫ ‘중복되지 않는 유일한 값’을 입력해야 하는 조건
⚫ PRIMARY KEY와 비슷하나 UNIQUE는 NULL 값 허용
⚫ NULL은 여러 개가 입력되어도 상관 없음

◦ CHECK 제약 조건
⚫ 입력되는 데이터를 점검하는 기능

⚫ ALTER TABLE문으로 제약 조건 추가 가능

◦ DEFAULT 정의
⚫ 값 입력하지 않았을 때 자동으로 입력되는 기본 값 정의하는 방법
⚫ ALTER TABLE 사용 시에 열에 DEFAULT를 지정하기 위해서 ALTER COLUMN문 사용

◦ Null 값 허용
⚫ NULL 값을 허용하려면 NULL을, 허용하지 않으려면 NOT NULL을 사용
⚫ PRIMARY KEY가 설정된 열에는 생략하면 자동으로 NOT NULL
⚫ NULL 값은 ‘아무 것도 없다’라는 의미, 공백(‘ ‘) 이나 0과 다름

테이블 압축
◦ 압축 기능은 대용량 테이블의 공간 절약하는 효과
◦ MySQL 5.0부터 자체적으로 테이블 압축 기능 제공
◦ MySQL 8.0에서 내부적인 기능이 더욱 강화
◦ MySQL이 허용하는 최대 용량의 데이터도 오류 없이 압축 가능

임시 테이블
◦ 임시로 잠깐 사용되는 테이블

◦ 세션(Session) 내에서만 존재
⚫ 세션이 닫히면 자동 삭제
◦ 생성한 클라이언트에서만 접근 가능
⚫ 다른 클라이언트에는 접근 불가
◦ 임시 테이블 삭제 시점
⚫ 사용자가 DROP TABLE로 직접 삭제
⚫ Workbench를 종료하거나 mysql 클라이언트를 종료하면 삭제됨
⚫ MySQL 서비스가 재시작되면 삭제됨

테이블 삭제

◦ 외래 키 제약 조건의 기준 테이블은 삭제할 수가 없음
⚫ 먼저 외래 키가 생성된 외래 키 테이블을 삭제해야 함
⚫ 구매 테이블이 존재하는데 회원 테이블을 삭제 할 수 없음, 구매 테이블 삭제가 선행 되어야 함
◦ 동시에 여러 테이블 삭제도 가능
⚫ DROP TABLE 테이블1, 테이블2, 테이블3;

테이블 수정
◦ ALTER TABLE문 사용
⚫ 테이블에 무엇인가 추가/변경/수정/삭제 모두 ALTER TABLE문 사용
◦ 열의 추가
⚫ 기본적으로 가장 뒤에 추가
⚫ 순서를 지정하려면 제일 뒤에 ‘FIRST’ 또는 ‘ALTER 열 이름’ 지정

뷰의 개념
◦ 일반 사용자 입장에서 테이블과 동일하게 사용하는 개체
⚫ 뷰를 생성한 후에는 테이블처럼 접근 가능하여 동일한 결과 얻을수 있음

뷰의 장점
◦ 보안에 도움
⚫ 사용자가 중요한 정보에 바로 접근하지 못함
◦ 복잡한 쿼리 단순화
⚫ 긴 쿼리를 뷰로 작성, 뷰를 테이블처럼 사용 가능

테이블스페이스의 개념
◦ 물리적인 공간을 뜻함
◦ 데이터베이스는 논리적 공간
◦ 테이블스페이스를 지정하지 않은 경우

◦ 시스템 변수 innodb_data_file_path에 관련 내용 저장됨

성능 향상을 위한 테이블스페이스 추가
◦ 소용량의 데이트를 사용하는 경우에는 테이블스페이스 고려하지 않아도 되나 대용량의 데이터를 운영할 경우에는 성능 향상을 위해 테이블스페이스의 분리를 적극 고려

인덱스(Index)란?
◦ 책의 <찾아보기>의 개념과 비슷
◦ 데이터를 좀 더 빠르게 찾을 수 있도록 해주는 도구

인덱스의 장단점
◦ 장점
⚫ 검색 속도가 무척 빨라질 수 있음 (항상 그런 것은 아님)
⚫ 쿼리의 부하가 줄어들어 시스템 전체의 성능 향상
◦ 단점
⚫ 인덱스가 데이터베이스 공간을 차지해서 추가적인 공간 필요
⚫ 대략 데이터베이스 크기의 10% 정도의 추가 공간 필요
⚫ 처음 인덱스 생성하는데 시간 소요
⚫ 데이터의 변경 작업 (Insert, Update, Delete)이 자주 일어나는 경우 성능이 나빠질 수도 있음

인덱스의 종류
◦ 클러스터형 인덱스 (Clustered Index)
⚫ ‘영어 사전’과 같은 책
⚫ 테이블 당 한 개만 지정 가능
⚫ 행 데이터를 인덱스로 지정한 열에 맞춰 자동 정렬
◦ 보조 인덱스 (Secondary Index)
⚫ 책 뒤에 <찾아보기>가 있는 일반 책
⚫ 테이블당 여러 개도 생성 가능

◦ 인덱스의 특징
⚫ PRIMARY KEY로 지정한 열은 클러스터형 인덱스가 생성
⚫ UNIQUE NOT NULL로 지정한 열은 클러스터형 인덱스 생성
⚫ UNIQUE(또는 UNIQUE NULL)로 지정한 열은 보조 인덱스 생성
⚫ PRIMARY KEY와 UNIQUE NOT NULL이 존재
⚫ PRIMARY KEY와 UNIQUE NOT NULL이 있으면 PRIMARY KEY에 지정한 열에 우선 클러스터형 인덱스 생성
⚫ PRIMARY KEY로 지정한 열로 데이터가 오름차순 정렬

B-Tree(Balanced Tree, 균형 트리)
◦ 자료 구조’에 나오는 범용적으로 사용되는 데이터 구조
◦ 인덱스 표현할 때와 그 외에도 많이 사용

페이지 분할
◦ 인덱스 구성시 SELECT 문의 효율성 향상
◦ 인덱스 구성시 INSERT 문이 일어날 경우 속도 저하되는 단점

클러스터형 인덱스와 보조 인덱스의 구조
◦ 클러스터형 인덱스 구성한 테이블 구조
⚫ userID를 Primary Key로 지정하면 클러스터형 인덱스로 구성됨

◦ 클러스터형 인덱스의 특징
⚫ 클러스터형 인덱스의 생성 시에는 데이터 페이지 전체 다시 정렬
⚫ 이미 대용량의 데이터가 입력된 상태라면 업무시간에 클러스터형 인덱스 생성하는 것은 심각한 시스템 부하
⚫ 인덱스 자체의 리프 페이지가 곧 데이터
⚫ 인덱스 자체에 데이터가 포함되어 있음
⚫ 클러스터형 인덱스는 보조 인덱스보다 검색 속도는 더 빠름
⚫ 데이터의 입력/수정/삭제는 더 느림
⚫ 클러스터형 인덱스는 성능이 좋지만 테이블에 한 개만 생성 가능
⚫ 어느 열에 클러스터형 인덱스 생성하는지에 따라 시스템의 성능이 달라짐

◦ 보조 인덱스의 특징
⚫ 보조 인덱스 생성시 별도의 페이지에 인덱스 구성
⚫ 인덱스 자체의 리프 페이지는 데이터가 아니고 데이터가 위치하는 주소 값(RID)
⚫ 클러스터형보다 검색 속도는 더 느림
⚫ 데이터의 입력/수정/삭제는 덜 느림
⚫ 보조 인덱스는 여러 개 생성할 수 있음
⚫ 남용할 경우에는 시스템 성능을 떨어뜨리는 결과 발생

◦ 클러스터형 인덱스와 보조 인덱스가 혼합되어 있을 경우
⚫ 보조 인덱스를 검색한 후에 다시 클러스터형 인덱스를 검색해야 하므로 약간의 손해를 볼 수도 있겠지만, 데이터의 삽입 때문에 보조 인덱스를 대폭 재구성하게 되는 큰 부하는 걸리지 않음
⚫ 보조 인덱스와 혼합되어 사용되는 경우 되도록이면 클러스터형 인덱스로 설정할 열은 적은 자릿수의 열을 선택하는 것이 바람직함
⚫ 인덱스를 검색하기 위한 일차 조건
⚫ WHERE절에 해당 인덱스를 생성한 열의 이름이 나와야 함
⚫ WHERE절에 해당 인덱스를 생성한 열 이름이 나와도 인덱스를 사용하지 않는 경우도 많음

인덱스의 성능 비교
◦ 인덱스 없는 경우, 클러스터형 인덱스, 보조 인덱스를 설정하여 쿼리 속도 비교, 서버 부하 비교
⚫ 데이터의 중복도가 높은 경우에, 인덱스 사용하는 것이 효율이 있음
⚫ 하지만 인덱스의 관리 비용과 INSERT 등의 구문에서는 오히려 성능이 저하될 수 있다는 점 등을 고려하면 인덱스가 반드시 바람직하다고 보기는 어려움

인덱스에 대한 결론
◦ 인덱스는 열 단위에 생성
⚫ 두 개 이상의 열을 조합해서 인덱스 생성 가능
◦ WHERE절에서 사용되는 열에 인덱스를 만들어야 함
⚫ 테이블 조회 시 WHERE절의 조건에 해당 열이 나오는 경우에만 인덱스 주로 사용
◦ WHERE절에 사용되더라도 자주 사용해야 가치가 있음
⚫ SELECT문이 자주 사용 되어야 효과적
⚫ INSERT문이 자주 사용되고 생성된 인덱스가 클러스터형이면 효율 감소
◦ 데이터의 중복도가 높은 열은 인덱스 만들어도 효과 없음
⚫ 인덱스의 관리 비용 때문에 인덱스가 없는 편이 나은 경우도 있음
◦ 외래 키 지정한 열에는 자동으로 외래 키 인덱스가 생성

◦ JOIN에 자주 사용되는 열에는 인덱스를 생성해 주는 것이 좋음
◦ INSERT/UPDATE/DELETE가 얼마나 자주 일어나는지 고려해야 함
⚫ 인덱스는 단지 읽기에서만 성능 향상
⚫ 데이터의 변경에서는 오히려 부담
◦ 클러스터형 인덱스는 테이블당 하나만 생성 가능
⚫ 클러스터형 인덱스를 생성할 열은 범위(BETWEEN, >, < 등의 조건)로 사용하거나 집계 함수를 사용하는 경우 아주 적절하게 사용
◦ 클러스터형 인덱스가 테이블에 아예 없는 것이 좋은 경우도 있음
◦ 사용하지 않는 인덱스는 제거
⚫ 공간 확보 및 데이터의 입력 시에 발생되는 부하 줄임