47회 SQL 개발자 자격 시험에 합격했다. 진로를 확실히 비틀어버린 뒤에 처음으로 취득하는 자격증이라 굉장히 뿌듯한 감이 있다.
처음에는 1달 정도를 투자하고 싶었는데 다른 할 일들에 치이거나 너무 이론적으로 접근하는 등.. 시간 낭비를 꽤 많이 한 것 같아서 아쉬운 부분이 있다. 공부하면서 확인했던 점들을 여기에 남긴다.
마지막 파트에 개인적으로 정리한 개념들이 기재되어 있는데 이후에 실전적인 부분이나, 내가 암기하기 편하도록 편집된 점들이 이곳저곳에 남아서 맞지 않는 부분 등이 존재할 수 있다! 그래도 혹시 누군가가 공부할 때에 도움이 될 수 있으니 전체 내용을 남겨두고 나중에 생각나면 편집할 예정이다.
실질적으로 소모한 시간은 2주 가량, 문제 풀이에는 1주 가량을 소비했다.
처음에는 Data on Air에서 제공하는 개념 설명을 통해 왕도에 가까운 방향으로 공부를 진행하고 싶었지만 SQLD 자체가 개념적인 부분보다는 실전적인 SQL 구문의 형태로 제공되는 문제 수가 훨씬 많은 것을 보고 초반부에 하차하게 되었다. 하지만 여전히 내용 자체는 좋다고 생각하기 때문에 시간이 많다면 한 번 확인하는 것을 추천한다!
그 다음으로는 유튜브에 존재하는 다양한 형태의 강의를 통해 대략적인 개요를 잡았다. SQLD에 한해서는 꽤 많은 양의 정리된 강의가 존재하고 있기 때문에 좋아보이는 것을 골라잡는 것으로 충분할 것이다.
마지막으로 문제풀이인데 문제의 경우는 관련 카페 혹은 블로그에 기출 문제를 복원해놓은 자료들이 존재한다. 일명 "노랭이" 라고 불리는 책도 좋지만 기출문항에 대한 풀이도 소홀히 하지 않는 것이 중요하다! 노랭이의 경우는 2단원까지 1회독 및 오답 노트 정리만 진행하였고 나머지 시간 동안 전부 기출 문제 풀이에 시간을 사용했다.
개인적으로 추천하는 복원 문제 모음 사이트는 이 블로그를 추천하고 싶다. 답을 입력하는 것으로 즉시 해당 문제의 정오를 확인할 수 있기 때문.
참고사항: 1단원 쪽이 2단원보다 문제 비중이 적어 후순위로 밀렸고 그에 따라 필요한 내용만 기재하여 내용이 충분치 않을 수 있음
1개 엔터티: 2개 이상의 인스턴스 집합 + 2개 이상의 속성
1개 속성: 1개 이상의 속성값
ERD에서는 존재적 관계와 행위적 관계를 구분하지 않는다.
하지만 Class 다이어 그램에서는 구분하며 연관 관계, 의존 관계를 서술해야 한다.
데이터 베이스 성능 향상을 목적으로 성능 관련 사항을 데이터 모델링에 반영
정규화된 엔터티, 속성, 관계의 중복, 통합, 분리를 통해
시스템의 성능을 향상, 개발 및 운영의 단순화
무결성이 깨질 수 있음에도 성능 저하가 예상될 때 수행한다.
개별적으로 발생하는 Transaction -> 개별 테이블
슈퍼 + 서브 타입 -> 슈퍼 + 서브 테이블
전체 -> 하나의 테이블
- 지역 자치성, 점진적으로 시스템의 용량 확장이 가능
- 신뢰성과 가용성 / 효용성과 융통성
- 빠른 응답 속도, 통신 비용의 절감, 지역 사용자의 요구 수용 증대
- 데이터의 가용성과 신뢰성 증가, 시스템 규모 조절
- 개발 비용 및 오류 잠재성 증가, 처리 비용 증가, 데이터의 무결성을 위협
- 설계 과정의 어려움, 관리의 복잡성과 비용, 불규칙한 응답속도, 통제의 어려움
Data Control Language, 권한을 관리하는 명령어
권한을 부여하는 역할
GRANT {permission} ON {table} TO {user};
의 형태로 사용
WITH GRANT, WITH ADMIN의 비교
GRANT: 특정 사용자에게 권한 부여가 가능한 권한을 부여, 부여한 부모의 권한이 회수될 때 자식의 권한도 회수
ADMIN: 테이블에 대한 모든 권한을 부여, 부여한 부모의 권한 회수와 관계 없는 권한
REVOKE {permission} ON {table} FROM {user};
의 형태로 사용ALL -- 모든 권한 부여
SELECT INSERT UPDATE DELETE /* */
REFERENCES ALTER INDEX /* */
/* ROLE: 다양한 권한을 하나의 그룹으로 묶어서 관리 */
CREATE ROLE {role_name}; -- 권한 그룹 생성
GRANT {permission_type} TO {role_name}; -- 해당 그룹에 권한 등록
GRANT {role_name} TO {user_1}, {user_2}...; -- 다른 유저들에게 권한 그룹 부여
Data Definition Language, 데이터를 정의하는 명령어
SQL Server 기준으로 Auto Commit을 지원
테이블 구조 생성
CREATE TABLE {table_name} {table_elements};
의 형태로 사용
CREATE TABLE EXAMPLE (
/*
컬럼명은 영어, 한글, 숫자 전부 가능
첫 글자를 문자로 지정해야 하며, 컬럼의 데이터 타입은 반드시 설정해야 한다.
*/
NAME varchar2(max_length) -- 최대 길이를 가진 가변길이 문자열
ID번호 char(length) -- 고정된 길이 문자열
나이_2 number(max_length) -- 숫자형 데이터 타입
생일 date -- 날짜형 데이터 타입
);
테이블 및 컬럼에 대해 이름과 속성의 변경, 추가, 삭제 등의 구조 수정 역할
ALTER TABLE {table_name} {detail_order} {detail_property(if need)} TO {change_target};
의 형태로 사용
테이블, 컬럼을 ALTER를 거치지 않고 제거할 수 있음
테이블 초기화 (삭제가 아님!)
내부 데이터만 제거되고 테이블의 존재 및 컬럼은 남는다.
Data Manipulation Language, 레코드를 조작하는 명령어
INSERT INTO {table_name} {column_name} VALUES {change_column_name};
의 형태로 사용UPDATE {table_name} SET {column_name} = {column_value} WHERE {condition};
의 형태로 사용DELETE FROM {table_name} WHERE {condition};
의 형태로 사용특정 데이터를 조회
SELECT {select_target} FROM {select_origin} WHERE {condition};
의 형태로 사용
GROUP BY {calc_type} HAVING {condition} / ORDER BY {sort_condition}
의 형태로 조건을 넣기도 함
중복값 없이 조회하는 조건 (a, b, NULL, a, b, NULL) => (a, b, NULL)
(*): 전체 행의 수를 NULL 값을 포함하여 카운팅
({column_name}): 특정 컬럼의 행값을 NULL을 제외하고 카운팅
Transaction Control Language, Transaction 제어 명령어
Transaction: DB의 상태를 변화시키는 작업
* transaction의 특징
고립성: 실행되는 동안 다른 transaction에 영향을 받아 잘못된 결과를 만들면 안됨
일관성: 실행 전 데이터베이스에 잘못된 점이 없다면 transaction 수행 후에도 내용에 오류가 있으면 안됨
지속성: transaction이 갱신한 데이터베이스 내용은 영구적으로 저장
원자성: transaction에서 정의한 연산은 모두 성공적으로 실행되거나 전혀 실행되지 않음 (All or Nothing)
SAVEPOINT {savepoint_name};
의 형태로 사용ROLLBACK TO {rollback_point};
의 형태로 사용SELECT, WHERE 등의 조건을 지정할 때 많이 사용
EXTRACT ({information} FROM {data})
의 형태로 사용해당 함수들을 통해 데이터 타입을 변경할 수 있다
문자열 > 숫자
숫자, 날짜 > 문자 (포맷에 따라서 다르게 생성)
문자열 > 날짜 (포맷에 따라서 다르게 생성)
명시적 형변환 vs 암시적 형변환
명시적 형변환: 함수를 활용하여 데이터 타입을 변경
암시적 형변환: 데이터베이스가 알아서 바꿔주는 것
>> 숫자 타입의 PK는 암묵적으로 인덱스가 되는데 데이터의 조회 등으로 암시적 형변환이 발생한 경우, 인덱스로 사용이 불가능
WITH {table_name} AS {table_condition}
의 형태로 사용그룹 대상 컬럼값, 집계 대상 컬럼값은 NULL로 출력
일반 그룹함수로 동일한 결과를 추출할 수 있음
일반적으로 테이블 간의 결합, 집합과 유사
테이블과 테이블, 조인 결과와 테이블, 조인 결과끼리의 JOIN이 가능
관련된 두 테이블에 적어도 하나의 공통 속성이 존재할 때 적용 가능
JOIN을 명시하는 ANSI 표준형 쿼리가 있고 그렇지 않는 비표준형 쿼리가 존재한다.
JOIN이 나열된 경우 한 번에 2개씩 작업, 모두 동시에 작업 불가능
교집합
합집합
차집합
교집합을 배제하는 하나의 집합만 확인하려고 할 때 적용 가능
결합되는 대상 간의 일치 정도
EQUI JOIN: 동일한 컬럼을 사용하여 두 Relations을 결합
non-EQUI JOIN: 정확하게 일치하지 않는 컬럼들을 사용하여 두 Relations을 결합
ex) A.key <, >, <=, >= B.key
Key 없이 JOIN하면 두 테이블에 대해 Cartesian Product 발생
5개의 행 * 3개의 행 = 15개의 행으로 조회
트리 형태의 데이터에 대해 조회를 수행하는 것
계층 구조의 시작점은 START WITH로 설정(ROOT NODE)
자식 노드가 없는 노드 = LEAF NODE
계층을 LEVEL로 표기
계층 구조가 연결된 방향성을 확인
레코드 사이의 관계를 쉽게 정의하기 위한 함수
SELECT WINDOW_FUNCTION {arguments} OVER {partition by column} {order_style} FROM {table};
의 형태로 사용
윈도우 함수
그룹 내 집계함수: COUNT, SUM, MIN, MAX, AVG 등
그룹 내 순위함수
순위함수를 만들더라도 자동으로 sorting 하지 않기 때문에 ORDER BY 절을 활용해야 한다.
그룹 내 비율 관련 함수
그룹 내 행 순서 함수
- 인수(컬럼명 등 함수의 작업이 이뤄지는 대상)
함수의 연산 대상이 되는 레코드의 범위를 정함
대용량의 테이블을 여러 개의 데이터 파일에 분리하여 저장하는 것
물리적으로 분리된 데이터 파일에 저장 => 성능 향상 및 독립적 관리 가능
조회의 범위를 줄이는 효과 => 성능 향상
같은 SQL문이더라도 어떻게 실행하느냐에 따라서 성능이 달라짐 (성능의 지표: 소요시간, 자원사용량 등)
따라서, SQL문을 분석하여 일정 기준에 따라서 실행 계획을 세울 필요가 있으며 이 때 옵티마이저를 사용한다.
옵티마이저는 실행 성능에 영향을 줄 수 있지만 결과값은 달라지지 않는다.
SQL문 작성 => 파싱 (문법 검사, 구문 분석) => 옵티마이저 (비용 기반 / 규칙 기반) => 실행 계획 (PLAN_TABLE 저장) => SQL 실행
인덱스 키를 기준으로 정렬 => 탐색이 빨라짐
PK는 자동적으로 INDEX가 됨
하나의 테이블에 여러 개의 인덱스를 생성할 수 있으며, 하나의 인덱스가 여러 컬럼으로 구성될 수 있음
내림차순으로 생성 및 정렬됨
자주 변화하는 속성을 인덱스로 설정하는 것은 좋지 않음
보조 인덱스에는 UNIQUE 속성의 인덱스가 아니라면 중복 데이터의 입력이 가능하다.
인덱스 스캔보다 전체 스캔이 더 효율적이고 비용 기반으로 유리할 수 있음
파티션 테이블은 파티션에 대해 파티션 키 인덱스를 생성 가능, Global 인덱스라고 부름
인덱스가 늘어나면 당연히 데이터의 증가이므로 입력, 삭제, 수정 속도의 하락을 불러올 수 있음
모든 데이터 타입으로 인덱스 형성이 가능
인덱스의 종류로 순차 인덱스, 비트맵, 결합 인덱스, 클러스터, 해시 인덱스가 존재한다.
두 테이블 중 작은 테이블을 HASH 메모리에 로딩, 두 테이블의 JOIN 키를 사용하여 해시 테이블 생성
두 테이블을 동시에 스캔
선행 테이블에는 "작은 데이터"가 먼저 와야 함
시스템 자원을 최대한 활용 가능, 자원을 너무 많이 사용할 수 있으며 부하 등의 우려 존재
대용량 처리에 빠른 처리 속도를 보임
EQUI JOIN에서만 가능
INDEX를 사용하지 않음
JOIN 방식
먼저 선행 테이블을 결정, 선행 테이블에서 주어진 조건에 해당하는 레코드를 선택
해당 행이 선택되면 JOIN Key를 기준으로 해시 함수를 사용
해시 테이블을 메인 메모리에 생성, 후행 테이블에서 주어진 조건을 만족하는 행을 찾음
후행 테이블의 JOIN Key를 사용해서 해시함수를 적용, 해당 버킷을 검색
SQL을 확장시켜 다양한 절차적 프로그래밍을 가능하게 한 언어
하나의 데이터베이스 시스템(DBMS)이 네트워크를 통해 물리적으로 분리된 데이터베이스들을 제어하는 형태의 DB
메모
count(*): 전체 행의 수를 카운팅, null 포함
count({column_name}) null 을 제외한 행의 수를 카운팅
null: 모르는 값을 상징, 값의 부재를 말함
(null is null) = TRUE
null과의 모든 비교는 null 반환
0 혹은 ' '과 동일한 값이 아님
서브쿼리: SELECT문 내의 SELECT문이 반복 사용된 쿼리, 단일행 및 다중행으로 구분
- 정렬을 수행하는 ORDER BY를 사용할 수 없다.
- 여러 행을 반환하는 서브 쿼리는 다중 행 연산자를, 단일 행을 반환하는 서브쿼리는 단일 행 연산자를 사용
- 메인 쿼리에서 서브 쿼리의 컬럼을 자유롭게 사용할 수 없음
- EXIST는 True 혹은 False를 반환한다
스칼라 서브쿼리: 한 행과 한 컬럼만 반환하는 서브쿼리
인라인뷰: 서브쿼리가 FROM 절 내에 쓰여진 것
view 테이블
- 사용상의 편의를 위해 사용
- 수행속도의 향상을 위해 사용
- SQL의 성능을 향상시키기 위해 사용
- 임시적인 작업을 위해 사용
- 보안관리를 위해 사용
실행 순서
SELECT ALIAS => FROM => WHERE => GROUP BY => HAVING => SELECT => ORDER BY
조회 행수 제한
몇 번째 행을 조회하는지 부여하는 조건문
ROWNUM {row_number}: Oracle
TOP {row_number}: SQL Server
LIMIT {row_number}: MySQL
ROWID
해당 데이터가 어떤 데이터 파일 상에서 어느 블록에 저장되었는지 알려준다.
데이터베이스에 저장되어 있는 데이터를 구분할 수 있는 유일한 값이다.
ROWID의 번호는 데이터 블록에 데이터가 저장된 순서이다.
테이블에 데이터를 입력하면 자동으로 생성된다.
이 글 보고 SQLD 49회 합격했어요!