프로그래밍 언어/[ DB ]

[ DB ] 00. 데이터베이스란?

kim.svadoz 2020. 8. 10. 16:16
반응형

0. 데이터 베이스란?

대량의 정보를 컴퓨터가 효율적으로 접근할 수 있도록 가공 및 저장한 것을 '데이터베이스'라고 한다.

  1. 계층형 데이터 베이스(HDBMS)
  2. 관계형 데이터베이스(RDBMS)
    • 열과 행으로 이루어진 2차원 표형식으로 데이터를 관리
    • 가장 많이사용
  3. 객체지향 데이터베이스(OODB)
  4. XML 데이터베이스(XMLDB)
  5. 키-밸류형 데이터스토어(KVS)
  • 정형화 데이터 처리 프로그램
    • DB
    • Oracle
      • 대부분의 기업들이 사용(일반적)
      • 데이터 저장, 대량처리 가능
    • MySQL
      • 보통 중소기업
    • MSSQL
      • 보통 중소기업
    • 티베로

1. 데이터베이스 정규화

관계형 데이터베이스 설계시 중복을 최소화하도록 데이터를 구조화 하는 작업

1. 함수 종속성

관계형 데이터베이스의 설계에서 중복된 데이터가 최소화되도록 데이터베이스의 구조를 결정하는 것을 정규화 (normalization)라고 한다. 정규화된 데이터베이스가 그렇지 않은 데이터베이스에 비하여 더욱 효율적으로 데이터에 대한 연산을 수행할 수 있는 것은 매우 당연한 것이다. 이러한 데이터베이스의 정규화 과정에서 함수 종속성이라는 개념은 매우 중요하게 이용된다.

함수 종속성은 수학에서의 함수와 같이 두 필드의 집합이 many-to-one 관계로 사상되는 것을 말한다. 즉, 함수와 같이 어떠한 값을 통해 종속 관계에 있는 다른 값을 유일하게 결정할 수 있다는 것이다. 데이터베이스에서의 함수 종속성을 더욱 명확하게 정의하면 다음과 같다.

어떤 테이블 RR에 존재하는 필드들의 부분집합을 각각 XX와 YY라고 할 때, XX의 한 값이 YY에 속한 오직 하나의 값에만 사상될 경우에 "YY는 XX에 함수 종속 (YY is functionally dependent on XX)"이라고 하며, XX→YY라고 표기한다.

예를 들어, 테이블에 [생일]과 [나이]라는 필드가 존재할 경우에 [나이] 필드는 [생일] 필드에 함수 종속이다. 즉, 생일을 알고 있다면, 나이에 대한 필드를 참조하지 않거나, 아예 필드를 유지하지 않아도 나이를 결정할 수 있다. 데이터베이스 설계 단계에서 함수 종속 관계에 있는 필드를 찾는다면, 그 만큼 중복된 데이터를 줄일 수 있다. 그러므로, 데이터베이스 설계 단계에서 각 정보들 간의 함수 종속 관계를 찾는 것은 매우 중요하다.

2. 함수 종속의 성질

어떠한 테이블 RR에 대해 X,Y,ZX,Y,Z라는 필드의 집합이 있을 때, 함수 종속은 다음과 같은 성질을 만족하며, 이를 암스트롱의 공리 (Armstrong's axioms)라고 한다.

  • augmentation: 만약 X→YX→Y이면, XZ→YZXZ→YZ이다.
  • t**ransitivity**: 만약 X→YX→Y이고 Y→ZY→Z이면, X→ZX→Z이다.
  • reflexivity: 만약 YY가 XX의 부분집합이면, X→YX→Y이다.
  • self-determination: 자기 자신은 자신에 의해 함수 종속적이다. 즉, X→XX→X이다.
  • union: 만약 X→YX→Y이고 X→ZX→Z이면, X→YZX→YZ이다.
  • decomposition: 만약 X→YZX→YZ이면, X→YX→Y이고 X→ZX→Z이다.

관계형 데이터베이스는 이산수학의 relation 및 function의 개념을 이용하여 정의되었기 때문에 그 성질 또한 이산수학의 개념과 유사한 것을 볼 수 있다.

3. 키의 종류

  1. 슈퍼키(Super key) -유일성을 만족하는 키이다. 즉 기본키의 유니크 속성 예를 들어 게임 아이디에서 (게임 닉네임+ 게임 아이디), (게임 닉네임), (게임 아이디) 또는 (게임 아이디 소유자 이름 + 거주지)같은 것이다. 참고로 키는 튜플들이 모여서 키가 될 수 있으므로 (게임 아이디+ 게임 아이디) 는 두 가지 다른 튜플이 모여서 키를 이룬 것이라고 할 수 있다.
  2. 후보키(Candidate Key) - 유일성과 최소성을 만족하는 키이다. 위에서 게임 아이디는 중복되게 만들 수 있나..
  3. 기본 키(Primary Key) - 후보키 중에서 기본적으로 사용하기 위해 선택한 키이다.
  4. 대체 키(Surrogate Key) - 기본 키로 선택되지 못한 후보키이다. 위에서 게임 아이디를 기본 키로 선택했다면 게임 닉네임은 대체키가 된다.
  5. 외래키(Foreign Key) - 다른 릴레이션의 기본 키를 참조하는 키이다. 참조하는 릴레이션 : 외래키를 가진 릴레이션, 참조되는 릴레이션 : 외래키가 참조하는 기본키를 가진 릴레이션

4. Closure개념을 이용한 Super 키 판별

어떠한 테이블에서 주어진 필드의 집합이 해당 테이블의 super key인지를 판별하기 위해 closure라는 개념을 이용할 수 있다. 어떠한 테이블의 모든 필드가 주어진 필드의 집합 SS에 대해 함수 종속이라면, 주어진 필드의 집합 SS는 해당 테이블의 super key라고 할 수 있다. 따라서, 함수 종속성과 암스트롱의 공리, closure 개념을 이용하여 super key를 판별할 수 있다. 예를 들어, 어떠한 테이블 R(A,B,C,D,E,F)R(A,B,C,D,E,F)에서는 다음과 같은 함수 종속성이 존재한다.

1) 필드의 집합 CLOSURE={A,B}CLOSURE={A,B}를 정의한다.

2) 위의 주어진 함수 종속성에서 (1)에 해당하는 함수 종속 관계를 통해 A→CA→C임을 알 수 있다. 그러므로, 필드의 집합인 CLOSURECLOSURE에 CC를 추가한다.

3) 함수 종속 관계 (2)에 대해서는 해당하는 사항이 없다.

4) 함수 종속 관계 (3)에 의해 B→EB→E라는 사실을 알 수 있다. 그러므로, CLOSURECLOSURE에 EE를 추가한다.

5) 함수 종속 관계 (4)에 대해서는 해당하는 사항이 없다.

6-1) CLOSURECLOSURE에 변화가 있었으면, [과정 2]로 이동하여 현재 CLOSURECLOSURE 집합에 대해 알고리즘을 다시 실행한다.

6-2) CLOSURECLOSURE에 변화가 없었으면, 알고리즘을 종료한다.

알고리즘을 끝낸 후의 CLOSURECLOSURE는 주어진 테이블의 속성 중에서 DD가 빠진 {A,B,C,E,F}{A,B,C,E,F}와 같다. 따라서, 필드의 집합 {A,B}{A,B}는 해당 테이블의 super key가 아니다.

5. 정규화 작업의 장점과 단점

정규화는 기본적으로 하나의 테이블을 여러개의 테이블로 분리시키는 과정이므로 정규화가 진행될 수록 테이블 수가 늘어나게 됩니다. 정규화의 장점은 위와 같이 중복된 데이터를 제거하고 각종 이상증상을 없애는데 있지만 이에 반해 테이블 수가 늘어나게 되어 "조회"시에 여러 테이블을 참조해야만 하므로 "조회" 성능이 저하되는 단점이 있습니다.

여러 테이블에 분산되어 있는 정보는 "조회"시에 다시 하나로 모아야 하는데 이 작업은 JOIN이라는 명령으로 수행됩니다. 그런데 이 JOIN 명령이 테이터베이스에서 가장 부하가 많이 걸리는 작업 중에 하나입니다. 참고로 JOIN 작업을 줄이기 위해서 **Subquery** (쿼리 속의 쿼리)를 사용하기도 합니다.

따라서 정규화 과정은 대체적으로 성능과 이상증상의 제거를 서로 고려하여 적당한 선에서 결정합니다. 정규화는 1NF, 2NF, 3NF, BCNF, 4NF, 5NF 등 많이 있으나 (NF=Normal Form, 정규형) 성능 등을 고려하여 적당히 3NF 또는 BCNF 정도에서 멈추게 됩니다.

(성능을 위해 이미 정규화가 진행된 테이블을 서로 합치는 것을 역정규화라고 합니다.)

2. First Normal Form (1NF)

테이블에 존재하는 필드가 모두 scalar value만을 가지며, 필드의 값이 모두 atomic 할 때, 1NF라고 한다. 여기에서 atomic 하다는 것은 테이블에 중복되는 항목이 존재하지 않아야 한다는 것과 같다. 1NF에서 "중복되는 항목이 없다"에 대한 정의는 명확한 것이 아니기 때문에 1NF에 대한 정의 또한 여러 개가 존재할 수 있다.

image-20191218214325557

​ [그림 1] 예제 테이블 SUPPLIERS

위의 [그림 1]에 있는 테이블 SUPPLIERS는 {S#, P#}을 primary key로 가지며, 1NF의 정의를 만족하지 않는 테이블을 보여준다. 1NF의 정의를 만족하지 않기 때문에 아래의 [그림 2]에 표시된 것과 같이 서로 다른 primary key를 갖는 두 레코드가 같은 값을 갖고 있다. 즉, [그림 2]의 테이블에서는 [STATUS=10, CITY=Seoul, QTY=300]과 [STATUS=20, CITY=Busan, QTY=100]이라는 중복된 항목이 존재한다.

image-20191218214514258

위의 [그림 2]와 같은 테이블에서는 INSERT, DELETE, UPDATE 시에 이상 현상이 나타날 수 있다.

(1) INSERT anomaly

만약, [그림 2]의 테이블에 S5이라는 공급자가 London에 있다는 정보를 저장하고 싶다면, primary key의 구성 요소인 P#에 해당하는 필드에 dirty data를 입력해야 한다.

(2) DELETE anomaly

테이블에서 S3이라는 공급자가 더는 P2를 공급하지 않게 되어, S#이 S3에 해당하는 레코드를 삭제하면, S3이라는 공급자가 Busan에 있다는 정보까지 손실된다.

(3) UPDATE anomaly

테이블에서 S1이라는 공급자가 있는 도시를 Seoul에서 Paris로 변경하려면 총 3번의 update 연산이 필요하다. 즉, 하나의 정보를 변경하기 위해 불필요한 update 연산이 2번 더 실행되어야 한다.

  • [그림 1]의 테이블을 {S#, STATUS, CITY}, {S#, P#, QTY}로 이루어진 두 개의 테이블로 분해하여 1NF의 정의를 만족하는 새로운 테이블로 변경할 수 있다. 1NF의 정의를 만족하도록 분해한 새로운 테이블에서는 위에서 예시로 들은 anomaly가 발생하지 않는다.

3. Second Normal Form (2NF)

2NF는 1NF의 속성을 만족하면서, 테이블에 존재하는 모든 함수 종속 관계가 완전 함수 종속이어야 한다. 2NF를 정의할 때 이용되는 완전 함수 종속의 정의는 다음과 같다.

어떤 테이블 RR의 필드 YY가 필드의 집합 XX에 함수 종속이면서, XX 자신을 제외한 XX의 어떤 부분 집합에도 함수 종속이 아니면, YY는 XX에 완전 함수 종속이라고 한다.

예를 들어, [그림 1]의 테이블에서 primary key는 {S#, P#}이지만, CITY라는 필드는 {S#, P#}이 아니라 S#에 대해 함수 종속적이다. 따라서, [그림 1]의 테이블에는 완전 함수 종속이 아닌 함수 종속 관계가 존재하므로 2NF가 아니다. 위의 [그림 1]의 테이블을 2NF의 정의를 만족하도록 변형하면, 아래의 [그림 3]과 같이 SSC와 SPQ로 표현되는 두 개의 테이블로 분해할 수 있다.

image-20191218214801303

그러나 2NF의 정의를 만족하는 SSC와 SPQ 테이블에서도 다음과 같은 이상 현상이 발생한다.

(1) INSERT anomaly

SSC 테이블에는 "Paris라는 CITY의 STATUS는 40이다"라는 정보를 저장할 수 없다. SSC 테이블의 primary key는 S#이기 때문에 어떠한 도시의 상태에 대한 정보를 SSC 테이블에 저장할 수 없다. 또는, 해당 정보를 저장하기 위해서 S#에 dirty data를 추가해야 한다.

(2) DELETE anomaly

만약, SSC 테이블에서 두 공급자 S2와 S3가 제거되면, "Busan이라는 CITY의 STATUS는 20이다"라는 정보도 같이 손실된다.

(3) UPDATE anomlay

만약, Seoul이라는 CITY의 STATUS가 10에서 30으로 변경되면, SSC 테이블에서는 Seoul의 STATUS를 30으로 변경하는 작업을 1번이 아니라, 총 2번 수행해야 한다.

4. Third Normal Form (3NF)

2NF의 정의를 만족하면서, 어떠한 테이블에 존재하는 key가 아닌 필드들이 서로 독립적일 때 3NF라고 한다. 예를 들어, [그림 3]의 SSC 테이블에서 STATUS 필드는 테이블의 key가 아닌 CITY 필드에 함수 종속적이기 때문에 SSC 테이블은 3NF의 정의를 만족하지 못한다. 3NF의 정의를 만족하도록 [그림 3]의 SSC 테이블을 분해하면, 아래의 [그림 4]와 같다.

image-20191218214940133

위의 [그림 3]의 SSC 테이블에서는 key가 아닌 CITY에 STATUS가 종속적이었지만, [그림 4]의 SC와 CS 테이블에서는 key가 아닌 필드 사이에 어떠한 종속 관계도 존재하지 않는 것을 볼 수 있다.

5. Boyce-Codd Normal Form (BCNF)

image-20191218215023018

위의 [그림 5]는 BCNF의 정의를 만족하지 않는 테이블을 보여준다. [그림 5]의 테이블에서 candidate key는 {STD#, COURSE}이다. 따라서, {STD#, COURSE}를 통해 하나의 레코드를 유일하게 구별할 수 있다.

그러나 테이블 SCT에는 TEACHER에 의해 COURSE가 결정되는 함수 종속 관계가 존재한다. 즉, determinant가 candidate key에 해당하지 않는 함수 종속 관계가 존재하기 때문에 테이블 SCT는 BCNF의 정의를 만족하지 않는다. 이러한 테이블 SCT를 BCNF의 정의를 만족하도록 변경하면, 테이블 SCT는 아래의 [그림 6]과 같은 두 개의 테이블로 변환된다.

image-20191218215045120

위의 [그림 6]에서 함수 종속 관계는 테이블 TC에서만 존재하며, determinant에 해당하는 것은 TEACHER로써, 테이블 TC의 candidate key에 해당한다. 따라서, [그림 6]의 두 테이블은 BCNF의 정의를 만족한다.

6. Fourth Normal Form (4NF)

4NF는 MVD (multivalued dependency)라는 개념을 통해 정의된다. MVD는 functional dependency의 일반화된 개념으로써, functional dependency에서는 determinant X에 의해 Y의 값이 하나만 결정되었다면, MVD에서는 determinant X에 의해 다수의 Y값이 결정된다. 위와 같은 MVD 관계는 X →→ Y로 표기한다.

MVD는 trivial MVD와 nontrivial MVD로 구분된다. 각각의 정의는 아래와 같다. 또한, 이 글에서 4NF를 정의하기 위해 언급되는 MVD는 모두 아래의 nontrivial MVD를 의미한다.

  • trivial MVD: Y가 X의 부분집합이거나, X와 Y를 합한 것이 테이블 그 자체인 경우 (X ∪ Y = R)
  • nontrivial MVD: 위에서 정의된 trivial MVD가 아닌 모든 MVD

만약, 어떠한 테이블 R에 존재하는 필드 A와 B가 A →→ B이면, R에 존재하는 다른 모든 필드가 A에 의해 functional dependent하게 값이 결정될 때, 4NF라고 한다. 예를 들어, 테이블 R(A, B, C, D)에 대해 A →→ B일 때, A → C 이고 A → D이면 R은 4NF의 정의를 만족한다고 할 수 있다.

아래의 [그림 7]과 같이 COURSE와 MVD 관계를 갖는 두 개의 필드를 포함하는 정보가 있다. 두 개의 필드는 각각 COURSE 필드의 값에 의해 값이 결정되며, 하나의 COURSE 값에 대해 다수의 TEACHER와 TEXT 값이 존재할 수 있다.

image-20191218215153706

위의 [그림 8]의 테이블 CTT에서 Data Structure를 가르치는 사람이 변경되면, 하나가 아니라, 총 세 개의 레코드를 변경해야 하는 UPDATE anomaly가 발생한다. 이러한 UPDATE anomaly를 해결하기 위해서는 [그림 8]의 테이블을 4NF의 정의를 만족하도록 변경하는 것이 필요하다. 테이블 CTT를 4NF의 정의에 맞도록 분할하면, [그림 9]의 두 테이블, CT1과 CT2로 변경된다.

image-20191218215219745

위의 [그림 8]의 테이블 CTT를 [그림 9]의 두 테이블 CT1과 CT2로 분할하면, Data Structure를 가르치는 사람을 변경할 때, 더는 UPDATE anomaly가 발생하지 않는다.

반응형

'프로그래밍 언어 > [ DB ]' 카테고리의 다른 글

[ DB ] 03. SQLite의 이야기와 질의(Query)  (0) 2021.01.08
[ DB ] 02. SQLite3 with C/C++ (기본편)  (0) 2020.11.06
[ DB ] 01. SQL  (2) 2020.08.10