본문 바로가기
행복바이러스 행복바이러스

Bubble.io 데이터베이스 1:N·N:M 관계 설계|차이와 실제 데이터 구조 예제

읽는 시간 약 9분

Bubble.io로 서비스를 만들다 보면 데이터베이스 구조를 설계하는 단계에서 한 번쯤 막히는 부분이 있습니다.

바로 1:N(일대다)과 N:M(다대다) 관계를 어떻게 구성할 것인가입니다.

데이터가 몇 건 없을 때는 어떤 방식으로 만들어도 잘 작동하는 것처럼 보입니다. 하지만 사용자와 주문, 상품처럼 데이터가 계속 늘어나는 서비스라면 처음 설계한 관계가 나중에 검색과 워크플로우를 복잡하게 만들 수 있습니다.

이번 글에서는 이론적인 설명보다 실제 쇼핑몰 데이터를 예로 들어 두 관계가 어떻게 다른지 살펴보겠습니다.

1:N 관계부터 이해해보겠습니다

가장 간단한 예가 사용자(User)와 주문(Order)입니다.

한 명의 사용자는 여러 개의 주문을 만들 수 있습니다.

User 1명
   ↓
Order 여러 개

예를 들어 김사용자가 주문을 세 번 했다면 데이터는 다음과 같습니다.

OrderUser금액
주문001김사용자35,000원
주문002김사용자18,000원
주문003김사용자52,000원

이것이 전형적인 1:N 관계입니다.

여기서 중요한 것은 관계를 어디에 저장할 것인지입니다.

User 데이터에 모든 Order 목록을 계속 저장할 수도 있지만, Order 쪽에 User 필드를 두고 주문의 소유자를 기록하는 방법도 생각할 수 있습니다.

예를 들면 다음과 같습니다.

Order
- order_number
- user
- amount
- status
- created_date

그러면 특정 사용자의 주문이 필요할 때 Order에서 해당 User를 조건으로 검색할 수 있습니다.

양쪽에 같은 관계를 무조건 저장하지 않습니다

처음 Bubble을 사용할 때 이런 구조를 만들기 쉽습니다.

User
- orders (List of Orders)

Order
- user (User)

양쪽에서 관계를 바로 확인할 수 있어 편해 보입니다.

하지만 주문을 생성할 때마다 Order.user뿐 아니라 User.orders까지 정확하게 업데이트해야 한다면 관리할 데이터가 하나 더 생깁니다.

한쪽 업데이트가 실패하면 관계가 서로 맞지 않을 수도 있습니다.

그래서 양쪽에 관계를 저장해야 할 명확한 이유가 있는지 먼저 확인하는 편이 좋습니다.

무조건 한쪽 방식이 빠르다는 의미가 아니라 데이터의 기준을 명확하게 만드는 것이 중요하다는 뜻입니다.

N:M은 어떤 경우일까?

이번에는 상품(Product)과 카테고리(Category)를 생각해보겠습니다.

상품 하나가 여러 카테고리에 들어갈 수 있고 하나의 카테고리에도 여러 상품이 들어갈 수 있다면 N:M 관계가 됩니다.

Product 여러 개
      ↕
Category 여러 개

예를 들어 운동화 A가 다음 두 카테고리에 포함될 수 있습니다.

남성 신발
러닝화

러닝화 카테고리에는 운동화 A뿐 아니라 운동화 B와 운동화 C도 들어갈 수 있습니다.

이런 관계는 1:N처럼 단순하지 않습니다.

N:M에서 중간 데이터 타입이 필요한 경우

N:M 관계에서는 두 데이터 타입에 List를 만드는 방법을 먼저 생각할 수 있습니다.

하지만 관계 자체에 추가 정보가 필요해지면 별도의 데이터 타입을 만드는 방법이 유용합니다.

예를 들어 사용자와 프로젝트 관계를 생각해보겠습니다.

사용자 한 명이 여러 프로젝트에 참여할 수 있고 프로젝트에도 여러 사용자가 참여할 수 있습니다.

그런데 단순히 참여 여부만 필요한 것이 아니라 다음 정보도 필요합니다.

역할 / 참여일 / 권한 / 상태

이때 ProjectMember라는 중간 데이터 타입을 만들 수 있습니다.

User
   ↓
ProjectMember
   ↑
Project

ProjectMember에는 다음과 같이 저장합니다.

ProjectMember
- user
- project
- role
- joined_date
- status

예를 들어 실제 데이터는 이렇게 됩니다.

UserProjectRole
김사용자프로젝트 AAdmin
이사용자프로젝트 AMember
김사용자프로젝트 BMember

이렇게 만들면 관계 자체에 필요한 정보를 함께 저장할 수 있습니다.

단순 List와 중간 데이터 타입의 차이

예를 들어 Project에 다음 필드를 만들 수도 있습니다.

members
List of Users

단순히 “이 프로젝트에 누가 참여하는가?”만 필요하다면 충분할 수 있습니다.

그런데 나중에 요구사항이 바뀌어

누가 관리자인가?
언제 프로젝트에 참여했는가?
현재 활성 상태인가?

까지 관리해야 한다면 User 목록만으로는 부족해집니다.

결국 별도의 필드를 추가하거나 데이터 구조를 다시 변경해야 합니다.

그래서 N:M 구조를 설계할 때는 현재 관계뿐 아니라 관계 자체에 추가 속성이 필요한지 확인하는 것이 좋습니다.

데이터가 많아지면 Search 조건도 중요합니다

Bubble에서는 Do a search for를 사용해 데이터를 가져오는 경우가 많습니다.

예를 들어 특정 사용자의 주문을 가져온다면 개념적으로 다음과 같은 조건을 사용하게 됩니다.

Search for Orders
Constraint:
user = Current User

이런 구조에서는 Order에 User가 직접 연결되어 있기 때문에 어떤 조건으로 검색해야 하는지 이해하기 쉽습니다.

반면 데이터 구조가 여러 단계로 얽혀 있다면 원하는 데이터를 찾기 위해 추가 검색이나 필터링이 필요할 수 있습니다.

특히 데이터가 늘어난 서비스에서는 먼저 많은 데이터를 가져온 다음 화면에서 다시 걸러내는 구조를 반복해서 사용하고 있지는 않은지 확인할 필요가 있습니다.

:filtered를 습관적으로 사용하는 것도 확인합니다

예를 들어 검색 결과를 가져온 뒤 다시 :filtered로 조건을 적용하는 구조를 만들 수 있습니다.

작은 테스트 앱에서는 별다른 문제가 없어 보일 수 있습니다.

하지만 데이터가 많아지면 처음부터 필요한 조건으로 검색할 수 있는 부분까지 모두 가져온 다음 추가 처리하는 구조가 적절한지 검토해야 합니다.

가능하다면 검색 단계에서 사용할 수 있는 조건은 먼저 적용하고, :filtered가 정말 필요한 상황인지 구분하는 것이 좋습니다.

Privacy Rules도 함께 생각해야 합니다

Bubble 데이터베이스 설계에서는 관계와 검색만 볼 수 없습니다.

사용자별 데이터를 다룬다면 Privacy Rules도 함께 설계해야 합니다.

예를 들어 주문 데이터가 있다고 해보겠습니다.

일반 사용자는 자신의 주문만 확인해야 하고 관리자는 전체 주문을 확인해야 할 수 있습니다.

그렇다면 단순히 화면에서 다른 사용자의 주문을 숨기는 것만으로 끝내기보다 데이터 접근 규칙 자체를 함께 확인해야 합니다.

특히 User와 Order, ProjectMember 같은 관계를 만들 때는 어떤 사용자가 어떤 데이터에 접근할 수 있는지까지 함께 생각하는 것이 좋습니다.

1:N과 N:M 중 무엇이 더 빠를까?

이 질문은 단순하게 답하기 어렵습니다.

“1:N은 빠르고 N:M은 느리다”고 단정하는 것은 적절하지 않습니다.

실제 사용 경험에는 데이터 개수뿐 아니라 검색 방식, 페이지에서 실행되는 워크플로우, Privacy Rules, 표시하는 데이터 양, 관계 구조 등이 함께 영향을 줄 수 있기 때문입니다.

따라서 관계 유형 자체의 속도를 비교하기보다 필요한 데이터를 가장 단순하고 일관된 방식으로 찾을 수 있는 구조인지를 확인하는 것이 더 중요합니다.

제가 데이터 구조를 정할 때 확인하는 기준

새로운 데이터 타입을 만들 때는 먼저 관계를 그림으로 그려봅니다.

User 1 ─── N Order

User N ─── N Project
       ↓
  ProjectMember

그리고 다음을 확인합니다.

관계의 기준 데이터는 어디인가?

양쪽에 같은 관계를 저장해야 하는가?

관계 자체에 역할이나 날짜 같은 정보가 필요한가?

검색할 때 어떤 조건을 가장 많이 사용할 것인가?

Privacy Rules는 어떤 기준으로 설정할 것인가?

이 다섯 가지를 먼저 결정하면 데이터가 늘어난 뒤 구조를 다시 뜯어고치는 일을 줄일 수 있습니다.

마무리

Bubble.io에서 1:N과 N:M 관계를 설계할 때 중요한 것은 어느 방식이 무조건 더 빠른지를 찾는 것이 아닙니다.

사용자와 주문처럼 소유 관계가 명확하다면 1:N 구조가 자연스럽고, 사용자와 프로젝트처럼 양쪽에 여러 관계가 존재하면서 역할이나 참여일 같은 추가 정보까지 필요하다면 중간 데이터 타입을 활용한 N:M 구조를 검토할 수 있습니다.

처음에는 데이터가 적어서 구조의 차이가 잘 드러나지 않습니다.

하지만 서비스가 커지면 데이터 검색, 워크플로우, 권한 관리까지 연결되기 때문에 처음부터 데이터의 기준과 관계를 명확하게 만들어두는 것이 중요합니다.

youngji
함께 보면 좋은 글

댓글 0

첫 댓글을 남겨보세요.

광고 차단 알림

광고 클릭 제한을 초과하여 광고가 차단되었습니다.

단시간에 반복적인 광고 클릭은 시스템에 의해 감지되며, IP가 수집되어 사이트 관리자가 확인 가능합니다.