· 오늘 공부한 것
기술면접 질문 2가지
최종 프로젝트 모집글 작성 기능
· 공부한 내용, 궁금한 내용, 부족한 내용
오늘의 기술면접 질문 2가지는 다음과 같다.
- RDBMS의 정규화에 대해 설명해 주세요.
- 테이블 간에 중복된 데이터를 허용하지 않는다는 것으로 이를 함으로써 무결성을 유지할 수 있고 DB의 저장 용량을 줄일 수 있다.
- 제1 정규화는 테이블의 칼럼이 원자값을 갖도록 테이블을 분해하는 것이다.
- 제2 정규화는 제1 정규화를 진행한 테이블에 대해 완전 함수 종속을 만족하도록 테이블을 분해하는 것이다.
- 제3 정규화는 제2 정규화를 진행한 테이블에 대해 이행적 종속을 없애도록 테이블을 분해하는 것이다.
- BCNF 정규화는 제3 정규화를 진행한 테이블에 대해 모든 결정자가 후보키가 되도록 분해하는 것이다.
- Primary Key, Foreign Key에 대해 설명해 주세요.
- PK는 데이터베이스에서 각 데이터를 고유하게 식별하는 용도로 사용하는 기본 키이다.
- FK는 다른 테이블에 있는 기본 키를 참조해서 사용할 때 쓰이는 키이다.
오늘은 어제 entity를 만든 것을 가지고 모집글 작성 기능을 구현했다. 아직 인증된 유저 정보를 추가하지 않았기 때문에 제외하고 진행했다. 그리고 작성할 때 post테이블 말고 관련된 테이블이 2개 더 있었기 때문에 저장된 post를 가지고 다른 테이블에 저장하는 과정을 거쳤다. 하지만 아직 정해지지 않은 부분이 있다. postStack, jobLimit 테이블이 과연 분리할 필요가 있는지가 해결되지 않았다. 만약 분리를 하면 받은 배열데이터를 가지고 반복문으로 테이블을 저장해 주면 되고 만약 분리하지 않고 칼럼에 포함시키면 save()를 한 번만 진행하면 된다. 하지만 나중에 수정 부분이 있을 때 테이블이 분리되지 않으면 역시나 반복문을 거치게 된다. 그렇기 때문에 내일 튜터님과 팀원들이 모여 정하기로 하였다. 그래서 일단 분리한 경우로 로직을 구성했다.
API 명세서
기능 | method | URL | request | response |
모집글 작성 | POST | /v1/posts | { ”title”: “title”, ”content”: “content”, ”deadline”: “2024.02.01”, ”jobLimits”: [{ ”job”: “BACKEND”, ”headcount”: 3 }], ”skills”: [”JAVA”, “SPRING”, “KOTLIN”] } ”image”: “image” (multipartfile) |
{ ”postId”: 1 } |
Controller
@PostMapping
public RestResponse<PostCreateRes> createPost(
@RequestBody PostCreateReq postCreateReq) { // 인증된 유저 정보 추가
return RestResponse.success(postService.createPost(postCreateReq));
}
Service
public PostCreateRes createPost(PostCreateReq postCreateReq) {
// postCreateReq로 들어온 값들에 대한 검증
// title, content, deadline => validation 진행
// skills 테이블 분리하지 않고 문자열 배열 형식 (회의후 진행)
// image 처리 분리 => 저장소url 가져오기
Post savedPost =
postRepository.save(
Post.builder()
.title(postCreateReq.getTitle())
.content(postCreateReq.getContent())
.deadline(postCreateReq.getDeadline())
.status(Status.OPEN)
.visit(0L)
.imageUrl(postCreateReq.getImage())
.build());
// 저장된 post로 postStack에도 저장
// 테이블 분리할 경우 => for문으로 들어온 값 수만큼 저장 (보류)
// Post테이블에 저장할 경우 들어온 값 그대로 저장 => 위에서 컬럼만들어서 진행
// 저장된 post로 jobLimit에도 저장
postCreateReq
.getJobLimitList()
.forEach(
jobLimit -> {
jobLimitRepository.save(
JobLimit.builder()
.job(jobLimit.getJob())
.headcount(jobLimit.getHeadcount())
.post(savedPost)
.build());
});
return PostServiceMapper.INSTANCE.toPostCreateRes(savedPost);
}
그리고 이번에 @Mapper를 사용하게 되었는데 항상 @Builder나 new 생성자로 했던 경우와 다른 경험을 하게 되었다. builder의 경우 무엇으로 해당 객체가 구성되는지 눈으로 볼 수 있어서 파악하기 좋은 장점이 있었고 mapper의 경우는 해당 객체를 가지고 원하는 target 객체에 맵핑이 알아서 되는 형식이어서 좋았다. 특히 지금 우리가 api마다 req와 res를 1개씩 설정하기로 했는데 mapper를 통해서 target으로 res마다 지정만 해주면 되었기에 사용하는데 장점이 있었다.
더 알아야 할 부분은 예외설정하는 로직에 대한 이해와 image 데이터를 받아서 url로 받아오는 과정이다. 일단 지금 로직에서는 imageUrl를 받아온 값으로 그대로 넣고 있는데 받아온 데이터를 s3와 같은 곳에 저장하고 url정보를 받아와서 저장하는 과정이 필요하다. 아직 전체조회 같은 경우는 저녁에 정해지기 때문에 그전까지 단건조회, 수정, 삭제를 해야 할 텐데 이 부분들에도 알아가야 할 부분들이 많다고 생각한다.
· 오늘 서칭 한 자료
https://mangkyu.tistory.com/110
https://datarian.io/blog/type-of-keys-in-relational-model
· 느낀 점
- 아직 초기 설정이 확실하게 정해지지 않았지만 로직을 짜면서 모든 경우를 생각하면서 구현해야 한다.
- 코드로 작성을 하지 못하더라도 주석을 이용해서 남겨놓으면 나중에 리팩터링 할 때 도움이 된다.
- 코드를 작성하면서 커밋을 자주 하고 기능별로 pr를 하면 좋을 거 같다. pr를 너무 많은 것을 진행하고 하면 다른 팀원들이 코드리뷰하기 힘들고 통합할 때도 문제가 여러 곳에서 발생할 수 있다.
'Today I Learned' 카테고리의 다른 글
2024-01-10 TIL 기술면접, 최종프로젝트(4) (0) | 2024.01.10 |
---|---|
2024-01-09 TIL 최종프로젝트(3) (0) | 2024.01.10 |
2024-01-05 TIL 기술면접, 최종프로젝트(1) (0) | 2024.01.05 |
2024-01-03 TIL 업무 관리 시스템 팀프로젝트(KPT회고) (0) | 2024.01.03 |
2023-12-28 TIL 업무 관리 시스템 팀프로젝트(3) (0) | 2023.12.29 |