도당탕탕
Effective-SQL Better-Way-8 : 제 3정규화로도 부족하다면 더 정규화 하자 본문
여기 흔히 떠도는 말로 대부분의 애플리케이션은 제 3정규화만 해도 충분하다.
가 있습니다. 많은 실무자, 현업자들은 일단 최대한 정규화한 후 애플리케이션이 제대로 돌아갈 때까지 역정규화하라고 말을 합니다. 사실 이 말들은 맞습니다. 대부분의 데이터 모델에서 이미 제 3정규화를 거친 엔티티는 더 높은 수준의 정규화를 만족할 가능성이 크기 때문입니다. 실제로 현재 많은 데이터베이스에서 이미 5정규화 6정규화 까지 도달해 있는데도 사람들은 이를 제 3정규화라고 칭합니다.
그렇다면?
우리는 어떻게 해야 할까요? 드물기는 하지만 제 3정규화를 만족하는 것처럼 보이더라도 데이터 이상 현상을 일으키는 설계 실수를 찾아야 합니다. 특히 제 3정규화로 설계했지만, 한 테이블이 다른 테이블 두 개 이상과 관계를 맺는다면 더 높은 정규화 형식을 위반할 수 있으므로 주의해야 합니다.
- 첫 번째로 다대다 관계에서는 더 주의해야 합니다.
- 두 번째로 테이블에 더 높은 정규화 형식을 위반할 수 있는 복합키가 있을 때도 마찬가지입니다.
- 마지막 세 번째로는 대리키를 사용하고 대리키 대신 자연키를 분석할 때는 각별히 주의가 필요합니다.
결론부터 말하면 제 1,2,3 정규화 형식은 관계의 속성 중 기능적 의존성이 있는 속성과 관련되었다고 할 수 있습니다. 기능적 의존성은 해당 속성이 관계를 이루는 키에 의존함을 의미합니다. 예를 들어 한 개의 전화번호가 A의 것이라면 이 번호는 A가 들어있는 컬럼에 기능적으로 의존하며, 다른 속성들의 컬럼은 그 두 개의 컬럼에 영향을 주지 않는다고 할 수 있습니다. 즉 전화번호가 다른 속성 컬럼에 의존한다면 이상이 발생할 것입니다.
제 4정규화
그럼 제 4정규화는 어떻게 할까요? 제 4정규화 형식은 다치 종속과 관련되어 있습니다. 다치 종속이란 말은 무엇일까요? 위키에 이렇게 설명되어 있습니다.
다치 종속은 릴레이션 내의 두 어트리뷰트 집합 사이 성립하는 제약조건 중 하나이다.
저 말이 무슨 말일까요? 예를 들면 테이블 X, Y가 있습니다. X의 여러개 속성값들이 Y의 여러 속성값들에 대응하고 반대로 해도 서로 대응하면 (다대다) Y는 X의 다치 종속이라고 말할 수 있습니다.
하지만 제 4정규화 형식을 위반할 수 있는 특수한 경우가 있습니다. 다음 예를 들어보죠.
| sales_person | menufacturer | product |
--------------------------------------------------------
| Lee | ACE | single-bed |
| Lee | ACE | queen-bed |
| Lee | Apple | phone |
| Lee | Apple | tablet |
| Kim | Samsung | phone |
| Kim | Samsung | laptop |
비즈니스 규칙
- 제조업자는 두 개의 제품만 생산 및 판매를 할 수 있다.
여기서 park이라는 사원이 ACE의 물건을 판다고 하면 데이터 갱신을 해야 하는데 이 과정에서 제대로 갱신을 못 하면 데이터 이상이 올 수 있습니다. 이런 오류를 피하려면 다음과 같이 분할 해야 합니다.
해당 다이어그램은 SalesPeopleManufacturer, ManufacturerProduct 라는 다대다 관계의 테이블이 존재합니다. 이렇게 구조를 하면 좋은 점은 다음과 같습니다.
- SalesPerson, Manafacturer, Product 세 개의 테이블은 서로 독립적이다.
- 다대다 테이블을 조인하여 자유롭게 데이터를 추출 할 수 있는 장점이 있다. 즉 필요한 데이터를 자유롭게 추출할 수 있다.
이와 같은 이유로 위의 예제가 훨씬 좋아 보입니다. 하지만 우리는 간과한 사실이 있습니다. 바로 제조업자는 두 개의 제품만 생산 및 판매를 할 수 있다
라는 비즈니스 규칙입니다. 이 규칙을 보면 해당 표는 제 4정규화를 위반하지 않습니다. 즉 대부분의 비즈니스 규칙 때문에, 데이터 모델은 더 높은 정규화 형식을 사용하지 않고 만족하면서 사용하고 있습니다.
제 5정규화
제 5정규화는 후보키가 모든 조인 의존성을 함축해야 합니다. 다음 예는 의사가 특정 장비로 검사할 수 있는 검사실 예약 표입니다.
| office | doctor | equipment |
----------------------------------------
| A | kim | x-ray |
| A | kim | scanner |
| A | Lee | MRI |
| B | Lee | scanner |
| B | Lee | MRI |
| C | Park | x-ray |
| A | Park | x-ray |
| A | kim | scanner |
비즈니스 규칙
- 의사는 해당 장비를 다루는 교육을 이미 받았다. 그렇기에 장비 사용 자격이 없는 검사실로 의사를 보내지 않는다.
위에 표를 보면 검사실 위치와 검사 장비를 알 수 있습니다. 겹치는 항목이 있긴 하지만 모두 독립적입니다. 또한, 비즈니스 규칙에 따라 의사는 배정받은 방의 장비를 다룰 수 있기 때문에 다음과 같은 그림으로 나타낼 수 있을 것 같습니다.
이 그림은 Doctors, Equipment, Offices와 각각의 다대다 테이블을 만든 다이어그램입니다. 이 그림을 통해 새 검사실이 생기거나 기존 검사실에 새 장비가 들어오거나 의사가 받는 교육 내용이 바뀌더라도 이 요소는 모두 독립적이며, 다대다 테이블에도 이상이 발생하지 않습니다.
하지만 의사가 해당 장비 사용에 필요한 교육을 받지 못했거나 검사실에 장비가 부족하다면 어떻게 해야 할까요? 위와 같은 구조에서는 DoctorSchedule 테이블에 문제가 생길 것입니다. 만약 이를 해결하기 위해서는 다음 예의 구조로 바뀌어야 할 것 같습니다.
위 구조는 테이블 설계를 변경하지 않고 관계만 변경한 다이어그램입니다. 이렇게 관계를 맺음으로써 어느 특정 장비에서는 유효한 의사와 검사실 조합만 선택할 수 있도록 보장할 수 있습니다.
하지만 우리는 또 하나의 사실을 간과하고 있습니다. 바로 비즈니스 규칙입니다. 의사는 해당 장비를 다루는 교육을 이미 받았다. 그렇기에 장비 사용 자격이 없는 검사실로 의사를 보내지 않는다.
이 규칙을 통해 DoctorSchedule 테이블에 equipment_id 컬럼이 필요하지 않을 것입니다. 단지 의사를 검사실에 예약만 하면 됩니다.
무손실 분할
더 높은 정규화 형식을 위반하는지 분석할 때 사용할 수 있는 방법의 하나는 무손실 분할입니다. 이 말은 테이블에 컬럼이 많으면 일련의 부분 집합으로 분할 해야 한다는 뜻입니다.
예를 들어 SELECT DISTINCT
문을 수행한 후 LEFT OUTER JOIN
을 사용해 다시 조인한 결과가 원래 테이블 결과와 동일한지 확인해 보는 것입니다. 만약 분할한 테이블을 조인으로 재결합한 결과, 데이터 손실이 없다면 원본 테이블은 일부 정규화 형식을 위반한 것이므로 다시 봐야 할 것입니다.
여기까지 제 3정규화로도 부족하다면 더 정규화 하자에 대해 알아봤습니다. 다음에는 데이터 웨어하우스에는 역정규화를 사용 하자에 관해 보겠습니다.
'Database' 카테고리의 다른 글
DB 용어 정리 (0) | 2020.09.11 |
---|---|
Effective-SQL Better-Way-9 : 데이터 웨어하우스에는 역정규화를 사용하자 (3) | 2020.09.06 |
Effective-SQL Better-Way-7 :테이블 간 관계를 명확히 하자 (0) | 2020.09.04 |
Effective-SQL Better-Way-6 : 참조 무결성을 보호하려면 외래키를 정의하자 (0) | 2020.09.04 |
Effective-SQL Better-Way-5 : 왜 계산 데이터를 저장하면 좋지 않은지 이해하자 (0) | 2020.09.03 |