메타코딩 SNS프로젝트

21. 구독하기 - 연관관계 개념잡기

정현3 2022. 6. 20. 13:18

- 연관관계 개념

1.  FK(외래키)는 Many가 가져간다

2. N:N의 관계는 '중간 테이블'이 생긴다

- 구독하기

- 구독 취소하기

 

회원가입, 로그인, 회원정보 수정까지 마쳤다

이제 회원간의 '구독하기 기능'을 구현해 볼 차례이다

구독하기, 좋아요 같은 기능을 구현하기 위해선 우선 데이터 테이블간의 '연관관계'를 이해하는것이 우선이다.

'구독하기 기능'에서 우리가 할 것은 

첫째, 연관관계에 대한 개념을 이해하는것

둘째, '구독하기 기능'을 완성시키는것

셋째, 구독하기를 했으니 구독한것을 다시 '취소'하는 기능이다

 

board 테이블이 있고, user 테이블이 있다고 해보자

만약 blog를 만들때, 한명의 user가 게시글을 몇개 쓸 수 있는가? 당연히 여러개를 만들 수 있다

때문에 board는 N이고, user는 1인 관계이다.

그런데 반대로 하나의 게시글은 여러명의 user가 작성하는가? 아니다.

그래서 이 상황에서는 board도 1이고, user도 1인 관계이다.

이렇게 상황이 다른 관계가 맺어졌을땐, 더 큰쪽으로 본다.

N:1의 관계가 1:1의 관계가 양쪽에서 발생했을때, N:1로 본다는것이다.

 

이것을 JPA에서는 board위치는 N의 위치이므로 ManyToOne이라고 하고, user는 1의 위치이므로 OneToMany라고 본다.

위 사진과 같이 board에 id,title이 있고 그 안으로 데이터가 있다

그리고 user도 마찬가지로 id,username이 있고 그 안에 데이터가 있다

이런 상황에서는 N:1인데, FK(Foreign Key)는 누가 가지게 될까?

 

board의 1번 스키마인 id1, 내용1의 게시물을 어떤 user가 작성했는지 알 수 없고,

user의 1번 스키마인 id1,ssar가 어떤 게시물을 작성했는지도 알 수 없다.

 

하지만 user 1번인 ssar은 게시글을 1번 썼을수도 있고, 2번도 썼을수도 있다.

이럴때, 데이터베이스에 게시글 id를 1,2처럼 콤마를 넣어서 여러개의 데이터를 넣을 수 없다.

왜냐하면 '원자성'이 깨지기 때문이다.

'원자성'이라는것은 하나의 '컬럼'엔 하나의 '데이터'가 들어가야 한다는 것이다.

 

따라서 FK는 N의 관계인 board가 가지게 되어서 스키마마다 userId를 넣으면, 해당 게시글을 누가 적었는지, 그리고 해당 user는 어떤 게시글을 적었는지 알 수 있게 된다.

 

다른 예시를 들어보자

user테이블이 있고, 옆에는 Movie테이블이 있다.

이때 1명의 user는 몇개의 영화를 볼 수 있을까? 당연히 여러개의 영화를 볼 수 있다.

그렇다면 하나의 영화는 몇명이 볼 수 있을까? 이 역시 마찬가지로 여러명이 볼 수 있다

그렇다면 이렇게 N:N의 관계가 발생했을때엔 FK키를 누가 가지게 될까?

1명의 유저가 여러 영화를 다 볼 수 있고, 반대로 1개의 영화를 여러명이 시청할 수 있다

때문의 양쪽의 '원자성'이 깨지게된다.

'중간 테이블'이 생긴다면 관계를 다시 정립해야 된다

유저,예매,영화 3개의 테이블이 관계를 맺게 되는 것이기 때문이다.

 

그렇다면 1명의 유저는 한번에 몇개의 영화를 예매할 수 있는가? 당연히 여러개의 영화를 예매할 수 있다.

그렇다면 하나의 예매는 몇명의 유저가 할 수 있는가? 우리가 예매를 하면, 그 예매번호가 unique하게 존재하듯이 1명의 유저가 할 수 있다.따라서 유저가 1, 예매가 N의 관계가 성립하게된다.

1개의 영화는 몇개의 예매정보를 가질 수 있나? 당연히 여러개의 '예매정보'를 가질 수 있다. 

반대로 하나의 예매정보에는 몇개의 영화가 담겨있는가? 역시 하나의 예매정보에는 하나의 영화가 담긴다. 따라서 이 상황에서도 영화가 1, 예매가 N의 관계가 성립하게 된다

이런 예시를 보면 알겠지만 각 관계마다 공식이 존재한다

1. FK는 Many(N)이 가진다

2. N:M의 관계에서는 '중간테이블'이 생기며, N:1:M의 관계가 된다

그런데 우리가 할 '구독하기 기능'은 약간 기준이 다르다

왜냐하면  user테이블과 user테이블간의 관계, 즉 '같은 테이블간의 관계'이기 떄문이다.

-> M:N의 관계이니 '중간테이블'이 생긴다

우리는 이 '중간테이블'을 Subscribe 테이블이라고 명하겠다.

이 안에서도 똑같은 user테이블간의 관계를 정립하지만, '구독자'와 '피구독자'로 나누어 데이터를 받으면 '테이블 설계'가 가능하다

따라서 우리는 '구독하기(Subscribe) 테이블'을 만들어야 한다

그리고 당연히 N의 관계인 '구독하기 테이블'이 FK키를 가져야 한다.