RDB는 관계를 표현하기 어렵다
The rise in connectedness translates in the relational world into increased joins, which impede performance and make it difficult for us to evolve an existing database in response to changing business needs.
(테이블 간의) 연결성 증가는 JOIN 쿼리의 증가로 이어지며, 이는 수시로 변화하는 비즈니스적 요구에 맞게 기존의 데이터베이스를 변경시키는 것을 어렵게 만들고 또한 성능 저하의 원인이 된다.
MySQL(RDB)를 현업에서 사용하면서 아래와 같은 문제들을 실제로 겪고 있다.
- 단순히 DB의 동작을 위해서 외래키를 추가하는 것은 유지보수 비용이 크다.
- 테이블에서 nullable 한 컬럼이 존재하는 것은 코드 상에서 null 값을 체크하기 위한 비용이 크다.
- Reciprocal query(상호쿼리)의 경우 한계를 지닌다.
예를 들어, 고객 중심으로 설계된 스키마가 있다고 하자. 이 경우, 고객 테이블의 PK를 외래키로 가지는 Product 테이블은 고객 테이블의 PK를 기준으로 정렬이 되어 있다.
이 경우, "고객 A가 구매한 product는 어떤 것이 있는가?" 의 질문에 답하는 것은 비교적 쉽다. 고객 A의 ID 값을 찾아서, 그 값에 대한 products 만 조회해오면 된다. 근데, 이 질문을 조금만 뒤집으면 기하급수적으로 어려워지기 시작한다.
"어떤 product 를 구매한 customer 들은 누구인가?" (참고로 이것은 추천 시스템의 근간이 되는 조회 쿼리이기 때문에, 이러한 경우 RDB 를 사용하는 것이 적절치 않다는 것을 알 수 있다.)
심지어, "이 product를 구매했으면서 저 product를 구매한 고객들은 누구인가?" 라는 질문(recursive questions)에 답하기는 더욱 어렵다. (불가능한 것은 아니지만 recursion 의 정도가 늘어날수록 성능 저하는 훨씬 커질 것이다. 즉 RDB가 적합하지 않다는 의문이 강력하게 들 수 있는 것이다.)
RDB를 사용하면, Business Needs 에 따라 테스트를 하기가 어려운 이유
위 테이블 구조는 아주 아주 간단한 형태이지만, 우선 말로 설명하면 이럴 것이다. 예를 들어 twitter 같이 관계성이 비즈니스 모델의 핵심인 브랜드가 있다고 치자. 그러면 고객 DB는 person 으로 표현되고, 서로 친구인지 관계를 보여주는 person_friend 테이블이 하나 있을 것이다.
그러면 지금부터는 다양한 PM의 요구사항에 따라 개발자가 어떤 query 문을 작성해야하는지 적어보면서 RDB 에서는 관계를 자유자재로 생각하는 것이 얼마나 어려운지 살펴보자.
PM : John의 친구들은 누구인지 보고싶어요!
SELECT p1.name
FROM Person p1 JOIN PersonFriend
ON PersonFriend.FriendID = p1.ID
JOIN Person p2
ON PersonFriend.PersonID = p2.ID
WHERE p2.name = 'John';
이렇게 찾으면, 실제로 값은 누가 나오게될까? Alice, Sam이 나올 것이다.
PM : John을 친구로 두고 있는 사람들은 누구인지 보고 싶어요!
SELECT p1.name
FROM Person p1 JOIN PersonFriend
ON PersonFriend.PersonID = p1.ID
JOIN Person p2
ON PersonFriend.FriendID = p2.ID
WHERE p2.name = 'John';
답은 Alice 혼자다.
이렇듯 위의 케이스로 보면 person id 의 경우 person_friend 테이블에서 정렬이 되어있으나, friend_id 의 경우 정렬이 되어있지 않아, 모든 테이블의 rows 들을 조회해야할 수 밖에 없다.
PM : John의 친구들의 친구들까지 볼 수 있을까요?
SELECT p1.name AS PERSON, p2.name AS FRIEND_OF_FRIEND
FROM PersonFriend pf1 JOIN Person p1
ON pf1.PersonID = p1.ID
JOIN PersonFriend pf2
ON pf2.PersonID = pf1.FriendID
JOIN Person p2
ON pf2.FriendID = p2.ID
WHERE p1.name = 'John' AND pf2.FriendID <> p1.ID
이 쯤 되면, 이 부탁을 하는 PM과 담당 개발자 사이의 심리적 거리가 멀어질지도 모른다. 이렇듯 사소한 요구사항에서도 DB에 날려야 되는 쿼리의 JOIN의 개수는 4개, 5개로 늘어나고, recursively joining tables 은 시간복잡도와 공간복잡도를 상당히 늘리게 된다.
위 내용을 통해서 우리는 왜 Graph Databases 의 수요가 점점 늘어나고, 현재 많은 BM에서 RDB의 한계를 여실히 느낄 수 밖에 없는지 살펴보았다. 다음 글에서는 왜 NoSQL(Not Only SQL)이 관계성을 다루는데 한계가 있는지에 대해 살펴보도록 하자.
* 위 글은 Oreilly 에서 나온 Graph Databases 책을 읽고 공부하기 위한 목적으로 작성한 글입니다.
책 링크는 아래에 있어요 : )
https://www.oreilly.com/library/view/graph-databases-2nd/9781491930885/
Graph Databases, 2nd Edition
Discover how graph databases can help you manage and query highly connected data. With this practical book, you’ll learn how to design and implement a graph database that brings the … - Selection from Graph Databases, 2nd Edition [Book]
www.oreilly.com
'프로그래밍, 개발' 카테고리의 다른 글
왜 그래프 데이터베이스를 사용하는가? (0) | 2023.03.19 |
---|---|
keycloak : id of client 와 client id 값의 차이 (0) | 2023.03.06 |
DDD 개발 이해하기 : 도메인(Domain)과 애그리거트(Aggregate) (0) | 2023.02.26 |
헥사고날 아키텍처(Hexagonal Architecture) 란? (0) | 2023.02.26 |
인증과 인가, 그리고 OAuth (0) | 2023.02.20 |