Skip to main content
RelationsλŠ” Entity κ°„μ˜ μ—°κ΄€ 관계λ₯Ό μ •μ˜ν•˜μ—¬ λ°μ΄ν„°λ² μ΄μŠ€μ˜ μ°Έμ‘° 무결성을 보μž₯ν•˜κ³  νƒ€μž… μ•ˆμ „ν•œ 쑰인 쿼리λ₯Ό μž‘μ„±ν•  수 있게 ν•©λ‹ˆλ‹€.

Relation νƒ€μž… κ°œμš”

SonamuλŠ” 4κ°€μ§€ Relation νƒ€μž…μ„ μ§€μ›ν•©λ‹ˆλ‹€:

BelongsToOne

N:1 관계 - λ‹€μˆ˜κ°€ ν•˜λ‚˜λ₯Ό μ°Έμ‘° 예: Post β†’ User (μ—¬λŸ¬ κ²Œμ‹œκΈ€μ΄ ν•œ μ‚¬μš©μžμ—κ²Œ 속함)

OneToOne

1:1 관계 - μ„œλ‘œ ν•˜λ‚˜μ”©λ§Œ μ°Έμ‘° 예: User ↔ Employee (μ‚¬μš©μžμ™€ 직원 정보가 1:1 λ§€μΉ­)

HasMany

1:N 관계 - ν•˜λ‚˜κ°€ μ—¬λŸΏμ„ μ†Œμœ  예: User β†’ Posts (ν•œ μ‚¬μš©μžκ°€ μ—¬λŸ¬ κ²Œμ‹œκΈ€ μ†Œμœ )

ManyToMany

N:M 관계 - λ‹€λŒ€λ‹€ 관계 예: Post ↔ Tag (κ²Œμ‹œκΈ€κ³Ό νƒœκ·Έμ˜ λ‹€λŒ€λ‹€ 관계)

BelongsToOne

N:1 관계 - ν˜„μž¬ Entityκ°€ λ‹€λ₯Έ Entity에 μ†ν•˜λŠ” κ΄€κ³„μž…λ‹ˆλ‹€.

κΈ°λ³Έ μ‚¬μš©λ²•

post.entity.json
μƒμ„±λ˜λŠ” 컬럼: user_id (integer, not null) λ°μ΄ν„°λ² μ΄μŠ€ ꡬ쑰:

μ˜΅μ…˜

RelationOn μ˜΅μ…˜

예제: nullable과 CASCADE

λ™μž‘:
  • department_idκ°€ NULL ν—ˆμš©
  • λΆ€μ„œκ°€ μ‚­μ œλ˜λ©΄ μ§μ›μ˜ department_idκ°€ NULL둜 섀정됨

TypeScript μ‚¬μš©

OneToOne

1:1 관계 - 두 Entityκ°€ μ„œλ‘œ ν•˜λ‚˜μ”©λ§Œ μ°Έμ‘°ν•˜λŠ” κ΄€κ³„μž…λ‹ˆλ‹€.

κΈ°λ³Έ μ‚¬μš©λ²•

OneToOne은 두 κ°€μ§€ λ°©μ‹μœΌλ‘œ μ •μ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€:
ν˜„μž¬ Entity에 FK 컬럼이 μƒμ„±λ©λ‹ˆλ‹€.
employee.entity.json
μƒμ„±λ˜λŠ” 컬럼: user_id (integer, unique, not null)λ°μ΄ν„°λ² μ΄μŠ€ ꡬ쑰:

μ˜΅μ…˜

예제: μ–‘λ°©ν–₯ OneToOne

관계 μ„€λͺ…:
  • UserλŠ” Employeeλ₯Ό μ„ νƒμ μœΌλ‘œ κ°€μ§ˆ 수 있음 (nullable)
  • EmployeeλŠ” λ°˜λ“œμ‹œ Userλ₯Ό κ°€μ Έμ•Ό 함 (not null)
  • Userκ°€ μ‚­μ œλ˜λ©΄ Employee도 ν•¨κ»˜ μ‚­μ œλ¨ (CASCADE)

HasMany

1:N 관계 - ν•˜λ‚˜μ˜ Entityκ°€ μ—¬λŸ¬ 개의 λ‹€λ₯Έ Entityλ₯Ό μ†Œμœ ν•˜λŠ” κ΄€κ³„μž…λ‹ˆλ‹€.

κΈ°λ³Έ μ‚¬μš©λ²•

user.entity.json
쑰건:
  • Post Entity에 user_id 컬럼이 μžˆμ–΄μ•Ό 함
  • 보톡 Postμ—μ„œ BelongsToOne으둜 μ—­λ°©ν–₯ μ •μ˜

μ˜΅μ…˜

예제: fromColumn μ‚¬μš©

JOIN 쿼리:

TypeScript μ‚¬μš©

HasManyλŠ” DataLoader νŒ¨ν„΄μœΌλ‘œ μžλ™ μ΅œμ ν™”λ©λ‹ˆλ‹€. N+1 쿼리 λ¬Έμ œκ°€ λ°œμƒν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

ManyToMany

N:M 관계 - λ‹€λŒ€λ‹€ 관계λ₯Ό 쀑간 ν…Œμ΄λΈ”(Join Table)을 톡해 κ΅¬ν˜„ν•©λ‹ˆλ‹€.

κΈ°λ³Έ μ‚¬μš©λ²•

post.entity.json
μžλ™ μƒμ„±λ˜λŠ” Join Table:

μ˜΅μ…˜

Join Table 넀이밍 κ·œμΉ™: 두 ν…Œμ΄λΈ”λͺ…을 μ•ŒνŒŒλ²³ 순으둜 μ •λ ¬ν•˜μ—¬ __둜 μ—°κ²°ν•©λ‹ˆλ‹€. - μ˜¬λ°”λ₯Έ 예: posts__tags - 잘λͺ»λœ 예: tags__posts (μ•ŒνŒŒλ²³ 순 μ•„λ‹˜)

μ–‘λ°©ν–₯ μ •μ˜

TypeScript μ‚¬μš©

Custom Join Clause

λ³΅μž‘ν•œ JOIN 쑰건이 ν•„μš”ν•œ 경우 SQL ν‘œν˜„μ‹μ„ 직접 μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
customJoinClauseλŠ” κ³ κΈ‰ κΈ°λŠ₯μž…λ‹ˆλ‹€. κ°€λŠ₯ν•˜λ©΄ ν‘œμ€€ Relation을 μ‚¬μš©ν•˜μ„Έμš”.

Relation ν™œμš© νŒ¨ν„΄

1. Subsetμ—μ„œ Relation ν•„λ“œ 선택

μžλ™ μƒμ„±λ˜λŠ” 쿼리:
  • user: LEFT JOIN
  • tags: DataLoader둜 별도 쿼리

2. 쀑첩 Relation

Sonamuκ°€ μžλ™μœΌλ‘œ ν•„μš”ν•œ JOIN을 μƒμ„±ν•©λ‹ˆλ‹€:

3. Relation 필터링

4. Relation μ •λ ¬

Relation 섀계 κ°€μ΄λ“œ

BelongsToOne vs OneToOne

CASCADE vs RESTRICT

nullable μ„€μ •

μ£Όμ˜μ‚¬ν•­

μˆœν™˜ μ°Έμ‘° λ°©μ§€A β†’ B β†’ C β†’ A 같은 μˆœν™˜ μ°Έμ‘°λŠ” ν”Όν•˜μ„Έμš”. 데이터 생성 μ‹œ λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.
JOIN 깊이 μ œν•œλ„ˆλ¬΄ κΉŠμ€ 쀑첩 Relation (3단계 이상)은 μ„±λŠ₯ 문제λ₯Ό μΌμœΌν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€. ν•„μš”ν•œ 경우 별도 쿼리둜 λΆ„λ¦¬ν•˜μ„Έμš”.
ManyToMany Join TableJoin Table은 Sonamuκ°€ μžλ™μœΌλ‘œ κ΄€λ¦¬ν•˜λ―€λ‘œ λ³„λ„μ˜ Entityλ₯Ό λ§Œλ“€ ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€. μΆ”κ°€ 컬럼이 ν•„μš”ν•œ κ²½μš°μ—λ§Œ 별도 Entity둜 λΆ„λ¦¬ν•˜μ„Έμš”.

λ‹€μŒ 단계

Enums

Enum νƒ€μž… μ •μ˜ν•˜κ³  ν™œμš©ν•˜κΈ°

Subset

Subset을 ν™œμš©ν•œ νƒ€μž… μ•ˆμ „ν•œ 쿼리

Puri Query Builder

Relation을 ν™œμš©ν•œ 쿼리 μž‘μ„±ν•˜κΈ°

Performance

Relation 쿼리 μ΅œμ ν™”ν•˜κΈ°