본 게시글은 [전자책] 2023 유선배 SQL개발자(SQLD) 과외노트를 기반으로 작성했습니다.
책엔 더 자세한 설명과 문제가 나와있습니다. 저작권에 위배된다면 댓글 부탁드립니다!
정규화
엔터티를 작은 단위로 분리하는 과정
정규화를 할 경우 데이터의 입력/수정/삭제성능이 향상된다.
제1정규형: 모든 속성은 반드시 하나의 값만 가져야 한다.
제2정규형: 엔터티의 모든 일반속성이 반드시 모든 주식별자(복합식별자면 전부 다 포함)에 종속되어야한다.
제3정규형: 주식별자가 아닌 모든 속성 간에는 서로 종속될 수 없다.
(1) 제1정규형
모든 속성은 반드시 하나의 값만 가져야한다는 것
위의 경우, 다음과 같은 코드에선 아웃풋이 존재하지 않는다.
SELECT * FROM ENTERTAINER WHERE JOB = '가수' # NO DATA
다중값을 가지게 된다면 split함수를 이용해야 한다는 식의 번거로움이 생기기 때문에 아래와 같이 엔터티를 나누는 것이다.
Q. 유사한 속성이 한 엔터티 내에 존재하는 경우는 어떨까?
데이터가 늘어날 때마다 속성이 추가되고, null 또한 가능하므로 공간의낭비도 발생할 수 있기 때문에 아래와 같이 엔터티를 사이트로 분리한다.
(2) 제2정규형
복합식별자지만 음료명이 음료코드에만 종속되어있다.
이 경우, 카페오더/음료로 엔터티를 나누어 정규화시킨다.
![]() |
이 경우, 복합식별자지만 주문상품명/주문상품가격이 주문상품코드에만 종속되기 때문에 제2정규형 위반이다. |
(3) 제3정규형
주식별자가 아닌 모든 속성은 종속시키지 못한다. 위의 경우 소속사코드와 소속사명을 따로 엔터티로 나눈다.
(4) 반정규화(De-Normalization)
조회성능을 향상시키기 위해 데이터중복 허용, 데이터를 그룹핑하는 과정이다. 입력, 수정, 삭제 성능은 저하될 수 있으며, 정합성이슈가 발생할 수 있다.
반정규화는 정규화가 끝난 후 거치게 되는 과정이며, 일정한 룰이 존재한다.
1. 테이블 반정규화
1-1. 테이블 병합
1:M을 병합할 경우, 1에 엔터티속성개수가 많으면 병합 때 중복이 많아지므로 적절하지 못하다.
1:1 | 1:M |
![]() |
![]() |
출처: 2023 유선배 SQL개발자(SQLD) 과외노트, 정미나
1-2. 테이블 분할
수직분할 (일부 속성을 별도의 엔터티로 분할) | 수평분할 (파티셔닝) |
![]() |
![]() |
출처: 2023 유선배 SQL개발자(SQLD) 과외노트, 정미나
1-3. 테이블추가
데이터의 중복을 감안하더라도 성능상 반드시 필요하다고 판단되는 경우 별도의 엔터티를 추가한다.
중복 테이블 추가 | 통계 테이블 추가 |
중복을 감안하고 필요하다 생각되면 별도의 엔터티 추 | ![]() |
이력 테이블 추가 | 부분 테이블 추가 |
![]() |
![]() |
출처: 2023 유선배 SQL개발자(SQLD) 과외노트, 정미나
2. 컬럼 반정규화
중복컬럼 추가: JOIN을 많이 쓰는 경우 차라리 컬럼추가
파생컬럼 추가: 부하가 염려되는 계산값을 미리 추가해서 보관하는 방식 EX. 상품재고, 프로모션 적용 할인가
이력 테이블컬럼 추가: 대량의 이력 테이블을 조회하기 위해 기준이 되는 컬럼을 미리 추가 EX. 최신 데이터 여부
3. 관계 반정규화
업무 프로세스 상 JOIN이 필요한 경우가 많아 중복 관계를 추가하는 것이 유리한 경우 고려
트랜잭션
트랜잭션이란?
데이터를 조작하기 위한 하나의 논리적인 작업 단위
온라인 퀴즈에서 정답을 맞히면 쿠폰을 발행해주는 이벤트를 하고있다.
이 때 트랜잭션은 [이벤트 응모이력을 저장한다, 쿠폰을 발행한다] 이다.
NULL
SQL은 NULL이 포함되어있으면 결과값이 NULL이 된다.
SELECT * FROM ACCOUNT;
SELECT NAME, INCOME - EXPENSE FROM ACCOUNT; 가로계산의 경우 NULL값을 포함하면 결과값은 NULL |
![]() |
SELECT SUM(INCOME) FROM CCOUNT; 세로계산의 경우 NULL값을 제외한 나머지를 계산 ( <-> 타 인스턴스와의 연산에서는 NULL을 빼고 계산) |
![]() |