콘텐츠로 이동

관계에는 결과가 따른다

28개 언어로도 제공

English · Español · 日本語 · Português (Brasil) · Français · Deutsch · Italiano · 简体中文 · Português (Portugal) · 繁體中文 · Bahasa Indonesia · Türkçe · Polski · Tiếng Việt · ไทย · Nederlands · العربية · עברית · Українська · हिन्दी · Русский · Svenska · Dansk · Norsk bokmål · Suomi · Español (México) · Français (Canada) · Deutsch (Schweiz)

A brick house with a glass room built onto its side, and a separate timber garden studio across the lawn, joined to it only by a stepping-stone path.
AI로 생성한 이미지

Data Architect 과정 3장인 Salesforce 데이터 아키텍처의 모듈 7/10. 각 모듈은 독립적으로 읽을 수 있습니다. 이전: 필드도 아키텍처다 · 다음: 소유권과 생명주기

이 모듈이 답하는 질문: 두 Salesforce 개체를 연결할 때 나는 실제로 무엇을 고르는 걸까요?

관계를 그리는 것은 쉽습니다. 2장에서 선을 긋고 이름을 붙였습니다. 리테일 파트너는 배송 목록을 여럿 보내고, 배송에는 품목이 여럿 실리고, 배송팀과 트럭은 배송팀 배정에서 만납니다. 카디널리티, 선택성, 이력을 이야기했습니다. 이제 그 선들을 Salesforce에 구현하고, 다이어그램 위의 선이 훨씬 많은 무게를 지기 시작합니다.

Salesforce에서 관계 유형을 고를 때 저는 단지 이 두 레코드가 연결되어 있다고 말하는 게 아닙니다. 누가 하위를 소유하는지, 상위 없이 존재할 수 있는지, 누가 볼 수 있는지, 상위가 삭제되면 어떻게 되는지, 다른 상위로 옮길 수 있는지, 상위에 요약할 수 있는지, 하위가 수십만 건이 되면 어떻게 되는지도 정하는 것일 수 있습니다. 관계는 그냥 선이 아닙니다. 동작을 담고 있습니다.

조회냐 마스터-세부 사항이냐 전에 비즈니스로 돌아가십시오. 배송과 그 배송 품목, 즉 냉장고, 설치, 헌 제품 수거를 보십시오. 품목이 배송 없이 존재할 수 있나요? 아니요. 배송이 삭제되면 품목도 사라져야 하나요? 네. 품목에 자기 소유자나 자기 보안이 필요한가요? 그렇지 않습니다. 누군가 품목을 한 배송에서 다른 배송으로 옮겨야 하나요? 실수로는 아니길 바랍니다.

이제 배송과 그것이 속한 경로를 보십시오. 배송은 경로에 배정되기 전에 존재하고, 계획이 바뀌면 다른 경로로 옮겨질 수 있으며, 경로를 삭제해도 그 위의 배송이 삭제되어서는 절대 안 됩니다. 다이어그램에서는 똑같아 보이는 일대다 선 두 개가 전혀 다르게 동작합니다. 아직 “조회”나 “마스터-세부 사항”이라고 말하지 않았다는 점에 주목하십시오. 먼저 동작을 기술하라. 구성은 그것을 구현한다.

새 필드 화면을 열면 Salesforce는 몇 가지 관계 유형을 보여 줍니다(Object Relationships Overview (opens in a new tab)).

  • 조회: 두 개체를 연결합니다. Salesforce 관계의 기본 중의 기본입니다.
  • 마스터-세부 사항: 상위가 하위를 제어하는 상위-하위 결속입니다.
  • 다대다: 별도의 필드 유형이 아니라 하나의 패턴입니다. 마스터-세부 사항 두 개를 가진 사용자 정의 개체인 **Salesforce 연결 개체(Salesforce Junction Object)**입니다.
  • 자기 관계: 개체에서 자기 자신으로 가는 조회입니다.
  • 계층: 사용자 개체에만 있는 특별한 조회입니다. 사용자의 관리자 같은 것입니다.
  • 외부 조회와 간접 조회: 외부 개체, 즉 모듈 4의 __x 개체와 주고받는 관계입니다. 외부 조회는 상위 외부 개체를 가리킵니다. 간접 조회는 외부 개체에서 표준 개체나 사용자 정의 개체를 가리키며, 고유한 외부 ID로 일치시킵니다.

설계 시간의 대부분은 처음 세 가지에 들어갑니다. 하나씩 보겠습니다.

조회: 이 레코드들은 연결되어 있다

섹션 제목: “조회: 이 레코드들은 연결되어 있다 ”

조회는 이렇게 말합니다. 이 레코드는 저 레코드와 연관되어 있다. 하위는 자기 정체성, 자기 소유자, 자기 생애를 유지합니다. 배송이 자기 경로를 가리킵니다. 경로가 취소되어도 배송은 사라지지 않고, 다시 경로에 배정되러 돌아갑니다.

재미있는 점이 있습니다. 조회 필드는 하위에 놓이지만, 상위도 무언가를 얻습니다. 자기 하위들의 관련 목록입니다. 그러니 조회를 만들 때는 양쪽 끝에 모두 이름을 붙이십시오. 관련 목록 레이블은 사람들이 상위에서 보는 이름이고, 하위 관계 이름은 개발자와 연동이 상위에서 하위로 따라갈 때 쓰는 이름입니다. 기본값을 그대로 받아들이지 마십시오.

조회는 필수일 수도, 선택일 수도 있습니다. 선택이라면 가리키는 레코드가 삭제될 때 어떻게 할지 정하며, 선택지는 세 가지입니다(Considerations for Object Relationships (opens in a new tab)).

  • 이 필드의 값 지우기, 기본값입니다. 하위는 남고, 조회는 비게 됩니다.
  • 조회 레코드의 삭제 허용 안 함. 경로를 삭제하려 하면 Salesforce가 거부합니다. 관계의 일부이기 때문입니다.
  • 이 레코드도 삭제, 마스터-세부 사항처럼 연쇄 삭제입니다. 사용자 정의 개체의 사용자 정의 조회에서만 제공되고, 기본적으로 비활성화되어 있으며, Salesforce가 org에 켜 줘야 합니다. 연쇄 삭제는 보안과 공유를 우회하기 때문입니다. 사용자가 볼 수조차 없는 레코드를 삭제할 수 있습니다.

설정 화면에 숨은 생명주기 결정입니다.

조회 필터는 사용자가 고를 수 있는 범위를 좁힙니다. 배송에 연락처로 가는 설치 기사 조회가 있고, 설치 기사는 여러 연락처 레코드 유형 중 하나라고 합시다. 조회 필터는 설치 기사만 보여 주며, 현재 레코드, 조회되는 레코드, 그리고 사용자(프로필, 역할, 권한)를 기준으로 거를 수 있습니다(Lookup Filters (opens in a new tab)). 조회를 정직하게 유지하는 값싼 방법입니다.

마스터-세부 사항: 이 하위는 저 상위에 속한다

섹션 제목: “마스터-세부 사항: 이 하위는 저 상위에 속한다 ”

마스터-세부 사항은 훨씬 강한 진술을 합니다. 수업에서는 아주 단단한 결속이라고 부릅니다. 마스터 없이는 세부 사항을 가질 수 없고, 마스터 필드는 필수입니다. 세부 사항은 자기 소유자 필드를 잃고 상위의 소유자를 물려받습니다. 세부 사항에는 별도의 공유 테이블이 없으므로 하위만 따로 공유할 수 없고, 상위의 공유를 물려받습니다. 그래서 세부 사항 개체에는 공유 규칙, 수동 공유, 대기열을 둘 수 없습니다. 모두 소유자 필드가 필요하기 때문입니다(Object Relationships Overview (opens in a new tab)). 설정에서 그 공유 설정은 상위에 의해 제어됨(Controlled by Parent)으로 표시됩니다. 그리고 마스터-세부 사항 필드 자체에서 공유 설정을 고릅니다. 세부 사항을 만들고, 편집하고, 삭제하려면 마스터에 대해 읽기 전용 접근이 필요한지 읽기/쓰기 접근이 필요한지입니다. 마스터를 삭제하면 세부 사항도 삭제됩니다. 그리고 마스터는 롤업 요약 필드를 얻습니다.

그러니 배송 품목이 배송의 세부 사항이라면, 저는 이 품목이 평생 이 배송에 속한다고 말하는 것입니다. 누군가 설정에서 마스터-세부 사항 관계를 고르기 전에 답을 듣고 싶은 질문이 그것입니다.

충분히 생각했는지 알아보는 제가 좋아하는 방법이 있습니다. 누군가 상위를 삭제하면 하위는 어떻게 되어야 하는가? 모두가 불편해합니다. 좋습니다. 이제 아키텍처를 하고 있는 겁니다.

리테일 파트너에게 과거 배송이 수십만 건 있습니다. 누군가 그 파트너를 삭제합니다. 배송이 사라져야 할까요? 거의 확실히 아닙니다. 클레임, 청구, 이력이 모두 그것에 의존합니다. 어쩌면 파트너 삭제를 아예 허용하지 말고 비활성화해야 할지도 모릅니다. 마스터-세부 사항에서는 마스터를 삭제하면 세부 사항과 그 세부 사항까지 연쇄 삭제되고, 마스터를 복원하면 그것들도 돌아옵니다(Considerations for Object Relationships (opens in a new tab)). 그래서 누군가 “마스터-세부 사항을 쓰면 롤업이 생겨요”라고 하면 제 답은 이렇습니다. 좋습니다. 방금 또 무엇에 동의하셨죠?

조회에서는 하위가 자기 소유자를 가질 수 있습니다. 마스터-세부 사항에서는 그럴 수 없고, 접근은 마스터를 따릅니다. 세부 사항이 정말 상위의 일부라면 그게 정확히 맞습니다. 하지만 하위에 자기 소유자, 자기 공유, 자기 생명주기가 필요하다면, 모델은 마스터-세부 사항이 잘못된 선택이라고 말하고 있는 겁니다. 다음 모듈은 소유권을 더 깊이 다루고, Sharing and Visibility 과정은 더 멀리 갑니다. 지금은 이것만: 관계 설계와 보안 설계는 별개의 대화가 아닙니다. 누군가 공유 규칙을 쓰기 전에 데이터 모델이 보안 모델을 형성합니다.

상위를 알기 전에 하위가 존재할 수 있나요? 들리는 것보다 중요합니다. 배송이 전날 밤 배송 목록으로 도착하고 경로는 그 뒤에 만들어진다면, 배송에 경로를 필수로 두는 것은 레코드를 만들기도 전에 경로 배정이 끝나야 한다는 뜻이 됩니다. 물리적 관계는 실제 생명주기를 지원해야 합니다. 그래서 저는 정적인 다이어그램만으로 관계를 설계하지 않습니다. 알고 싶습니다. 어떻게 태어나고, 혼자 존재할 수 있고, 옮겨 갈 수 있고, 어떻게 사라지는가?

하위가 상위를 바꿀 수 있는가?

섹션 제목: “하위가 상위를 바꿀 수 있는가? ”

기본적으로 마스터-세부 사항의 하위는 다른 상위로 옮길 수 없습니다. 관계에서 상위 레코드 재지정 허용(Allow reparenting)을 선택하면 허용할 수 있습니다(Considerations for Object Relationships (opens in a new tab)). 제 본능은 보수적입니다. 하위가 평생 상위 하나에 속한다고 비즈니스가 말한다면, 옮기기 쉽게 만들지 않습니다. 품목이 한 배송에서 다른 배송으로 옮겨 가는 것은 필드 편집이 아니라 의도적인 비즈니스 이벤트여야 합니다. 다시 말하지만 설정이 아키텍처가 아닙니다. 생명주기 규칙이 아키텍처이고, 설정은 그것을 구현합니다.

나중에 팀들을 곤란하게 하는 것이 두 가지 더 있습니다. 이미 데이터가 있는 개체에는 마스터-세부 사항 관계를 만들 수 없습니다. 조회를 만들고, 모든 레코드에 값을 채운 뒤, 변환합니다. 그리고 마스터에 롤업 요약 필드가 없을 때만 다시 조회로 되돌릴 수 있습니다. 변환이 보안에 하는 일도 지켜보십시오. 조회를 마스터-세부 사항으로 바꾸면 하위의 공유가 상위에 의해 제어됨으로 설정되고, 마스터-세부 사항을 다시 조회로 바꾸면 하위의 조직 전체 기본값이 공개 읽기/쓰기로 설정됩니다(Considerations for Object Relationships (opens in a new tab)). 어제 비공개였던 레코드가 오늘은 열려 있습니다. 누군가 알아챌 때까지요. 일찍 고르십시오.

롤업은 유용하지만 공짜가 아니다

섹션 제목: “롤업은 유용하지만 공짜가 아니다 ”

저는 롤업을 좋아합니다. 배송의 품목 수를 세고, 청구서 줄 금액을 합하고, 최근 날짜를 찾는 것. 코드 없이 기본 기능으로요. 마스터-세부 사항 필드는 하위에 놓이지만, 롤업은 상위에 놓입니다. 하지만 작은 글씨가 붙어 있습니다(Roll-Up Summary Field (opens in a new tab)).

  • 특정 변경(새 롤업 필드, 그것이 의존하는 수식의 변경, 강제 재계산) 뒤에 롤업 값을 계산하는 데 영향받는 레코드 수에 따라 최대 30분이 걸릴 수 있습니다. 상위의 숫자가 왜 아직 안 바뀌었는지 의아해하는 사람들을 본 적이 있습니다.
  • 모든 것을 요약할 수는 없습니다. 자동 번호는 집계 대상 필드가 될 수 없습니다. 그리고 롤업은 수식 필드를 요약할 수 있지만, 그 수식이 다른 개체로 건너가지 않고 NOW()나 TODAY()처럼 스스로 바뀌는 함수를 쓰지 않을 때만입니다. TODAY()로 만든 “연체 일수” 수식은 아무도 레코드를 저장하지 않아도 매일 밤 바뀌므로, 롤업이 다시 계산할 근거가 없습니다. 그런 숫자에는 예약된 플로우나 보고서가 필요합니다.
  • 필터에도 한계가 있습니다. 긴 텍스트 영역, 다중 선택 선택 목록, 설명, 마지막 활동 같은 시스템 필드, 개체 간 수식, 조회 필드는 쓸 수 없습니다.
  • 롤업은 편집 페이지에 나오지 않으므로, 유효성 규칙이 롤업을 쓸 수는 있어도 그 오류를 거기에 보여 줄 수는 없습니다.

그리고 결정을 거꾸로 하지 마십시오. “롤업이 필요하니 마스터-세부 사항이어야 해요”라고 말하지 마십시오. “이 하위는 정말 이 상위에 속하고, 소유권과 생명주기가 맞으며, 이점 중 하나가 기본 롤업이다”라고 말하십시오. 의미가 맞지 않으면 계산은 다른 방법으로 푸십시오. 기능을 얻으려고 데이터 모델을 비틀지 마십시오.

그럼 다른 방법은 무엇일까요? 롤업을 직접 만드는 것입니다. 계산된 값을 담는 상위의 필드와 그것을 최신으로 유지하는 자동화입니다. 리테일 파트너가 배송에서 조회로 연결되어 있고(그래야 맞습니다), 비즈니스가 파트너에 미완료 배송 수를 원한다고 합시다. 파트너에 숫자 필드 Open Deliveries를 추가합니다. 그리고 레코드 트리거 플로우, 또는 양이나 로직이 코드를 요구할 때는 Apex 트리거가 배송이 바뀔 때마다 다시 계산합니다. 조회 위에서도 동작하고, 무엇으로든 필터링할 수 있으며, 기본 롤업이 못 쓰는 날짜와 수식도 쓸 수 있습니다.

하지만 이제 그것을 제대로 만드는 건 여러분의 몫이고, 바로 거기서 이런 것들이 잘못됩니다. 자동화는 중요한 모든 변경에서 실행되어야 합니다. 새 하위, 편집된 하위, 삭제된 하위, 복원된 하위, 그리고 다른 상위로 옮겨진 하위. 이 경우 이전 상위와 새 상위를 모두 다시 계산해야 합니다. 한 번에 200건씩 들어오는 데이터 로드를 한계에 걸리지 않고 처리해야 합니다. 더하고 빼지 말고 다시 세십시오. 그래야 이벤트 하나를 놓쳐도 숫자가 영원히 틀린 채로 남지 않습니다. 첫 로드와 값이 어긋나는 날을 위해 전부 다시 계산하는 방법을 계획하십시오. 그리고 이제 하위를 저장할 때마다 상위가 갱신된다는 걸 기억하십시오. 하위가 수천 건인 상위는 잠시 뒤 볼 잠금 문제를 다시 불러옵니다. 기본 롤업은 이 모든 것을 대신 해 줍니다. 직접 만든 롤업은 여러분이 소유하는 작은 소프트웨어입니다.

세 단계 깊이: 마스터-세부 사항 쌓기

섹션 제목: “세 단계 깊이: 마스터-세부 사항 쌓기 ”

플랫폼에는 형태가 있고, 마스터-세부 사항에는 그 형태의 두 가지 차원이 있습니다. 첫째는 깊이입니다.

마스터-세부 사항은 사용자 정의 세부 사항 세 단계까지 쌓을 수 있고, 거기가 바닥입니다(Considerations for Object Relationships (opens in a new tab)). 수업에서는 주문이 있는 계정(하나), 품목이 있는 주문(둘), 세부 내역이 있는 품목(셋)을 그리고, 네 번째를 추가하려 하면 Salesforce가 허락하지 않습니다. Steve Trucking에서는 이렇게 될 수 있습니다. 배송(Delivery)이 마스터이고, 그 배송 품목(Delivery Item)이 첫 번째 단계, 품목의 설치 작업(Install Task)이 두 번째, 각 작업의 작업 단계(Task Step)가 세 번째입니다. 네 번째 단계, 예를 들어 단계 메모(Step Note)는 조회여야 합니다.

마스터-세부 사항 세 단계 Steve Trucking에서 쌓아 올린 마스터-세부 사항 관계 세 개를 굵은 선으로 그린 그림입니다. 배송이 마스터입니다. 배송 품목이 세부 사항 1단계, 설치 작업이 2단계, 작업 단계가 3단계입니다. 네 번째 단계는 조회여야 하므로, 단계 메모는 가는 조회 선으로 작업 단계에 매달려 있습니다. 맨 아래: 소유권, 공유, 삭제는 배송에서 모든 단계로 흘러내려갑니다. 1단계 2단계 3단계 4단계는 조회 배송 Delivery__c · 마스터 배송 품목 Delivery_Item__c 설치 작업 Install_Task__c 작업 단계 Task_Step__c 단계 메모 Step_Note__c 소유권, 공유, 삭제는 배송에서 모든 단계로 흘러내려갑니다. 정확히 하나 0개 또는 1개 1개 이상 0개 이상 마스터-세부 사항 조회 © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

쌓을 때는 몇 가지 규칙이 따라옵니다.

  • 표준 개체는 사용자 정의 개체의 세부 사항 쪽에 올 수 없습니다. 사용자 정의 개체는 계정의 세부 사항이 될 수 있지만, 계정이 여러분 개체의 세부 사항이 될 수는 없습니다.
  • 개체는 다단계 스택에 한 번만 나올 수 있습니다. Salesforce는 스스로에게 되돌아오는 고리를 원하지 않습니다. 하위 세부 사항이 자기 마스터의 마스터가 될 수는 없습니다.
  • 마스터는 맨 아래 단계를 직접 롤업할 수 없습니다. 배송이 작업 단계 수를 원한다면, 설치 작업이 자기 단계를 롤업하고, 배송 품목이 그 롤업을 롤업하고, 배송이 품목을 롤업합니다. 한 번에 한 단계씩입니다.
  • 소유권과 공유는 맨 위에서 옵니다. 모든 단계가 마스터의 소유자와 접근을 물려받습니다.
  • 마스터를 삭제하면 그 아래 모든 것이 삭제되고, 복원하면 모든 것이 돌아옵니다.

보통은 세 단계로 충분합니다. 설계가 자꾸 네 번째를 원한다면, 모든 단계가 정말 평생 바로 위 단계에 속하는지 물으십시오. 그리고 어느 연결에서 사슬을 끊을지 여러분이 고를 수 있다는 걸 기억하십시오. 네 번째 단계가 조회일 필요는 없습니다. 어쩌면 설치 작업은 배송 품목에 정말 속하지 않을 수 있습니다. 따로 일정이 잡히고 따로 배정되니까요. 그러면 그 연결이 조회가 되고, 이제 설치 작업이 그 아래에 작업 단계와 단계 메모를 둔 새 사슬을 시작합니다. 하위에 정말 자기 생애가 있는 연결을 골라 그것을 조회로 만드십시오.

조회로 사슬 끊기 세 단계 쌓기와 같은 Steve Trucking 개체 다섯 개에서 가운데에 조회를 둔 그림입니다. 배송은 마스터이고, 배송 품목이 굵은 마스터-세부 사항 선으로 그 세부 사항입니다. 배송 품목은 사슬을 끊는 가는 조회 선으로 설치 작업에 연결됩니다. 설치 작업은 새 마스터입니다. 작업 단계가 그 세부 사항이고, 단계 메모가 작업 단계의 세부 사항이며, 둘 다 굵은 마스터-세부 사항 선입니다. 맨 아래: 이제 설치 작업에는 자기 소유자와 공유가 있고, 배송을 삭제해도 그 설치 작업은 더 이상 삭제되지 않습니다. 1단계 조회가 사슬을 끊음 1단계 2단계 배송 Delivery__c · 마스터 배송 품목 Delivery_Item__c 설치 작업 Install_Task__c · 새 마스터 작업 단계 Task_Step__c 단계 메모 Step_Note__c 이제 설치 작업에는 자기 소유자와 공유가 있고, 배송을 삭제해도 그 설치 작업은 더 이상 삭제되지 않습니다. 정확히 하나 0개 또는 1개 1개 이상 0개 이상 마스터-세부 사항 조회 © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

이제 설치 작업에는 자기 소유자와 자기 공유가 있고, 배송을 삭제해도 설치 작업이 함께 지워지지 않으며, 설치 작업 아래에 두 단계를 더 둘 수 있습니다. 그것이 맞바꾸는 것입니다. 사슬은 짧아지고, 설치 작업의 생애는 그 자신의 것이 됩니다.

두 상위 너비: Salesforce 연결 개체

섹션 제목: “두 상위 너비: Salesforce 연결 개체 ”

먼저 용어 이야기를 하겠습니다. “연결 개체”는 두 가지를 뜻하고, 저는 둘 다 가르치기 때문입니다.

2장에서 우리는 논리적 연결 개체를 찾았습니다. 두 핵심 개념이 만나는 지점이 자기 속성을 가진 독립된 대상이 되는 것입니다. 개 한 마리는 재주를 여럿 알고, 재주 하나는 여러 개가 압니다. 그 사이에 개 재주가 숙련도와 날짜를 담고 있습니다. 그것이 논리적 연결 개체이고, 논리 모델 안에 있으며, 누군가 조회냐 마스터-세부 사항이냐를 정하기 훨씬 전의 일입니다.

Salesforce는 이 용어를 더 좁게 씁니다. Salesforce가 연결 개체라고 말할 때는 마스터-세부 사항 관계 두 개를 가진 사용자 정의 개체를 뜻합니다(Create a Many-to-Many Object Relationship (opens in a new tab)). 저는 그것을 **Salesforce 연결 개체(Salesforce Junction Object)**라고 부르겠습니다. 모든 Salesforce 연결 개체는 논리적 연결 개체이지만, 모든 논리적 연결 개체가 Salesforce 연결 개체가 되지는 않습니다. 마스터-세부 사항 하나와 조회 하나, 또는 조회 두 개로 만들면 여전히 논리적 연결 개체이지만 Salesforce 방식의 연결 개체는 아닙니다. (Salesforce 자신도 완벽히 일관되지는 않습니다. 자체 개체 참조 문서는 조회로 만든 일부 표준 개체를 “연결 개체”라고 부릅니다. 시험에서는 좁은 정의를 가정하십시오.)

시험 포인트. Salesforce 연결 개체는 마스터-세부 사항 관계 두 개를 가진 사용자 정의 개체이고, Salesforce가 “연결 개체”라고 말할 때 뜻하는 것이 이것입니다. 논리적 연결 개체는 더 넓은 모델링 개념입니다. 어떻게 만들었든, 다대다로 다른 두 개체를 잇고 자기 속성을 담는 모든 개체입니다.

두 번째 차원은 너비입니다. 하위가 마스터-세부 사항 상위를 둘 가질 수 있을까요? 네. 셋은요? 아니요. 각 사용자 정의 개체는 마스터-세부 사항 관계를 최대 두 개까지 가질 수 있습니다(Considerations for Object Relationships (opens in a new tab)). 마스터-세부 사항 상위 둘이 다대다를 위한 Salesforce 연결 개체를 만드는 방법입니다. 배송팀과 트럭은 배송팀 배정에서 만나고, 2장에서 봤듯이 그것은 배관이 아닙니다. 날짜, 경로, 어쩌면 상태도 있습니다. 연결 개체는 관계가 비즈니스 개념이 되는 곳입니다. Salesforce가 알려 주는 만드는 요령은 이렇습니다. 무엇인지 말해 주는 이름을 붙이고, 레코드 이름을 자동 번호로 하고, 각 마스터의 관련 목록 이름을 다른 쪽 마스터로 바꾸십시오. 그러면 배송팀 페이지에는 “트럭”이, 트럭 페이지에는 “배송팀”이 보입니다(Create a Many-to-Many Object Relationship (opens in a new tab)).

여기가 까다로운 부분입니다. 두 상위 중 하나가 기본(primary) 상위이고, 그것은 마스터-세부 사항 필드를 먼저 만든 쪽입니다. 어느 쪽인지 화면에 아무 표시도 없으니, 전형적인 시험 문제이자 전형적인 놀람거리입니다.

기본 상위는 무엇을 결정할까요? 세 가지입니다(Create a Many-to-Many Object Relationship (opens in a new tab)).

  • 모양과 느낌. 연결 개체의 페이지는 기본 마스터의 색과 아이콘을 씁니다.
  • 소유자. 연결 레코드는 기본 마스터 레코드의 소유자를 물려받습니다. 세부 사항에는 소유자 필드가 없으니 보이지는 않습니다. 나중에 마스터-세부 사항 관계를 둘 다 제거할 때만 의미가 있습니다.
  • 디비전, org가 디비전을 쓴다면, 같은 방식입니다.

그리고 다른 하나는 보조(secondary) 상위입니다. 이것은 무슨 뜻일까요?

  • 다음 기본 상위 후보입니다. 기본 마스터-세부 사항 필드를 삭제하거나 조회로 바꾸면, 보조 상위가 기본 상위가 됩니다.
  • 보고서의 범위를 정합니다. Salesforce는 보고서 유형 두 개를 줍니다. “Primary master with junction object and secondary master”와 “Secondary master with junction object and primary master”입니다. 먼저 나오는 마스터가 보고서에 어떤 레코드가 나올 수 있는지를 정합니다.
  • 접근에서는 똑같이 중요합니다. 저는 이렇게 말합니다. 소유권은 기본 상위에서, 접근은 양쪽에서, 그리고 가장 제한적인 쪽이 이긴다. 연결 개체에는 다른 세부 사항처럼 자기 공유 테이블이 없습니다. Salesforce는 각 마스터-세부 사항 필드의 공유 설정을 통해 사용자의 양쪽 마스터 레코드 접근을 확인합니다. 둘 다 읽기/쓰기로 설정되어 있다면, 배송팀 배정을 편집하려면 배송팀 그리고 트럭 모두에 읽기/쓰기 권한이 있어야 합니다(Considerations for Object Relationships (opens in a new tab)).
  • 삭제에서도 똑같이 중요합니다. 배송팀이든 트럭이든 어느 마스터를 삭제해도 그 연결 레코드는 휴지통으로 갑니다. 둘 다 삭제하면 영구히 사라집니다.
연결 개체의 기본 상위와 보조 상위 마스터-세부 사항 상위 두 개 아래에 있는 연결 개체를 굵은 선으로 그린 그림입니다. 왼쪽 위의 배송팀은 마스터-세부 사항 필드를 먼저 만들었으므로 기본 상위이며, 배송팀 배정에 소유자와 모양을 줍니다. 오른쪽 위의 트럭은 보조 상위이며, 두 번째 보고서 유형의 범위를 정하고, 첫 번째 관계가 제거되면 기본 상위가 됩니다. 배송팀 배정은 둘 사이 아래쪽에 있습니다. 맨 아래: 접근에는 두 상위가 모두 필요하고 가장 제한적인 쪽이 이깁니다. 어느 상위든 삭제하면 배정도 함께 삭제됩니다. 소유자와 모양 보고서 범위 배송팀 Crew__c · 기본: 먼저 생성 트럭 Truck__c · 보조 배송팀 배정 Crew_Assignment__c 접근에는 두 상위가 모두 필요하고, 가장 제한적인 쪽이 이깁니다. 어느 상위든 삭제하면 배정도 함께 삭제됩니다. 정확히 하나 0개 또는 1개 1개 이상 0개 이상 마스터-세부 사항 © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

몇 가지 규칙이 더 있습니다. 두 마스터 모두 연결 개체에서 롤업 요약을 가질 수 있고, 연결 개체의 수식과 유효성 규칙은 양쪽 필드에 닿을 수 있습니다. 하지만 연결 개체는 다른 어떤 것의 마스터도 될 수 없으므로 스택 중간에 놓일 수 없고, 두 마스터가 같은 개체일 수도 없습니다. 개체에서 자기 자신으로 가는 다대다에는 다른 설계가 필요합니다. 그리고 상위에 연결 레코드가 200건 넘게 있고 연결 개체가 다른 상위로 롤업된다면, 충분히 지울 때까지 Salesforce는 그 상위를 삭제하게 두지 않습니다.

그러면 어느 상위가 기본이어야 할까요? 의미를 소유한 쪽을 먼저 만드십시오. 배송팀 배정에서는 일을 하는 것이 배송팀이니, 저라면 배송팀을 먼저 만듭니다. 그리고 그것을 기록해 두십시오. 화면의 어떤 것도 다음 사람에게 알려 주지 않으니까요.

그렇게 말했지만, 실제로 저는 Salesforce 연결 개체를 많이 만들지 않습니다. 보통 개체에는 마스터-세부 사항 상위가 하나 있고, 같은 종류의 데이터입니다. 고객 데이터 아래에 고객 데이터, 트랜잭션 아래에 트랜잭션(2장의 데이터 종류를 기억하십시오. 고객, 트랜잭션, 참조). 다른 상위가 다른 종류, 대개 참조 개체라면 그 관계는 조회입니다. 배송 품목은 자기 배송에 속합니다. 마스터-세부 사항이고, 둘 다 트랜잭션입니다. 실어 나르는 제품은 조회로 가리킵니다. 제품은 자기 생애를 가진 참조 데이터이고, 제품을 삭제했다고 수년간의 배송 이력이 함께 사라지길 바라는 사람은 없으니까요. 배송 품목은 여전히 배송과 거기 실린 제품 사이의 논리적 연결 개체입니다. 다만 Salesforce 연결 개체가 아닐 뿐입니다.

개체는 자기 자신과 관계를 맺을 수 있습니다. 상위 계정, 관리자, 지역 허브에 보고하는 물류 센터. Salesforce에는 거의 모든 org에서 만나게 될 두 가지가 기본으로 들어 있습니다. 계정 계층을 만드는 상위 계정 필드인 계정에서 계정, 그리고 관련 케이스를 묶는 모듈 2의 상위 케이스인 케이스에서 케이스입니다. 자기 관계는 조회여야 하고, 레코드는 자기 자신을 가리킬 수 없지만 두 레코드가 서로를 가리킬 수는 있습니다(Considerations for Object Relationships (opens in a new tab)). 사용자 개체에서는 그것이 별도의 특별한 유형인 계층 관계이고, 사용자의 관리자 같은 데 쓰입니다. 구현은 쉽고, 이름 붙이기가 중요합니다. 물류 센터에서 물류 센터로 가는 조회를 Distribution_Center__c라고 부르면 아무에게도 도움이 안 됩니다. 상위? 백업? 초과 물량? 가리키는 개체가 아니라 역할을 따라 관계에 이름을 붙이십시오.

자기 관계 개체 세 개가 각각 자기 자신으로 가는 조회를 가집니다. 계정은 ParentId 필드로 상위 계정을 가리키고, 이것이 계정 계층을 만듭니다. 케이스는 ParentId 필드로 상위 케이스를 가리킵니다. 사용자 정의 개체인 물류 센터는 Regional_Hub__c라는 필드로 지역 허브를 가리킵니다. 맨 아래: 언제나 조회이고, 같은 레코드를 가리키지 않으며, 맡은 역할을 따라 이름을 붙입니다. 상위 계정 상위 케이스 지역 허브 계정 Account · ParentId 케이스 Case · ParentId 물류 센터 Distribution_Center__c · Regional_Hub__c 언제나 조회이고, 같은 레코드를 가리키지 않으며, 맡은 역할을 따라 이름을 붙입니다. 정확히 하나 0개 또는 1개 1개 이상 0개 이상 조회 © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

이것은 작지만, 시험에 나올 법한 바로 그런 잘 알려지지 않은 유일무이한 사실입니다. 계층은 사용자 개체에만 있는 특별한 조회입니다. 한 사용자를 다른 사용자와 연결하며, Salesforce는 그 사슬이 되돌아오지 못하게 합니다. 사용자는 직접적으로도 간접적으로도 자기 자신을 가리킬 수 없습니다(Object Relationships Overview (opens in a new tab)). 마리아의 관리자가 데브라면, 데브의 관리자는 마리아일 수 없고, 마리아에게 보고하는 누구도 될 수 없습니다.

그것이 위의 자기 관계와 다른 점입니다. 계정이나 사용자 정의 개체에서는 두 레코드가 서로를 가리킬 수 있습니다. 사용자에서는 계층이 계층으로 남아야 합니다. 그리고 그것이 사용자와 사용자를 연결하는 유일한 방법입니다. 사용자에서 자기 자신으로 가는 일반 조회는 제공되지 않습니다.

여러분은 이미 하나를 갖고 있습니다. 사용자의 표준 관리자 필드가 계층 관계이고, 승인이 그것을 쓸 수 있습니다. 이 요청을 제출자의 관리자에게 보내라. 직접 만들 수도 있습니다. 예를 들어 에스컬레이션 담당자나 대리 승인자를 만들면, 승인이 같은 방식으로 그것을 따라 전달될 수 있습니다(ApprovalProcess, Metadata API (opens in a new tab)). 레코드 접근을 결정하는 역할 계층과 헷갈리지 마십시오. 계층 필드는 사용자 사이의 관계일 뿐이고, 레코드를 하나도 공유하지 않습니다.

시험 포인트. 계층 관계는 표준 관리자 필드처럼 사용자 개체에만 있고, 사용자는 직접적으로도 간접적으로도 자기 자신을 가리킬 수 없습니다. 역할 계층이 아닙니다.

개체마다 마스터-세부 사항 관계는 최대 두 개입니다. 조회와 마스터-세부 사항 필드를 합쳐 관계 필드로 셉니다. 개체당 기본 40개, 요청 시 최대 50개입니다. 롤업 요약 필드는 개체당 기본 25개, 최대 40개입니다(Increase the Maximum Relationships Allowed per Object (opens in a new tab), Increase the Maximum Limit of Roll-Up Summary Fields (opens in a new tab)). Salesforce는 어느 한계를 올리든 성능에 영향을 줄 수 있다고 덧붙입니다.

그 숫자에 맞춰 설계할 필요는 없고, 거기에 가까워질 때 알아차리면 됩니다. 관계가 줄줄이 매달린 개체는 무언가를 말해 주고 있습니다. 정말 그만큼 중심적인 개체일 수도 있습니다. 아니면 모델이 틀렸을 수도 있습니다. (그리고 18장의 여유 공간 규칙이 적용됩니다. 3년째를 기준으로 한계보다 한참 아래에 머무르십시오.)

그다음은 하위가 너무 많은 상위입니다. Salesforce 자체의 권장은 마스터-세부 사항 상위 하나에 하위 레코드 약 10,000건을 넘지 않는 것이고(Considerations for Object Relationships (opens in a new tab)), 대규모 레코드 접근에 대한 가이드도 상위-하위 관계 전반에 대해 같은 말을 합니다(Parent-Child Data Skew (opens in a new tab)). 10,001번째 레코드가 org를 망가뜨리지는 않습니다. 하지만 그 지점을 넘으면 하위를 저장할 때 상위가 잠길 수 있고, 상위의 공유 변경이 모든 하위로 파급됩니다.

그래서 상위 하나에 엄청난 수의 하위가 보이면 저는 묻습니다. 왜 모두 같은 상위 아래에 있는가, 누가 소유하는가, 어떻게 조회되는가, 어떤 자동화가 상위를 건드리는가? 모든 배송을 “Steve Trucking” 계정 하나 아래에 두면 며칠 만에 10,000건을 넘깁니다. 순진한 일대다가 스큐 문제가 됩니다. 다음 모듈에서 스큐를 미리 보고, 파트 2에서 깊이 다룹니다.

이 모듈에서 바라는 습관이 이것입니다. “롤업이 필요해”, “필수여야 해”, “공유를 물려받고 싶어”에서 시작하지 마십시오. 그것들은 구현의 단서입니다. 비즈니스에서 시작하십시오. 하위에 자기 생애가 있는가, 누가 소유하는가, 혼자 존재할 수 있는가, 옮겨 갈 수 있는가, 상위가 사라지면 어떻게 되는가, 관계가 데이터를 담는가, 양쪽이 각각 얼마나 커질 수 있는가? 그다음 그 답을 구현하는 관계를 고르십시오.

조회, 마스터-세부 사항, 연결 개체? 관계 패턴 세 가지를 비즈니스 질문 여섯 개에 대어 본 매트릭스입니다. 조회: 하위는 단독으로 존재할 수 있고, 자기 소유자가 있으며, 상위를 바꿀 수 있고, 상위당 하위가 10,000건을 넘어도 감당하지만 스큐는 여전히 주의해야 합니다. 기본적으로 상위와 함께 삭제되지 않고(필드가 지워지거나 삭제가 차단됨), 필드 하나에 상위 하나를 담습니다. 의미는 연결됨입니다. 마스터-세부 사항: 상위가 필수이고, 하위는 상위의 소유자를 상속하며, 상위와 함께 연쇄 삭제되고, 상위 레코드 재지정이 허용될 때만 상위를 바꾸며, 하위가 10,000건을 넘으면 상위 잠금과 재계산이 생깁니다. 의미는 속함입니다. Salesforce 연결 개체: 두 상위가 모두 필요하고, 소유자는 기본 상위에서 받으며, 어느 상위가 삭제되든 함께 삭제되고, 양쪽 모두 다수인 경우를 위한 유일한 패턴입니다. 의미는 비즈니스 개념입니다. 맨 아래: 비즈니스 질문에 먼저 답하면 관계 유형은 따라옵니다. 단독 존재 자기 소유자 상위와 함께 삭제 상위 변경 양쪽 모두 다수 상위당 10,000건 이상 의미 조회 배송 → 경로 기본값: 지우기 또는 차단 필드당 상위 하나 스큐는 여전히 주의 연결됨 마스터-세부 사항 배송 → 배송 품목 상위 필수 상위의 소유자 상속 연쇄 삭제 재지정 허용 시에만 필드당 마스터 하나 상위 잠금, 재계산 속함 Salesforce 연결 개체 배송팀 + 트럭 → 배송팀 배정 두 상위 모두 필요 기본 상위에서 어느 상위든 삭제 재지정 허용 시에만 그것이 본래 역할 같은 10,000건 권장 비즈니스 개념 비즈니스 질문에 먼저 답하십시오. 관계 유형은 따라옵니다. 원하는 기능에서 출발하지 마십시오. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

시험 너머: AI가 바꾸는 것. AI는 몇 초 만에 관계를 제안할 수 있습니다. 비즈니스가 언젠가 상위를 삭제할지는 말해 줄 수 없습니다. 다이어그램을 빨리 그린다고, 수백만 건의 레코드와 수십 개의 자동화가 의존하게 된 잘못된 관계를 되돌리는 비용이 줄지는 않습니다.

아키텍트가 여기서 결정하는 것

섹션 제목: “아키텍트가 여기서 결정하는 것 ”
  • 하위에 자기 생명주기가 있는지 정말 상위에 속하는지, 그리고 소유권과 접근이 자기 것이어야 하는지 물려받아야 하는지.
  • 하위가 상위 없이 존재하거나, 상위 사이를 옮겨 가거나, 상위 삭제 뒤에도 살아남을 수 있는지.
  • 각 조회가 상위 삭제 시 무엇을 하는지: 지우기, 막기, 연쇄 삭제.
  • 다대다가 배관인지 비즈니스 개념인지, 논리적 연결 개체가 Salesforce 연결 개체가 되는지, 어느 상위가 기본 상위인지, 그리고 두 상위가 접근에 무엇을 뜻하는지.
  • 모델이 플랫폼의 형태에 맞는지: 사용자 정의 세부 사항 세 단계 깊이, 마스터-세부 사항 상위 두 개 너비, 관계와 롤업의 한계.
  • 예상되는 하위의 수와 분포가 설계를 바꿔야 할 스큐 위험을 만드는지.

관계는 두 데이터가 함께 어떻게 동작할지에 대한 약속의 묶음입니다. 의도적으로 약속하십시오.