관계 — 엔티티 두 개를 잇고 카디널리티 정하기
빌더 캔버스에서 소스 엔티티에서 타겟 엔티티로 드래그해 관계를 만들고, 명명 규칙(verb_phrase) · 카디널리티(1:1 · 1:N · N:N) · 기반 데이터셋(backing dataset) 매핑까지 닫습니다. 예시는 리테일 공급망의 세 관계.
엔티티 두 개를 정의했다고 그래프가 되지는 않습니다. 두 엔티티가 어떤 의미로 이어지는지를 명시한 순간 비로소 그래프입니다. 본 레슨은 그 의미 — 관계(Relationship) — 를 빌더 캔버스에서 한 번에 만들어 봅니다. 예시는 리테일 공급망 시나리오의 4 엔티티 · 3 관계 구조 (RI_Product, RI_Branch, RI_Region, RI_Supplier + RI_STOCKED_AT, RI_LOCATED_IN, RI_SUPPLIED_BY).
사전 준비
- 직전 두 레슨의 흐름으로, 자기 컬렉션 안에 두 개 이상의 엔티티가 정의돼 있고 각자 기반 데이터셋 매핑이 끝난 상태.
- 빠른 진입을 원한다면
dhub2-examples의retail_inventory_intelligence시나리오를 import 해 네 엔티티가 이미 떠 있는 상태에서 시작.
빌더 캔버스에 두 엔티티 노드가 보이는 시점에서 시작합니다.
캔버스에서 드래그로 관계 만들기
- 소스 엔티티 노드(
RI_Product)의 테두리에 마우스를 올리면 작은 연결 핸들(점)이 보입니다. - 핸들을 클릭해 그대로 타겟 엔티티 노드(
RI_Branch)까지 드래그합니다. - 손을 떼면 Create Relationship 대화상자가 열립니다.
이 대화상자가 다음 다섯 영역의 입력을 한 자리에 모읍니다.
1. Source / Target — 방향성
- Source Entity — 관계의 시작점 (주체).
- Target Entity — 관계의 끝점 (대상).
방향성은 문법적 주어/목적어에 맞춥니다. 리테일 예시:
RI_Product -[RI_STOCKED_AT]-> RI_Branch— 상품이 지점에 보관됨.RI_Branch -[RI_LOCATED_IN]-> RI_Region— 지점이 지역에 위치함.RI_Product -[RI_SUPPLIED_BY]-> RI_Supplier— 상품이 공급업체로부터 공급됨.
방향을 거꾸로 두면 Cypher 쿼리가 어색해집니다(RI_Branch -[CONTAINS]-> RI_Product 식으로 다시 잡아야 함). 한 번 정한 방향은 다음 레슨의 그래프 탐색기에서 바로 영향을 보이므로 초기 결정을 신중하게.
2. Type — Cypher 에 그대로 쓰이는 이름
- Type — 관계의 시스템 이름. 대문자 + UPPER_SNAKE_CASE + verb_phrase 가 표준. Cypher 쿼리에서
:TYPE로 그대로 노출됩니다. - 좋은 예:
STOCKED_AT,LOCATED_IN,SUPPLIED_BY,PURCHASED,MANAGES. - 피해야 할 예:
Stocked_at(대소문자 혼용),stock(명사형 — 행위가 아니라 상태처럼 보임),RELATES_TO(의미 없음).
도메인 접두어를 두는 쪽이 권고되는 경우가 많습니다(예: RI_STOCKED_AT, IOT_reads_from). 한 컬렉션 안에서도 슬러그 충돌 가능성을 줄이고, 글로벌 검색에서 어느 도메인의 관계인지가 시각적으로 분리됩니다.
3. Alias / Description — 자연어 라벨
- Alias — 사용자에게 보여줄 1차 라벨. 자연어 그대로(
재고 위치,지역 위치,공급). - Description — 한 줄 자연어 설명. AI 자동 생성 버튼이 있지만, 본인 도메인 단어가 6 개월 뒤 본인을 살려 줍니다.
UI 1차 타이틀은 alias, 부제목은 시스템 type.
4. Schema — Identity Keys / Display Column
관계도 엔티티와 동일한 스키마 메타데이터를 가질 수 있습니다.
- Identity Keys — 관계 인스턴스를 고유 식별하는 키 컬럼들. 파이프라인의 Relation I/O 사용 시 필수.
- Display Column — 관계 인스턴스의 라벨.
관계의 스키마는 관계 자체의 속성입니다. 리테일 예시의 RI_STOCKED_AT 은 단순한 연결선이 아니라 다음 같은 속성을 가집니다.
inventory_qty(현재 재고 수량)inventory_turnover_rate(회전율)selling_price_krw_synth,safety_stock_level,stockout_risk_flag_synth- 그 외 가격/할인/프로모션 관련 다수
반면 RI_LOCATED_IN, RI_SUPPLIED_BY 두 관계는 연결 자체가 의미의 전부라 schema fields 가 비어 있습니다 — 둘 다 정상.
5. 기반 데이터셋 — 관계도 매핑 가능
관계가 스키마 fields 를 가진다면 그 행들이 어디에서 오는지 기반 데이터셋으로 잇습니다. 흐름은 엔티티 매핑과 같습니다.
- 관계 인스펙터의 Data Source 탭.
- 같은 컬렉션의 데이터셋 선택 (예:
RI_STOCKED_AT←stock_levels데이터셋). - 관계 속성과 데이터셋 컬럼을 1:1 매핑.
- Identity Keys 매핑을 명시 — 행 단위 조회가 가능해짐.
매핑이 끝나면 매핑한 데이터셋의 References 탭에 이 관계가 자동 등록됩니다. sink 는 매핑 시점에 자동으로 동작합니다(별도 UI 없음, 직전 레슨과 동일).
카디널리티 — 1:1 · 1:N · N:N
관계 인스펙터의 Constraints 영역에서 카디널리티를 명시합니다.
| 카디널리티 | 의미 | 리테일 예시 |
|---|---|---|
| 1:1 | 한 소스 인스턴스가 정확히 한 타겟에만 연결 | 거의 없음 |
| 1:N | 한 소스가 여러 타겟에 연결, 한 타겟은 한 소스로만 | RI_LOCATED_IN — 지점 한 개는 한 지역에만 위치, 지역 한 개는 여러 지점을 가짐 |
| N:N | 양쪽 모두 여러 인스턴스에 연결 | RI_STOCKED_AT — 한 상품이 여러 지점에, 한 지점에 여러 상품이; RI_SUPPLIED_BY — 한 상품이 여러 공급업체로부터, 한 공급업체가 여러 상품을 |
카디널리티는 검증 신호입니다. 잘못 잡으면 빌더의 유효성 검사 패널이 경고를 띄우거나 Cypher 결과가 의도 외 패턴을 보입니다.
Self-reference — 같은 엔티티 안의 관계
엔티티가 자기 자신과의 관계를 가질 수 있습니다. 흔한 예:
Person -[MANAGES]-> Person— 사원이 다른 사원을 관리.RI_Product -[SUBSTITUTES]-> RI_Product— 상품이 다른 상품의 대체재.
Self-reference 관계는 그래프 탐색기에서 루프 엣지로 시각화됩니다. 트리/위계 구조를 다룰 때 자주 등장합니다.
빠른 점검 — 4 엔티티 · 3 관계
리테일 예시의 끝 상태를 캔버스에서 확인하면 다음과 같이 보입니다.
RI_Region
▲ RI_LOCATED_IN (1:N)
│
RI_Branch
▲ RI_STOCKED_AT (N:N)
│
RI_Product ──RI_SUPPLIED_BY (N:N)──▶ RI_Supplier
본 레슨 끝에서 위와 동일한 형태가 본인 컬렉션 위에 보여야 합니다.
자가 점검
- 캔버스에서 두 엔티티 사이에 화살표(엣지) 가 한 개 이상 보이는가
- 관계 type 이 UPPER_SNAKE_CASE + verb_phrase 인가
- alias 가 자연어로 채워져 있어 노드 라벨이 어색하지 않은가
- 관계가 스키마 fields 를 가진다면 기반 데이터셋 매핑이 끝났는가
- 카디널리티 한 줄이 정해져 있는가
다음 레슨
다음 레슨은 지금까지 정의한 4 엔티티 · 3 관계가 그래프 탐색기에서 어떻게 인스턴스로 보이는지 직접 확인합니다. 라벨 클릭, 더블클릭 이웃 확장, Cypher 세 줄 패턴(MATCH · RETURN · LIMIT)까지.