최근 수정 시각 : 2024-10-24 03:21:38

SQL/정규화

프로그래밍 사이트 선정 프로그래밍 언어 순위 목록
{{{#!wiki style="margin: 0 -10px -5px; word-break: keep-all"
{{{#!wiki style="display: inline-table; min-width: 25%; min-height: 2em;"
{{{#!folding [ IEEE Spectrum 2024 ]
{{{#!wiki style="margin: -5px 0"
<rowcolor=#fff> 스펙트럼 부문 상위 10개 프로그래밍 언어 직업 부문 상위 10개 프로그래밍 언어
1 Python 1 SQL
2 Java 2 Python
3 JavaScript 3 Java
4 C++ 4 TypeScript
5 TypeScript 5 SAS
6 SQL 6 JavaScript
7 C# 7 C#
8 Go 8 HTML
9 C 9 Shell
10 HTML 10 C++
}}}
}}}
}}}
[ Stack Overflow 2024 ]
||<tablewidth=100%><width=9999><-4><bgcolor=#FFA500><tablebgcolor=#fff,#222> 2024년 Stackoverflow 설문조사 기준 인기 상위 25개 프로그래밍 언어 ||
1 JavaScript 14 Rust
2 HTML, CSS 15 Kotlin
3 Python 16 Lua
4 SQL 17 Dart
5 TypeScript 18 어셈블리어
6 Bash 19 Ruby
7 Java 20 Swift
8 C# 21 R
9 C++ 22 Visual Basic
10 C 23 MATLAB
11 PHP 24 VBA
12 PowerShell 25 Groovy
13 Go
[ TIOBE 2024 ]
||<tablewidth=100%><width=9999><-4><bgcolor=deepskyblue><tablebgcolor=#fff,#222> 2024년 8월 기준 검색어 점유율 상위 20개 프로그래밍 언어 ||
1 Python 11 MATLAB
2 C++ 12 Delphi / Object Pascal
3 C 13 PHP
4 Java 14 Rust
5 C# 15 Ruby
6 JavaScript 16 Swift
7 SQL 17 Assembly language
8 Visual Basic 18 Kotlin
9 Go 19 R
10 Fortran 20 Scratch
{{{#!wiki style="margin: 0 -10px -5px; min-height: calc(1.5em + 5px);"
{{{#!folding [ 21위 ~ 50위 펼치기 · 접기 ]
{{{#!wiki style="margin: -5px -1px -11px"
21 COBOL 36 Scala
22 Classic Visual Basic 37 Transact-SQL
23 LISP 38 PL/SQL
24 Prolog 39 ABAP
25 Perl 40 Solidity
26 (Visual) FoxPro 41 GAMS
27 SAS 42 PowerShell
28 Haskell 43 TypeScript
29 Dart 44 Logo
30 Ada 45 Wolfram
31 D 46 Awk
32 Julia 47 RPG
33 Objective-C 48 ML
34 VBScript 49 Bash
35 Lua 50 Elixir
}}}}}}}}} ||
[ PYPL 2024 ]
||<tablewidth=100%><width=9999><-4><bgcolor=green><tablebgcolor=#fff,#222> 2024년 8월 기준 검색어 점유율 상위 20개 프로그래밍 언어 ||
1 Python 11 Objective-C
2 Java 12 Go
3 JavaScript 13 Kotlin
4 C# 14 MATLAB
5 C/C++ 15 PowerShell
6 R 16 VBA
7 PHP 17 Dart
8 TypeScript 18 Ruby
9 Swift 19 Ada
10 Rust 20 Lua

}}} ||
프로그래밍 언어 목록 · 분류 · 문법


1. 개요2. 장점3. 단점4. 정규화
4.1. 1NF4.2. 2NF4.3. 3NF

1. 개요

SQL의 정규화는 데이터의 일관성, 최소한의 데이터 중복, 최소한의 데이터 유연성을 위해 사용되며 데이터를 분해하는 과정이다. 주로 관계형 데이터베이스에서만 사용되며 3NF 이상은 하지 않는 편이다.[1]
  • 정규화된 모델은 테이블이 분해된다.[2] 테이블이 분해되면 A 테이블과 B 테이블 간에 조인(JOIN)을 수행하며 하나의 합집합으로 만들 수 있다.
  • 정규화를 하면 불필요한 데이터를 입력하지 않아도 되기 때문에 중복 데이터가 제거된다.

2. 장점

  • 불필요한 데이터를 제거하여 데이터의 중복을 최소화할 수 있기 때문에 저장 공간을 효율적으로 이용할 수 있게 된다.
  • 각종 이상 현상(Anomaly)[3]를 방지할 수 있다.
  • 테이블 데이터 집합이 논리적, 직관적으로 구성된다. (자료 구조가 안정적으로 변화한다.)
  • 다양한 관점에서의 쿼리를 지원한다.
  • 데이터 무결성 유지

3. 단점

  • 릴레이션(관계)의 분해로 릴레이션 간의 참조 연산(JOIN)이 많아져 응답 시간이 길어질 수 있다.
  • 상대적으로 타 DBMS로의 구조 이식이 어려워진다.

4. 정규화

정규화의 과정은 1NF -> 2NF -> 3NF -> BCNF -> 4NF -> 5NF 의 순서를 거친다.

4.1. 1NF

릴레이션에 속한 모든 속성의 도메인이 원잣값으로만 구성되어 있으면 제1정규형에 속한다(원자성).

수강 Table
수강 번호 이름 수강 강의
1001 김나무 물리학
1002 이위키 지리학
1003 박좋아 컴퓨터공학, 화학공학

김나무와 이위키는 물리학과 지리학을 들을 뿐이지만, 박좋아는 복수 전공을 통해 컴퓨터공학과 화학공학을 동시에 듣고 있다. 사실 이렇게 하여도 SQL DB를 운용하는 데 지장은 없지만 윗선에서 '화학공학'을 듣는 친구들을 교수실로 보내게라고 알람이 내려왔다. 관련 알람을 확인한 SQL 관리자는 쿼리문을 통해 '화학공학'을 듣는 친구들을 찾아야 하는데 문제점이 발생했다.

일반적이라면 단순히

#!syntax sql
SELECT = * ;
FROM = '수강 Table' ;
WHERE 수강 강의 = '화학공학' ;


으로 찾을 수 있겠지만 1NF가 되어있지 않은 경우

#!syntax sql
SELECT = * ;
FROM = '수강 Table' ;
WHERE 수강 강의 LIKE '%화학공학%' ;


으로 귀찮게 찾아야 한다는 것이다.(...) 이는 박좋아의 수강 강의의 컬럼이 원자성을 가지지 않기 때문이다. 물론 표에 없는 다른 학생들이 복수 전공을 듣고 있다면 관리자는 더욱 머리가 복잡해질 것이다. 하는 수 없이 관리자는 위의 테이블을 1NF 정규화하여 아래와 같은 테이블로 만들었다.

수강 Table
수강 번호 이름 수강 강의
1001 김나무 물리학
1002 이위키 지리학
1003 박좋아 컴퓨터공학
1003 박좋아 화학공학

이제 각 ROW마다 컬럼의 값이 1개만 들어있게 됨으로써 원자성이 충족되었다.
1NF는 검색 쿼리의 단순화를 위해서라는 목적도 있지만 실질적으로는 데이터의 중복성을 제거하고 데이터의 일관성과 무결성을 유지하기 위한 목적이 더욱 크다. 중복된 데이터가 존재할 경우 데이터베이스의 크기가 커지고 데이터의 일관성이 깨지는 등의 문제가 발생할 수 있기 때문에, 제1정규형을 수행하여 DB의 효율성을 높이고 데이터의 신뢰성을 확보할 수 있다.

4.2. 2NF

후보 키 K와 K에 속하지 않는 속성 A가 있을 때 A를 결정하기 위해 K의 일부가 아닌 K 전체를 참조해야만 하는 경우 제2정규형에 속한다.[4]
쉬운 이해: 기본 키가 아닌 모든 속성이 기본 키에 완전 함수 종속되면 제2정규형에 속한다.

수강 등록 현황 Table
수강 번호 이름 수강 강의 강의 지각 벌금 납부 여부(회)
1001 김나무 물리학 10,000 2
1002 이위키 지리학 7,500 1
1003 박좋아 컴퓨터공학 5,000 0
1003 박좋아 화학공학 15,000 1
1004 최고다 물리학 10,000 1
나무대학교의 이사장은 강의마다 지각한 사람들의 횟수를 체크하여 벌금을 매기기로 하였다! 학생들은 불만이 컸지만 그런대로 수긍하며 지각 벌금을 묵묵히 내고 있었는데 물리학을 강의하는 교수님께서 이제부터 물리학의 지각 벌금은 10,000원이 아닌 15,000원입니다.라고 선언하였다. 해당 SQL 데이터를 관리하는 관리자는 이제 2가지 선택을 해야만 한다.
  • 1번 선택지: 물리학의 '강의 지각 벌금'에 해당하는 컬럼을 일일이 찾아 15,000원으로 고친다. 다만 SQL 관리자가 과거에 본 기억상으로는 나무대학교에서 물리학을 듣는 학생 수가 수천 명 이상이었다고 기억한다.
  • 2번 선택지: 제2정규화를 해서 현재 테이블의 주제와 관련 없는 컬럼을 다른 테이블로 빼낸다.
관리자는 수천 명 이상의 데이터를 일일이 15,000원으로 바꿀 자신이 없었기에 2번 선택지를 통해 제2정규화를 진행하여 아래와 같은 테이블을 만들었다.

수강 등록 현황 Table
수강 번호 이름 수강 강의 납부 여부(회)
1001 김나무 물리학 2
1002 이위키 지리학 1
1003 박좋아 컴퓨터공학 0
1003 박좋아 화학공학 1
1004 최고다 물리학 1
강의 지각 벌금 Table
강의 강의 지각 벌금
물리학 15,000
지리학 7,500
컴퓨터공학 5,000
화학공학 10,000
이제 각각의 테이블은 제2정규형을 만족하는 테이블이 되었다. SQL 관리자는 귀찮게 물리학의 '강의 지각 벌금'에 해당하는 컬럼을 일일이 찾으면서 고칠 필요가 없는 것이다! 이제 '강의 지각 벌금 Table'에서 물리학에 해당하는 벌금을 15,000원으로 변경하기만 하면 끝이 난다. 제2정규화를 통해 관리가 매우 편해진 것이다. 하지만 다른 문제도 생겼는데 이제는 '수강 등록 현황 Table'를 보기만 해서는 강의 지각 벌금이 얼마인지를 알 수 없게 되어버린 것이다.

4.3. 3NF

제2정규형에 속하면서 기본키가 아닌 모든 속성이 기본 키에 이행적 함수 종속[5]이 되지 않으면 제3정규형에 속한다.



[1] 일반적인 경우, 1NF부터 3NF까지의 정규화만으로도 데이터 중복, 무결성 제약 조건 위반 등의 문제를 해결하는 데 충분하다고 여겨지기 때문이다. 하지만 대규모 트랜잭션의 처리 등이 필요해질 경우 BCNF를 넘어 심지어는 5NF까지 진행을 해야 할 수도 있다.[2] 즉 아래의 정규화 과정에서 나오겠지만 테이블이 분할되며 복잡한 관계의 테이블이 만들어지게 된다. A는 B를 참조하는 식으로....[3] 흔히 삽입, 삭제, 갱신 이상이라고 한다. 불필요한 데이터를 넣지 않으면 안된다거나, 특정한 컬럼을 삭제했는데 연쇄적으로 다른 것까지 삭제 된다거나 특정 테이블의 데이터를 업데이트했는데 다른 테이블에서는 업데이트가 되지 않아, 정보의 차이가 발생한다거나...[4] 부분함수종속을 제거하여 완전함수종속을 충족하기위해 정규화한다.[5] 여기서 이행적 함수 종속이란 A->B, B->C, A->C가 성립하는 것을 의미한다. 이를 C가 A에 이행적으로 함수 종속 되었다고 한다.

분류