- 데이터의 중복을 줄이고, 데이터 무결성을 높이는 데이터 베이스 설계 방법
- 데이터의 저장 효율성을 높이고, 데이터의 일관성을 유지할 수 있다.
- 모든 열이 원자값을 가진다.
- 중복된 데이터가 없어야 한다.
- 1정규형에서 부분 종속성을 제거
- 기본 키의 일부가 다른 열을 결정하지 않아야 한다.
- 제2 정규형에서 이행 종속성을 제거
- A->B->C일 때, A->C 관계를 제거
- 제3 정규형에서 모든 결정자가 후보 키가 되도록 한다.
- 결정자가 비 후보 키에 의존하지 않아야 한다.
제4 정규형, 제5 정규형도 있다.
정규화 단계를 적용할수록 데이터의 중복을 최소화하고, 무결성을 높일 수 있다.
하지만 정규화가 반드시 필요한 것은 아니며, 정규화가 장점만 있는 것도 아니다. 상황에 맞게 적절한 정규화를 적용하는 것이 중요하다.
- 중복 방지 : 데이터 중복을 줄일 수 있다. 이로 인해, 저장 공간을 절약할 수 있다.
- 일관성 : 데이터 수정 시 하나의 데이터만 수정하면 되기 때문에, 데이터 일관성이 유지된다.
- 무결성 : 정규화된 테이블 구조는 참조 무결성과 같은 무결성 제약 조건을 쉽게 적용할 수 있어 무결성을 보장한다.
- 정규화된 구조는 간단하고 체계적이라 설계와 유지보수가 용이하다.
- 정규화 과정에서 데이터가 여러 테이블로 분산되면서, 데이터를 조회할 때 다수의 테이블을 조인해야 하는 경우 성능 저하가 발생되고 쿼리가 복잡해진다. 데이터베이스 규모가 클수록 대규모 데이터를 빠르게 처리하기 위해 비정규화 데이터베이스나 NoSQL 데이터베이스를 사용하는 것이 더 좋을 수 있다.
- 구조가 정규화되면, 새로운 요구사항에 맞춰 데이터를 변경하기가 어렵고 유연성이 떨어질 수 있다.
정규화와 반대로 정규화된 테이블을 결합하거나 중복된 데이터를 허용하는 방법. 데이터베이스의 성능과 접근성을 향상시키기 위해 사용된다.
- 필요한 데이터를 하나의 테이블에 모다 두고 조회를 하면 응답 시간이 빨라지고 시스템의 전체 성능이 향상될 수 있다.
- 읽기 전용 시스템에서는 데이터 일관성 유지가 덜 중요하다. 비정규화를 통해 데이터 조회 성능은 향상시키고, 일관성이 떨어지지는 않는다.
- 하나의 행에서 모든 데이터를 조회할 수 있어 쿼리 작성이 간단해진다.
- 데이터 중복 저장으로 저장 공간이 더 많이 필요하고 중복된 데이터를 관리하는 어려움이 생길 수 있다.
- 중복된 데이터는 여러 포인트에서 업데이트되어 데이터 일관성을 유지하기 힘들 수 있다. 같은 기능을 하는 중복된 데이터들 중 하나만 업데이트되지 않아도 데이터 불일치 문제가 생길 수 있다.
- 데이터 무결성을 유지하기 위한 제약 조건을 적용하기 어렵다.
- 변경 사항이 발생할 때 더 많은 업데이트가 필요해 유지보수 비용이 증가할 수 있다.
데이터 중복을 피하기 위해 JSON 형식으로 배열을 사용할 수 있다.
| PlayerId | Name | Inventory |
|---|---|---|
| 101 | 호호아저씨 | 황금방패 |
| 101 | 호호아저씨 | 먹다남은음식 |
⬇️
| PlayerId | Name | Inventory |
|---|---|---|
| 101 | 호호아저씨 | [황금방패, 먹다남은음식] |
비정규형
PlayerId Name Class Inventory Stat 101 호호아저씨 전사 황금방패, 먹다남은음식 힘:15, 민첩:5, 지능:5 102 팥죽할멈 마법사 지팡이, 팥죽, 설탕 힘:5, 민접:5, 지능:15 103 뉴삐 도적 나이프 힘:5, 민첩:10, 지능:15
제1 정규형
원자값을 갖지 않는 Inventory, Stat열을 별도 테이블로 분리
PlayerId Name Class 101 호호아저씨 전사 102 팥죽할멈 마법사 103 뉴삐 도적
PlayerId Inventory 101 황금방패 101 먹다남은음식 102 지팡이 102 팥죽 102 설탕 103 나이프
PlayerId Str Dex Int 101 15 5 5 102 5 5 15 103 5 10 5
제2 정규형
부분종속성을 가지는 Class 분리
PlayerId Name 101 호호아저씨 102 팥죽할멈 103 뉴삐
ClassId Class 201 전사 202 궁수 203 마법사 204 도적
PlayerId ClassId 101 201 102 203 103 204
이행 종속성이 없기때문에 3 정규화는 안 함.
두 단계 정규화 후 총 다섯개의 테이블이 됨.
비정규화 테이블에서는 호호아저씨의 직업을 바로 알 수 있지만
정규화 테이블에서는 조인을 통해 호호아저씨의 PlayerId(101)를 알아내고 PlayerId(101)의 ClassId(201)를 알아내고 ClassId(201)의 Class(전사)를 알아내야 한다.
조회를 빈번하게 한다면 비정규화가 더 좋고 조회를 가끔하고 정확성과 일관성 유지가 중요하다면 정규화가 더 좋다.
중복된 데이터가 많으면 여러 지점에서 수정을 할 수 있고 데이터 불일치가 발생할 수 있다. 이를 최소화하기 위해 정규화를 하는 것이다.
하지만 정규화를 많이 하면 테이블이 많이 생기고 조인 연산이 복잡해져서 응답 시간이 길어져 읽기 성능이 저하된다.
요컨대, JOIN이 많이 일어나는 쿼리는 안 좋다는 것.
정규화의 단점을 극복하기 위한 방법으로는 비정규화가 아닌 NoSQL을 많이 사용한다.
NoSQL은 유연성있는 스키마리스 데이터베이스를 의미한다.
데이터베이스 사양을 높여 성능을 커버할 수는 있지만, Scale-up은 비용이 기하급수적으로 증가하고 Scale-out은 유연성이 떨어진다. 반면에 NoSQL은 Scale-out이 유연하고 간편하다.