Database

정규화와 반정규화 및 대량 데이터에 따른 성능

천방지축 개발노트 2020. 9. 8. 20:24


정규화(Normalization) 특징

불필요한 중복으로 인한 이상(Anomaly)현상을 방지하기위한 정규화는 데이터베이스 모델링에서 매우 중요한 프로세스이다. 이와 관련하여 로우체이닝(Row Chaining)과 로우마이그레이션(Row Migration), 파티셔닝(Partitioning) 및 반정규화에 대한 특징을 비교하며 이해해야 합니다.

정규화


1) 데이터 모델링을 하면서 정규화를 하는 것은 기본적으로 데이터에 대한 중복성을 제거하여 주고 데이터가 관심사별로 처리되는 경우가 많기 때문에 성능이 향상되는 특징을 가지고 있다.


2) 정규화를 수행한다는 것은 데이터를 결정하는 결정자에 의해 함수적 종속을 가지고 있는 일반속성을 의존자로 하여 입력/수정/삭제 이상을 제거하는 것이다. 데이터의 중복속성을 제거하고 결정자에 의해 동일한 의미의 일반속성이 하나의 테이블로 집약되므로 한 테이블의 데이터 용량이 최소화되는 효과가 있다. 따라서 정규화된 테이블은 데이터를 처리할 때 속도가 빨라질 수도 있고 느려질 수도 있는 특성이 있다.


데이터베이스에서 데이터를 처리할 때 성능이라고 하면 ①조회성능과 ②입력/수정/삭제 성능. 두 부류로 구분된다. 두 성능 모두 우수하면 좋겠지만, 방식에 따라 두 성능이 반비례하는 경우가 많다.

→ SQL문장에서 join이 많이 발생해 성능 저하가 나타나는 경우도 있지만, 그렇다고 반정규화만이 조회 성능을 향상시킨다는 건 아니다. 아닌 경우도 많음.




반정규화(De-Normalization) 특징

정규화된 엔티티, 속성, 관계에 대해 시스템의 성능향상과 개발 및 운영의 단순화를 위해 중복, 통합, 분리 등을 수행하는 데이터 모델링의 기법을 의미.

반정규화


1) 중복성의 원리를 활용하여 데이터 조회 시 성능을 향상시키는 역할을 할 수 있음.

2) 데이터의 무결성이 깨질 위험이 있지만 디스크 I/O량이 많아 성능저하가 예상될 때 수행함.

(반정규화를 하면 무결성이 깨진다는 것이 아니라, 가능성이 있기 때문에 반드시 무결성을 보장할 수 있는 방법을 고려해서 적용해야 함)




대량의 데이터에 따른 테이블 분할

한 테이블에 데이터가 대량으로 집중되거나, 여러 개의 칼럼이 존재하여 디스크에 많은 블록을 점유하는 경우는 모두 성능저하를 유발할 수 있다. (칼럼은 물리적인 디스크에 여러 블록에 나뉘어 저장됨. 따라서 칼럼이 많아지게 되면 데이터를 I/O할 때, SQL문장의 성능이 저하될 수도 있음)

→ 왜냐면 한 테이블에 데이터가 많아지면 Index Tree구조(Index의 크기(용량))가 커지게 되고, 따라서 데이터를 처리(입력, 수정, 삭제, 조회)하기 위한 디스크(I/O)의 양이 많아지는 것임. 즉, 성능이 저하되는 것임.


※위 내용은 한번의 I/O 요청에 한 블록씩 데이터를 읽는 Index Scan 방식의 경우임. 반대로, Full Table Scan은 데이터를 읽을 때 한번의 I/O 요청으로 여러 블록을 한꺼번에 읽음. 즉, 하나의 테이블에 데이터가 많다고 해서(JOIN을 덜 한다고 해서) I/O양이 적어지는 것은 아님.

디스크에 데이터 저장 개념디스크에 데이터 저장 개념

1) 로우체이닝(Row Chaining)

로우의 길이가 너무 길어서 데이터 블록 하나에 데이터를 모두 저장하지 않고 두 개 이상의 블록에 걸쳐서 하나의 로우가 저장되는 형태.


2) 로우마이그레이션(Row Migration)

데이터 블록에서 수정이 발생하면 수정된 데이터를 해당 데이터블록에 저장하지 못하고 다른 블록의 빈 공간을 찾아 저장하는 방식.




파티셔닝(Partitioning)

테이블에 많은 양의 데이터가 예상될 경우 파티셔닝을 적용하거나 PK에 의해 테이블을 분할하는 방법을 적용할 수 있다. Oracle의 경우 크게 LIST PARTITION(특정값 지정), RANGE PARTITION(범위), HASH PARTITION(해쉬적용), COMPOSITE PARTITION(범위와 해쉬가 복합) 등이 가능하다. 데이터량이 몇 천만건을 넘어서면 아무리 서버사양이 훌륭하고 인덱스를 잘 생성해준다고 하더라고 SQL문장의 성능이 나오지 않는다. 이 때는 논리적으로는 하나의 테이블로 보이지만 물리적으로 여러 개의 테이블스페이스에 쪼개어 저장될 수 있는 구조의 파티셔닝을 적용하도록 한다.


① Range Partition : 범위, 날짜or 숫자값으로 테이블 분할. 데이터보관주기에 따라 테이블의 데이터 지우기 가능.

② List Partition : 특정값에 따라 분리 저장, 보관주기에 따라 테이블의 데이터 지우기는 불가능.

③ Hash Partition : 해쉬 적용, Hashing알고리즘이 적용되어 테이블이 분리되며, 설계자는 테이블에 데이터가 어떻게 들어갔는지 알 수 없음.

④ Composite Partition : 범위와 해쉬가 복합.