이전 글에 이어서 데이터베이스 반정규화에 대해 정리한다
정규화 단계를 거치면서 데이터 중복과 같은 이상현상을 줄이고자 릴레이션을 분리하였다
릴레이션을 분리함으로써 데이터를 저장하는 테이블을 분리하였는데, 이 과정은 쉽게 말하면
쓰기 비용을 줄이면서 읽기 비용을 지불했다고 볼 수 있다 (정규화 단계에 따라 읽기 비용도 줄일 수 있다)
따라서 정규화를 통해 정규형 등급을 높이는 것은 항상 해답이 될 수 없다
이러한 이유로 다시 릴레이션을 합치는 반정규화과정이 존재한다
반정규화란?
- 정규화된 관계에 대해 시스템의 성능향상, 개발 운영에서의 단순화를 위해 중복, 통합, 분리 기법을 수행하여 데이터 모델링을 하는 기법
반정규화를 적용하면 데이터 무결성이 깨질 수 있는 위험이 있음
반정규화도 데이터베이스의 성능을 높이기 위해 이루어지는 작업이다
정규화와 마찬가지로 쓰기 비용을 올리고 읽기 비용을 줄이는 방법이다 따라서 어떤 비용을 줄이기 위해선 항상 트레이드오프가 존재한다
그렇다면 어떤 상황에 반정규화를 고려해 보는 것이 좋을까?
- 여러 개의 조인을 통해 데이터를 가져오는 상황에 만약 업무적으로 조회에 대한 처리 성능이 중요하다고 판단될 때
- 정규화의 함수적 종속관계는 위반하지 않지만 데이터의 중복성을 증가시켜야만 데이터조회의 성능을 향상하는 경우
- 기본키의 부분집합이 결정자가 되지 않는 선에서 데이터 중복 컬럼을 추가
하지만 설계단계에서 반정규화를 기술적으로 수행하지 않는 경우에는 다음과 같은 현상이 발생된다
- 성능이 저하된 데이터베이스가 생성될 수 있다
- 구축단계나 시험단계에서 반정규화를 적용할 때 수정에 따른 노력비용이 많이 들게 된다
반정규화 적용 방법
무분별한 반정규화는 데이터의 무결성을 깨뜨리는 결정적인 역할을 할 수 있다
반정규화에 대한 필요성이 결정이 되면 칼럼의 반정규화 뿐만 아니라 테이블의 반정규화와 관계의 반정규화를 종합적으로 고려하여 적용해야 한다
또한 반정규화를 막연하게 중복을 유도하는 것만을 수행하기보다는 성능을 향상시킬 수 있는 다른 방법들을 고려하고 그 이후에 반정규화를 적용하도록 해야 한다
- 반정규화를 통한 데이터 무결성이 깨질 위험이 증가한다는 것은 매우 큰 비용으로 작용된다
- 무결성이 깨지면 이를 복구하기 위한 재 설계의 비용은 예상하기 어렵다..
반정규화를 적용하기 위해서는 위와 같은 반정규화 절차에 맞게 반정규화 대상을 조사하고, 다른 방법을 검토한 후 반정규화를 적용한다
반정규화 대상조사
전체 데이터의 양을 조사하고 그 데이터가 해당 프로세스를 처리할 때 성능저하가 나타날 수 있는지 검증해야 한다
데이터가 대량이고 성능이 저하될 것으로 예상이 되면 다음 4가지 경우를 고려하여 반정규화를 고려하게 된다
- 자주 사용되는 테이블에 접근(Access)하는 프로세스의 수가 많고 항상 일정한 범위만을 조회하는 경우에 반정규화를 검토한다
- 테이블에 대량의 데이터가 있고 대량의 데이터 범위를 자주 처리하는 경우에 처리범위를 일정하게 줄이지 않으면 성능을 보장할 수 없을 경우에 반정규화를 검토한다
- 통계성 프로세스에 의해 통계 정보를 필요로 할 때 별도의 통계테이블(반정규화 테이블)을 생성한다
- 테이블에 지나치게 많은 조인(JOIN)이 걸려 데이터를 조회하는 작업이 기술적으로 어려울 경우 반정규화를 검토한다
대상조사를 통해 반정규화를 고려해봐야 할 테이블이 발견됐다면 다른 방법으로 성능을 개선할 수 있는 방법을 찾아봐야 한다
-> 반정규화를 통해 데이터 무결성이 깨질 위험이 증가하기 때문에 이는 최후의 수단으로 고려하는 게 좋다
반정규화의 대상에 대해 다른 방법으로 처리할 수 있는지 검토
- 많은 조인이 걸려 데이터를 조회하는 작업이 기술적으로 어려울 경우 뷰(VIEW)를 사용하면 이를 해결할 수도 있다
- 뷰가 조회의 성능을 향상하는 역할을 수행하지는 않지만 개발자별로 SQL문장을 만드는 방법에 따라 성능저하가 나타날 수 있으므로 성능을 고려한 뷰를 생성하여 개발자가 뷰를 통해 접근하게 함으로써 성능저하의 위험을 예방하는 것도 좋은 방법이 된다
- 대량의 데이터처리나 부분처리에 의해 성능이 저하되는 경우에 클러스터링을 적용하거나 인덱스를 조정함으로써 성능을 향상할 수 있다
- 클러스터링을 적용하는 방법은 대량의 데이터를 특정 클러스터링 팩트에 의해 저장방식을 다르게 하는 방법이다
- 클러스터링의 경우 데이터를 입력/수정/삭제하는 경우 성능이 많이 저하되므로 조회중심의 테이블이 아니라면 생성하면 안 되는 오브젝트이다. 다만, 조회가 대부분이고 인덱스를 통해 성능향상이 불가능하다면 클러스터링을 고려할 만하다
- 인덱스를 통해 성능을 충분히 확보할 수 있다면 인덱스를 조정하여 반정규화를 회피하도록 한다.
- 대량의 데이터는 Primary Key의 성격에 따라 부분적인 테이블로 분리할 수 있다
- 파티셔닝 기법(Partitioning)이 적용되어 성능저하를 방지할 수 있다
- 인위적인 테이블을 통합/분리하지 않고 물리적인 저장기법에 따라 성능을 향상할 수 있는 파티셔닝을 고려해 볼 수 있다
- 데이터가 특정 기준(파티셔닝 키)에 의해 다르게 저장되고 파티셔닝 키에 따른 조회가 될 때 성능이 좋아지는 특성이 있다
- 특정 기준에 의해 물리적인 저장공간이 구분될 수 있고 트랜잭션이 들어올 때 일정한 기준에 의해 들어온다면 파티셔닝 테이블을 적용하여 조회의 성능을 향상시키는 것도 좋은 방법이 될 수 있다
- 응용 애플리케이션에서 로직을 구사하는 방법을 변경함으로써 성능을 향상시킬 수 있다
- 응용 메모리 영역에 데이터를 처리하기 위한 값을 캐싱하기 혹은 중간 클래스 영역에 데이터를 캐싱하여 공유하게 하면 성능을 향상시키는 방법이 될 수 있다
반정규화 적용
위와 같이 반정규화가 아닌 다른 방법 적용을 고려해도 반정규화를 적용해야겠다는 판단을 했다면 반정규화의 세 가지 규칙을 고려하여 반정규화를 적용하도록 한다
- 반정규화를 하는 대상으로는 테이블, 속성, 관계에 대해 적용할 수 있다
- 테이블과 속성, 관계에 대해 중복으로 가져가는 방법만이 반정규화가 아니고 테이블, 속성, 관계를 추가할 수도 있고 분할할 수도 있으며 제거할 수도 있다
- 성능을 향상시킬 수 있는 포괄적인 방법을 적용하여 반정규화를 적용하는 것이 전문화된 반정규화의 기법임을 기억할 필요가 있다
반정규화 기법
테이블 반정규화
- 테이블 병합
- 1:1 관계 테이블 병합 : 1:1 관계를 통합하여 성능향상
- 1:M 관계 테이블 병합 : 1:M 관계를 통합하여 성능향상
- 슈퍼/서브타입 테이블병합 : 슈퍼/서브 관계를 통합하여 성능향상
- 테이블 분할
- 수직분할 : 하나의 테이블의 속성을 분할하여 두 개 이상의 테이블로 분할
- 수평분할 : 하나의 테이블에 있는 값을 기준으로 테이블을 분할
- 테이블 추가
- 중복 테이블 추가 : 동일한 테이블 구조를 중복하여 원격조인을 제거
- 통계 테이블 추가 : SUM, AVG 등을 미리 수행하여 계산
- 이력 테이블 추가 : 마스터 테이블에서 자주 조회되는 레코드를 중복하여 테이블 추가
- 부분 테이블 추가 : 자주 이용하는 칼럼을 모아놓은 별도의 테이블 추가
속성 반정규화
- 중복 칼럼 추가 : 조인 감소를 위해 중복된 칼럼을 추가
- 파생 칼럼 추가 : 미리 값을 계산하여 칼럼에 보관
- 이력 테이블 칼럼 추가 : 대량의 이력 데이터를 처리할 때 기능성 칼럼(최근값 여부, 시작과 종료일자 등)을 추가
- PK에 의한 칼럼 추가 : 여러 칼럼으로 이루어진 PK를 가진 테이블을 조인할 경우 단순성을 위해서 인공키를 PK로 지정하고 활용
- 응용시스템 오작동을 위한 칼럼 추가 : 이전 데이터를 임시적으로 중복하여 보관
관계 반정규화
- 중복 관계 추가 : 여러 경로를 거쳐 조인할 수 있지만, 성능 저하를 예방하기 위해 추가적인 관계를 맺음
- 테이블과 칼럼의 반정규화는 데이터 무결성에 영향을 미치게 되나 관계의 반정규화는 데이터 무결성을 깨뜨릴 위험을 갖지 않고서도 데이터처리의 성능을 향상할 수 있는 반정규화의 기법
반정규화를 적용할 때 기억해야 할 내용은 데이터를 입력, 수정, 삭제할 때는 성능이 떨어지는 점을 기억해야 하고 데이터의 무결성 유지에 주의를 해야 한다
- 반정규화란 무엇인가요?
- 반정규화란 정규화된 관계에서 시스템의 성능을 올리거나 운영의 단순화를 위해 테이블, 속성, 관계를 병합, 분할, 추가하는 기법입니다. 반정규화를 적용한다는 것은 데이터 무결성이 깨질 위험이 증가할 수 있어 여러 방면에서 고려해 보고 반정규화를 적용해야 합니다
- 반정규화는 어떤 상황에서 고려해봐야 하나요?
- 여러 개의 테이블에서 조인을 통해 데이터를 읽어오는데 이 조회 성능이 시스템에서 중요하다고 판단될 때
- 함수적 종속관계를 만들지 않는 선에서 데이터 중복을 했을 때만 조회 성능이 올라갈 때
- 반정규화 적용을 고려해 볼 테이블이 결정되었다면 반정규화를 하는 것이 좋나요?
- 반정규화를 적용했을 때 기대되는 성능향상만 보고 바로 반정규화를 적용하는 것은 올바르지 않다고 생각합니다
- 조회 성능을 올릴 수 있는 방법으로 뷰 생성을 통한 조회 쿼리 성능 저하 방지, 인덱스를 통한 조회 성능 향상, 파티셔닝, 캐싱을 먼저 고려해 보는 것이 좋을 것 같습니다.
- 왜 반정규화 대신 다른 방법을 우선적으로 고려해보는 것이 좋을 것 같나요?
- 반정규화를 적용한다는 것은 테이블, 컬럼, 관계를 병합하거나 데이터를 중복, 분할하는 기법입니다
- 데이터가 중복된다는 것은 데이터 무결성이 깨질 위험이 증가한다는 것이고, 무결성이 깨진다는 것은 데이터베이스의 신뢰도가 떨어지는 크리티컬한 문제라고 생각합니다
- 따라서 이런 위험을 아예 감수하지 않도록 성능 개선을 먼저 고려해 보는 것이 옳다고 생각합니다
Reference
https://dataonair.or.kr/db-tech-reference/d-guide/sql/?mod=document&uid=333
반정규화와 성능
1. 반정규화를 통한 성능향상 전략 가. 반정규화의 정의 반정규화(=역정규화) 용어는 조금 다르게 표현되어도 그 의미는 동일하다. 여기에서 반정규화는 ‘반(Half)’의 의미가 아닌 한자로 반대
dataonair.or.kr
'데이터베이스' 카테고리의 다른 글
트랜잭션 격리수준 (0) | 2023.09.09 |
---|---|
트랜잭션 (0) | 2023.09.07 |
데이터베이스 정규화 (0) | 2023.09.06 |
데이터베이스 커넥션 풀 (0) | 2023.09.05 |
MySQL 인덱스 동작 확인하기 (0) | 2023.07.23 |