DB/RDB

물리적 데이터 모델링 역정규화 (Denormalization) 활용

annovation 2024. 12. 26. 19:30

원본 테이블 

이 데이터 구조는 정규화된 상태로, 데이터의 중복을 최소화하고 데이터 무결성을 유지하도록 설계되어 있습니다.

이미지 1 : 역정규화 - 컬럼을 조작해서 join을 줄이기 (하단 출처 참조)

 

author: 작성자 정보 (id, name, profile)

topic : 주제 정보 (title, description, created, author_id)

topic_tag_relation : 주제와 태그 간의 관계를 나타내는 테이블 (topic_title, tag_id)

tag : 태그 정보 (id, name)


방법 1 . 컬럼 중복 JOIN 줄이기

topic_tag_relation 테이블에 tag_name이라는 열을 추가하여, 태그 이름(rdb, free, commercial)을 바로 확인할 수 있도록 만듭니다.

이미지 2 : 역정규화 - 컬럼을 조작해서 join을 줄이기 (하단 출처 참조)

 

1. 역정규화 이전 쿼리

SELECT tag.name
FROM topic_tag_relation AS TTR
LEFT JOIN tag
ON TTR.tag_id = tag.id
WHERE topic_title = 'MySQL';

 

정규화된 데이터베이스에서는 데이터를 가져오기 위해 여러 테이블 간의 조인(JOIN)이 필요합니다.

역정규화를 통해 tag_name 열을 직접 추가하면, 조인이 필요하지 않으므로 데이터 조회 속도가 빨라집니다.

 

2. 해결방법 

 

(1) 컬럼 추가

topic_tag_relation 테이블에 tag_name이라는 새 열(Column)을 추가합니다.

ALTER TABLE `topic_tag_relation` ADD COLUMN `tag_name` VARCHAR(45) NULL AFTER `tag_id`;

 

(2) 데이터 병합

tag_idtag_name의 관계를 매핑하여 새 컬럼에 데이터를 채웁니다.

각각의 tag_id에 해당하는 tag.name 값을 topic_tag_relationtag_name에 삽입합니다.

UPDATE `topic_tag_relation`
SET `tag_name` = 'rdb'
WHERE `topic_title` = 'MySQL' AND `tag_id` = '1';

UPDATE `topic_tag_relation`
SET `tag_name` = 'free'
WHERE `topic_title` = 'MySQL' AND `tag_id` = '2';

UPDATE `topic_tag_relation`
SET `tag_name` = 'rdb'
WHERE `topic_title` = 'ORACLE' AND `tag_id` = '1';

UPDATE `topic_tag_relation`
SET `tag_name` = 'commercial'
WHERE `topic_title` = 'ORACLE' AND `tag_id` = '3';

 

3. 역정규화된 쿼리

SELECT tag.name
FROM topic_tag_relation
WHERE topic_title = 'MySQL';

 

4. 역정규화 장점

조회 효율성 향상 : 태그 이름을 조회할 때, tag 테이블을 조인하지 않아도 바로 결과를 얻을 수 있습니다.

데이터 접근 간소화 : 한 테이블에 데이터를 포함하므로 쿼리가 간단해집니다.

 

5. 역정규화 단점

데이터 중복 발생 : tag_name이 중복 저장되므로 데이터 크기가 증가합니다.

수정 비용 증가 : 태그 이름 변경 시 여러 테이블을 업데이트해야 할 수도 있습니다.


방법 2. 파생 컬럼 형성  계산작업 줄이기

이미지 3 : 생활코딩 관계형 데이터 모델링 - 7.4. 역정규화 : 컬럼을 조작해서 계산을 줄이기

 

1. 역정규화 이전 쿼리

SELECT author.id, COUNT(author.id) 
FROM topic
GROUP BY author.id;

이러한 쿼리는 테이블의 데이터가 많아지고 요청이 빈번해질수록 성능 부하가 발생할 수 있습니다.

특히, GROUP BY 연산은 데이터베이스에서 CPU와 메모리를 많이 사용하므로, 실시간 조회가 필요한 상황에서는 적합하지 않습니다.

 

2. 해결방법

 

(1) 컬럼 추가

author 테이블에 topic_count라는 새 열(Column)을 추가합니다. 이 열은 각 작성자가 작성한 주제(topic) 개수를 저장합니다.

ALTER TABLE author ADD COLUMN topic_count INT NULL AFTER profile;

 

(2) 파생 컬럼 생성으로 계산작업 줄이기

author 테이블의 topic_count 열을 계산하여 데이터를 업데이트합니다. 각 작성자가 작성한 주제 수를 집계하고 해당 값으로 테이블을 갱신합니다.

UPDATE author
SET topic_count = (
	SELECT COUNT(*)
	FROM topic
	WHERE topic.author_id = author.id
);

 

3. 역정규화된 쿼리

SELECT name, profile, topic_count 
FROM author;

 

4. 역정규화 장점

작성자가 작성한 주제 수를 조회할 때, JOIN이나 GROUP BY 연산 없이도 topic_count 값을 직접 조회할 수 있습니다.

 실시간 응답 속도가 크게 향상됩니다.

 

5. 역정규화 단점

topic_count는 작성자별 주제 개수 데이터를 별도로 저장하기 때문에, 데이터 중복이 발생할 수 있습니다.

새로운 주제를 추가하거나 삭제할 때마다 topic_count 값을 업데이트해야 합니다.


출처

OpenAI ChatGPT (https://openai.com)

이미지 1, 2 : 생활코딩 관계형 데이터 모델링 - 7.3. 역정규화 : 컬럼을 조작해서 join을 줄이기

이미지 3 : 생활코딩 관계형 데이터 모델링 - 7.4. 역정규화 : 컬럼을 조작해서 계산을 줄이기

반응형