티스토리 뷰



관계형 데이터베이스의 설계에서 중복을 최소한으로 만들게끔 설계하는 방법을 '정규화'라고 합니다. 그럼 정규화는 왜 필요한 걸까요?

데이터베이스의 기본적인 목적은 작게 구성된 조직된 데이터 셋을 만드는데 있습니다. 하지만 데이터들을 저장할 때 이러한 개념을 무시한 채 사용자가 원하는데로 담게 된다면 사용자는 원하는 데이터를 찾기 어렵거나, SQL문이 복잡해지는 문제점을 가지게 될 것입니다. 


복잡한 테이블에서 데이터를 가지고오기 위해서는 Where의 절이 점점 복잡해지는 경향이 있습니다.


이러한 문제를 해결하기 위해서도 반드시 정규화 과정은 거쳐야 합니다. 위키피디아에서 정의하고 있는 정규화는 아래와 같습니다.


관계형 데이터베이스의 설계에서 중복을 최소화하게 데이터를 구조화하는 프로세스를 정규화라고 한다. 데이터베이스 정규화의 목표는 이상이 있는 관계를 재구성하여 작고 잘 조직된 관계를 생성하는 것에 있다. 일반적으로 정규화란 크고, 제대로 조직되지 않은 테이블들과 관계들을 작고 잘 조직된 테이블과 관계들로 나누는 것을 포함한다. 정규화의 목적은 하나의 테이블에서의 데이터의 삽입, 삭제, 변경이 정의된 관계들로 인하여 데이터베이스의 나머지 부분들로 전파되게 하는 것이다.


관계형 모델의 발견자인 에드거 F. 커드는 1970년에 제 1 정규화(1NF)로 알려진 정규화의 개념을 도입하였다.에드거 F. 커드는 이어서 제 2 정규화(2NF)와 제 3 정규화(3NF)를 1971년에 정의하였으며, 1974년에는 레이먼드 F. 보이스와 함께 보이스-코드 정규화(BCNF)를 정의하였다.[3] 4NF 이상의 정규화는 이후에 다른 이론가들에 의해서 정의되었으며, 가장 최근에 소개된 정규화는 2002년에 크리스토퍼 J. 데이트, 허그 다위, 니코스 로렌츠에 의해 소개된 제 6 정규화(6NF) 이다.


비공식적으로 관계형 데이터베이스 테이블(컴퓨터 공학적 표현으로는 관계)가 제 3 정규(3NF)화가 되었으면 정규화 되었다 라고 한다. 3NF 테이블의 대부분이 삽입, 변경, 삭제 이상이 없으며, 3NF 테이블의 대부분이 BCNF, 4NF, 5NF이다.(그러나 일반적으로 6NF는 아니다.)


데이터베이스 디자인 표준 가이드는 데이터베이스가 완전히 정규화되게 디자인되어야 한다; 그 뒤에 일부가 성능상의 이유로 비정규화될 수는 있다.그러나, 데이터 웨어하우스 디자인을 위한 관점 모델링 과 같은 일부 모델링 규칙에서는 예외적으로 비 정규화된 디자인을 추천한다. 즉 대규모 부분에서의 디자인은 3NF가 아니다.


<참조 : 위키피디아>


정규화는 위에서 보았듯이 제 1정규화, 제 2정규화, 제 3정규화 등으로 구분이 됩니다. 정규화의 레벨이 위로 올라가면 올라 갈 수록 조건이 까다로워지는 경향이 있습니다. 이 글에서는 정규화를 하는 이유와 제 1정규화(1NF)에 대해서 설명을 드리도록 하겠습니다.


1. 정규화를 하는 이유


RDBMS에서 테이블 설계할 때는 여러 테이블 사이의 열들이 서로 어떠한 관계에 있는지를 고려해야 합니다. 적절한 열들을 사용해서 원하는 정보를 쉽게 찾을 수 있도록 정보를 표현하는 것이 쉽지는 않습니다. 이를 위해서는 테이블을 생성할 때 대략 다음의 과정을 거치게 됩니다.


1. 테이블로 표현하려는 것을 선택합니다.

2. 테이블을 사용하여 얻어야 하는 정보들의 리스트를 작성합니다.

3. 어덯게 하면 가장 쉽게 쿼리를 할 수 있을것인가를 고려하면서, 리스트를 이용하여 테이블을 만들 정보들의 조각으로 나눕니다. 


위의 3가지 과정에서 효율적인 처리를 위해서 데이터베이스는 원자적(Atomic) 해야 합니다. 원자적 데이터라는 의미는 쪼갤 수 없는 가장 작은 조각으로 데이터가 쪼개졌다는 의미가 됩니다. 


피자 배달원에게는 배달지에 대한 전체 주소가 원자적이지만, 다음지도와 같은 지도에서는 특정 위치를 판단하기 위해서 동, 번지등이 다 구분이 되어있어야 원자적이라고 할 수 있을 것입니다. 즉 데이터가 원자적이라는 의미는 사용에 편리하게끔 적절하게 쪼개어진건가를 판단하면 됩니다. 


원자적 데이터는 테이블 내의 데이터를 정확히 나타내는데 도움이 됩니다. 원자적 데이터를 사용하면 쿼리 작성이 쉬워지고 수행시간이 빨리 쿼리를 효율적으로 처리할 수 있는 장점을 가지게 됩니다. 원자적 데이터는 아래와 같은 특성을 가집니다.


  • 원자적 데이터로 구성된 열은 그 열에 같은 타입의 데이터를 여러개 가질 수 없다.
  • 원자적 데이터로 구성된 테이블은 같은 타입의 데이터를 여러열에 가질 수 없다.


아래와 같은 데이터베이스 테이블이 있다고 과정을 하겠습니다. 


정규화와 원자적 데이터에 대한 고려가 전혀 되어 있지 않습니다. 생김새를 통해서 사람의 이름을 찾고자 할 때 이 테이블은 Where 절에서 like에 대한 구문을 이용해야 할 것입니다. 이는 효율적이지도 않을 뿐더러, 정확한 데이터를 찾아내는 데 많은 테스트를 거쳐야 하는 문제도 가지고 있습니다. 



이를 원자적을 만든다면 어떻게 할 수 있을 까요? 생김새의 부분의 ,를 없애면 될것입니다. 원자적인 데이터로 만들어 보았습니다. 


테이블은 원자적으로 만드는 것은 테이블을 정규화(Normalization) 하는 첫 단계입니다. 테이블을 정규화 한다는 의미는 앞에서 설명한 것과 같이 테이블들이 표준에 대한 규칙을 따르게 한다는 뜻입니다. 이는 같이 작업을 하는 사용자 혹은 개발자들이 테이블을 이해하기가 더 쉬워지는 것을 의미합니다. 


정규화를 통해서 테이블을 설계하면 아래와 같은 이점을 가지게 됩니다.


  • 정규 테이블은 중복 데이터가 없어 데이터 베이스 크기를 줄입니다.
  • 찾아야 할 데이터가 적어 쿼리의 속도가 빨라집니다.


2. 정규화를 하는 방법


원자성과 정규화의 공통적인 장점은 쿼리의 속도가 빨라진다는 것에 있습니다. 간단한 쿼리가 아닌 복잡한 쿼리에 대한 속도가 빨라지는 것은 데이터베이스를 이용해 프로그램을 개발하는 개발자에게도, 실제 사용하는 사용자에게도 큰 이점이 될 수가 있습니다. 따라서 설계자는 이러한 이점을 제공하기 위해서라도 이에 대한 처리 상황이 반드시 필요하게 되는것입니다. 


그럼 정규화는 어떻게 할 수 있는건가요? 정규화는 각각의 과정을 거쳐서 제 1정규화, 제 2정규화, 제3 정규화 등등으로 이루어집니다. 정규화 과정을 차트로 나타내면 아래의 그림과 같습니다. 



이 글에서는 제 1정규화에 대한 내용만 다룰 것입니다. 제 1정규화를 하기 위해서는 어떻게 진행을 해야 할까요?

1NF를 하기 위해서는 다음의 두개의 규칙을 만족해야 합니다. 


  • 각 행의 데이터들은 원자적 값을 가져야 한다.
  • 각 행의 유일무이한 식별자인 기본키(Primary Key)를 가지고 있어야 한다. 


원자적 데이터에 대한 내용은 위에서 다루었습니다. 그럼 기본키란 무엇일까요?

데이터베이스에서 기본키란 각 레코드(행)을 식별하는데 사용되는 유일무이한 데이터 값입니다. 절대 중복이 발생해서는 안되는 데이터입니다. 사람을 예로 들자면 주민등록번호가 될 수 있을것이고, 책을 예로 들자면 바코드가 기본키가 될 수 있을 겁니다.


기본키의 특징은 아래와 같습니다.


  • 기본키는 Null이 될 수 없습니다.
  • 기본키는 레코드가 삽일 될 때 값이 있어야 합니다.
  • 기본키는 간결해야 합니다.
  • 기본키의 값은 변경이 불가능합니다.


기본키를 만드는 가장 좋은 방법은 기본키를 위한 새로운 열을 만드는 것입니다. 이전 자료에서 Select, Delete 구문을 공부하기 위해서 사용했던 테이블을 다시 보도록 하겠습니다. 관련 링크는 아래와 같습니다. 



테이블은 충분히 원자적이지만 데이터를 구분할 수 있는 Primary Key는 없습니다. 



기본 키를 추가하기 위해서 Alter Table을 통해서 테이블에 추가적인 열을 넣어보도록 하겠습니다. 


ALTER TABLE CONTACTS_TABLE add Contact_ID int NOT NULL IDENTITY(1,1) PRIMARY KEY


위의 구문을 간략히 해석해 보겠습니다.

  • ALTER TABLE CONTACTS_TABLE add Contact_ID int : CONTACTS_TABLE에 Contact_ID라는 Int 값을 가지는 열을 추가합니다.
  • NOT NULL : 이 열의 값은 Null이 될수 없습니다.
  • IDENTITY(1, 1) : 이 열의 값은 첫번째 값이 1이며, Row가 증가할 때마다 1씩 증가하는 값을 자동적으로 가지게 됩니다.
  • PRIMARY KEY :  이 열을 기본키로 지정을 합니다.

구문을 실행하고 테이블을 Select 해보면 Contact_ID는 따로 값을 넣지 않았음에도 불구하고 1~8까지 자동으로 추가가 된것을 확인할 수 있습니다. 



이제 테이블에는 기본키가 생겼습니다. 그럼 기본키를 임의의 값을 가지는 행을 삽입해보도록 하겠습니다. 5의 ID를 가지는 행을 삽입하게 되면 IDENTITY가 활성화가 되어 있어 마지막 5값을 넣지 못한다는 에러가 뜹니다. 이 말은 Contact_ID는 사용자가 원하는 값을 넣지 못한다는 의미가 됩니다. 



그럼 5를 지우고 데이터를 넣어 보겠습니다. 



문제없이 데이터를 넣을 수 있음을 확인하였습니다. 

물론 Primary Key를 기본적으로 값이 증가하게끔 만들지 않아도 됩니다. 하지만 이렇게 만들어 놓으면 사용자는 기본키에 대해 많은 신경을 쓰지 않고 테이블을 관리할 수 있다는 이점을 가질 수 있습니다.


이 글에서는 왜 정규화를 해야 하는지와 정규화를 하는 방법에 대해서 알아보았습니다. 간략히 정리를 하자면 정규화는 쿼리의 속도와 데이터 터베이스의 크기에 대한 이점을 가지기 위해서 합니다. 제 1정규화를 하기 위해서는 테이블의 데이터가 원자적이어야 하고, 기본키를 가지고 있어야 한다고 알려드렸습니다.


이 글이 도움이 되셨나요?

그렇다면 아래의 그림을 클릭해주세요.



댓글