관계란
데이터베이스의 테이블은 서로 관련되어 있는 경우가 많습니다. 예를 들어 블로그 게시물에는 다수의 댓글이 있거나, 주문은 그것을 수행한 사용자와 관련되어 있습니다. Eloquent는 이러한 테이블 간의 관계를 간단하게 정의·조작할 수 있는 구조를 제공합니다. 관계는 Eloquent 모델의 메서드로 정의합니다.이 페이지에서는
User, Post, Comment, Tag 같은 구체적인 모델을 예로 사용합니다.
이 모델들과 테이블은 미리 생성되어 있다는 전제로 진행합니다.hasOne(1대1)
hasOne은 한 모델이 다른 모델을 하나만 가지는 관계를 나타냅니다. 예를 들어 User가 하나의 Profile을 가지는 경우입니다.
관계 정의
User 모델에 profile 메서드를 정의합니다.
profiles 테이블에 user_id 컬럼이 있다고 가정합니다.
관련 데이터 가져오기
정의된 관계는 프로퍼티로 접근할 수 있습니다.belongsTo(1대1의 역방향)
belongsTo는 hasOne의 역방향으로, 외래 키를 가진 쪽의 모델에 정의합니다. Profile이 User에 속하는 관계를 나타냅니다.
관계 정의
_id를 붙인 컬럼명(이 경우 user_id)을 외래 키로 사용합니다.
관련 데이터 가져오기
hasMany(1대다)
hasMany는 하나의 부모 모델이 여러 자식 모델을 가지는 가장 자주 사용되는 관계입니다. 예를 들어 하나의 Post가 여러 Comment를 가지는 경우입니다.
관계 정의
comments 테이블에 post_id 컬럼이 있다고 가정합니다.
관련 데이터 가져오기
hasMany의 관계는 컬렉션을 반환합니다.
역방향 관계(belongsTo)
댓글에서 게시물을 참조하려면Comment 모델에 belongsTo를 정의합니다.
belongsToMany(다대다)
다대다 관계는 양쪽 모델이 서로 여러 관련을 가지는 경우에 사용합니다. 예를 들어Post가 여러 Tag를 가지고, Tag도 여러 Post에 속하는 경우입니다.
테이블 구조
다대다에는 중간 테이블이 필요합니다.Post와 Tag의 경우 post_tag라는 중간 테이블을 준비합니다.
중간 테이블명은 Eloquent가 관련된 두 모델명을 알파벳 순으로 결합해 자동으로 추측합니다(
post + tag → post_tag).관계 정의
Tag 쪽에도 동일하게 정의함으로써 역방향에서도 참조할 수 있습니다.
관련 데이터 가져오기
관련 데이터 추가·삭제
attach로 중간 테이블에 레코드를 추가하고, detach로 삭제합니다.
Eager 로딩
N+1 문제란
관계를 프로퍼티로 접근하면 Eloquent는 그때마다 쿼리를 발행합니다. 이를 “지연 로드(Lazy Loading)“라고 합니다. 루프 안에서 관계에 접근하면 N+1 문제가 발생합니다.with()에 의한 Eager 로딩
with() 메서드를 사용하면 관련 데이터를 한 번에 가져올 수 있습니다. 이를 통해 쿼리는 2회만으로 억제됩니다.
여러 관계를 동시에 Eager 로드
배열로 여러 관계를 지정할 수 있습니다.중첩된 Eager 로드
점 표기법으로 중첩된 관계도 Eager 로드할 수 있습니다.다음 단계
Eloquent 입문
Eloquent의 기본 CRUD 조작으로 돌아가 복습합니다.