일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- java
- db
- 데이터베이스
- 웹
- JPA
- node.js
- HTTP
- ORM
- bytecode
- 스프링 부트
- django
- 디자인 패턴
- 자료구조
- 안드로이드
- 장고
- 자바
- python3
- BCI
- 보안
- Spring Boot
- 파이썬3
- Spring
- 개발
- Python
- 웹 개발
- 스프링
- 스프링부트
- mysql
- 파이썬
- rabbitmq
- Today
- Total
semtax의 개발 일지
RDB에 트리구조 저장하기 본문
개요
이번 포스팅에서는 RDB에 트리구조를 저장하는 법에 대해서 포스팅을 진행하도록 하겠다.
프로젝트를 진행하거나, 소프트웨어 개발을 하다보면 계층형 데이터를 저장 해야되는 경우를 많이 볼 수 있다.
하지만, RDB에서는 기본적으로 트리 구조에 대한 저장 기능을 따로 지원해주지 않는다.
(물론 최근 버전에서는 Recursive with 이나, connect by 같은 쿼리문을 이용해서 계층형 쿼리를 작성이 가능하긴 하다.
해당 기능은 추후 포스팅에서 다루도록 하겠다.)
따라서, 트리 구조를 저장할 방식을 고민을 해야한다.
이러한 고민을 하다 나온 아이디어 중 하나가, 바로 Closure Table이다.
Tree In RDB : Closure Table
Closure Table의 기본 아이디어는 다음과 같다.
먼저 트리를 노드와 간선으로 나누어서 본다.
그런 뒤, 트리의 노드를 구성하는 정보인 깊이(depth), 조상 노드의 번호(ancestor), 자식 노드의 번호(child)를 실제 데이터베이스에 저장하는 방식으로 구현 한다는 것이 기본 아이디어 이다.
구현
일단, 구현 예제로 계층형 댓글을 예시로 들어서 구현하도록 하겠다.
먼저 테이블 구조를 아래와 같이 모델링 해주자
컬럼명 | 설명 |
id | 댓글 ID |
text | 댓글 내용 |
parent | 부모 ID |
rank | 랭크(굳이 없어도 되긴 함) |
[표 1 : 댓글 테이블]
컬럼명 | 설명 |
ancestor | 조상 노드 id |
descendant | 자식 노드 id |
depth | 트리 노드의 깊이 |
[표 2 : 댓글의 노드 정보(Closure Table)]
먼저 댓글이 아래와 같이 달린다고 가정을 해보자.
1
| - 2
| - 3
| - 6
| - 5
| - 4
댓글에 대한 Closure Table은 아래와 같이 저장을 해주면 된다.
INSERT INTO `comments_closure` (`ancestor`, `descendant`, `depth`) VALUES
(1, 1, 0),
(0, 1, 0),
(2, 2, 0),
(1, 2, 1),
(0, 2, 1),
(3, 3, 0),
(1, 3, 2),
(2, 3, 1),
(0, 3, 2),
(4, 4, 0),
(1, 4, 1),
(0, 4, 1),
(5, 5, 0),
(1, 5, 2),
(2, 5, 1),
(0, 5, 2),
(6, 6, 0),
(1, 6, 3),
(2, 6, 2),
(3, 6, 1),
(0, 6, 3);
Closure table을 꺼내 오는것은 아래와 같이 꺼내오면 된다.
SELECT `id`,`parent` FROM `comments` `comment`
JOIN `comments_closure` `closure`
ON `comment`.`id` = `closure`.`descendant`
WHERE `closure`.`ancestor` = 2
위의 쿼리를 이용해서 얻어온 정보는 아래와 같다.
Id | Parent |
2 | 1 |
3 | 2 |
5 | 2 |
6 | 3 |
[표 3 : Closure table을 가져오는 쿼리문을 이용해서 꺼내온 결과 값]
이제 id와 parent id를 이용해서 comment 테이블을 가져온 뒤, 계층형으로 댓글을 뷰를 통해서 보여주면 된다.
(필요한 경우, depth도 가져와서 대댓글에 대한 depth정보도 뷰를 통해 보여줄 수 있다.)
활용
아래와 같은 곳에서 활용이 가능하다.
- 계층형 계시판
- Ex) 답글의 답글의 답글의 답글..
- 사원 조직도
- 콜 스택 덤프 저장
그 외에도, 트리나 그래프 형태로 모델링 되는 데이터는 해당 모델링을 이용해서 대부분 저장이 가능하다..
출처
'개발 > 데이터베이스' 카테고리의 다른 글
데이터베이스 DDL 자동 변환해주는 사이트 : SQLines (0) | 2020.06.07 |
---|---|
MySQL 아키텍처 Overview (0) | 2020.04.01 |
MySQL에서 SQL파일 실행하는 법 (0) | 2020.02.24 |
PostgreSQL에서 AUTO INCREMENT 사용하기 (0) | 2020.01.12 |
맥 OS 에서 PostgreSQL 설치하기 (1) | 2020.01.11 |