블로그
전체 32025. 03. 23.
0
[인프런 워밍업 클럽 3기 / 백엔드 프로젝트] 3주차 정리
공부 내용 정리이번주에는 GET 요청을 제외한 나머지의 요청들을 개발 (어드민 서비스)에 대해 공부하고 이에 Exception에 일관성있게 처리가능하도록 하는 법을 배웠습니다.그래서 이번 글에서는 Exception 처리에 대해서 정리해보았습니다. 커스텀 예외처리 순서1. 커스텀 예외 클래스 계층 정의2. 각 예외 상황에 맞는 구체적인 커스텀 예외 클래스 생성3. 예외 발생 시 @RestControllerAdvice를 통해 공통적으로 처리4. 적절한 HTTP 상태 코드와 메시지를 클라이언트에게 반환 이러한 구조를 통해 비즈니스 로직에서 의미 있는 예외를 던지고, 사용자에게 명확한 메시지와 상태 코드로 응답할 수 있었습니다. 내용 abstract class MementoCapsException 모든 커스텀 예외의 공통 부모 클래스 정의httpStatus를 저장하여 어떤 HTTP 상태 코드로 응답할지를 정의RuntimeException을 상속받아 체크 예외가 아닌 언체크 예외 class MementoCapsNotFoundException(message: String) 각각의 예외 상황에 맞는 클래스들이 MementoCapsException을 상속받아 정의프로젝트에서 발생할 수 있는 예외인 NOT_FOUND, BAD_REQUEST, FORBIDDEN, INTERNAL_SERVER_ERROR 에 대해 정의했으며 각각 파라미터로 넘겨받은 메시지를 부모클래스의 메시지로 넘겨주었습니다.class PresentationApiControllerAdvice@RestControllerAdvice 를 선언한 예외처리 컨트롤러 입니다애플리케이션 전역에서 발생한 익셉션은 해당 컨트롤러로 넘겨받아 처리하게됩니다.클래스 안에 @ExceptionHandler 를 가진 함수를 선언하여 예외 타입에 따라 다른 처리 로직을 실행하였습니다. 미션 5미션 5는 삽입, 수정, 삭제 REST API를 만들어 각각 테스트케이스를 3개 이상씩 만들어 제출하는 것 이였습니다. 해당 프로젝트에서는 중심적인 데이터 베이스 엔티티의 관계가 N:M 관계로 이루어져있었습니다.따라서 중간에 연결 테이블 엔티티가 존재했습니다. 그래서 처음 저장 로직을 작성할때 다음과 같은 고민이 생겼습니다. 문제 상황타임캡슐을 처음 생성하면 해당 캡슐의 작성자가 OWNER 로써 관계 테이블 (User_Capsule)에 등록되어야 했습니다.즉 타임캡슐 테이블 데이터 생성과 동시에 작성자_캡슐 테이블의 데이터도 저장되어야 했습니다.이때 처음에는 Capsule 엔티티에서 생성자 파라미터로 writer: User를 넘긴 뒤, 내부에서 작성자 정보를 UserCapsule로 매핑하는 방식을 사용했습니다.하지만 실제로 제가 설계한 테이블은 Capsule 엔티티에는 writer 필드가 존재하지 않고, UserCapsule(role = OWNER)로만 작성자를 식별하는 구조였기에 구조와 맞지않고, 엔티티의 책임이 커진다는 느낌을 받아 수정해보았습니다. 해결 방법UserCapsule은 capsule.id, user.id가 모두 필요한 관계이므로 캡슐을 먼저 저장 → 관계를 이후에 저장하는 방식이 더 명확하다고 판단했습니다.따라서 변경된 저장 순서는 다음과 같습니다. 캡슐 생성 로직 실행 1. 캡슐 테이블에 (작성자 정보 없이 순수한 캡슐 데이터만 있는) 캡슐 정보 저장 2. 입력받은 작성자 아이디를 가지고 user 테이블에서 user 정보 얻기 3. 저장된 캡슐 데이터에서 방금 작성한 캡슐 정보 얻기 4. 캡슐정보와 유저 정보를 매핑 (Role = OWNER)후 저장 이렇게 하게되면 UserCapsuleRepository의 save 로 멤버와 작성자 모두 처리가 가능합니다. 즉 서비스 단에서 "캡슐 저장"이라는 비지니스 로직은 다음과 같이 정의됩니다. 캡슐 데이터를 저장한다. 작성자 데이터를 가져온다. 캡슐 데이터와 작성자 데이터를 매핑하여 OWNER라는 Role 값으로 유저캡슐 데이터에 저장한다. 이렇게 구조를 바꾸니 멤버를 추가할때도 엔티티의 책임은 덜어내고 비슷한 방식으로 처리가 가능했습니다. 캡슐 데이터를 불러옵니다. 초대된 사용자 데이터를 불러옵니다. 두 데이터를 매핑하여 MEMBER 라는 Role 값으로 유저 캡슐 데이터에 저장합니다. 이렇게 정립한 의존성 규칙을 유지하며 나머지 기능들도 작성할 수 있었습니다. 테스트 코드 작성테스트 코드는 예외처리에 정의된 부분들에 대해서 테스트 할 수 있었습니다.정상적인 데이터 처리 케이스Vaild에 위반되어 400 에러가 발생하는 케이스url Path에 들어갈 값을 잘못 전달하여 404에러가 발생하는 케이스request Body값이 잘못 전달되어 400 에러가 발생하는 케이스해당 기능을 허용하지 않는 role을 가진 멤버가 기능을 요청할 경우 403에러를 발생하는 케이스 등각 기능에 맞게 테스트 케이스를 작성하였습니다. 회고GOOD설계 시 발생할 에러들에 대해서 미리 설계 문서에도 정리해두었었는데, 이 덕에 테스트 케이스를 작성하는데 많은 도움이 되었습니다.PROBLEM각 레이어들에서 어느정도의 기능을 구현하는 것이 책임을 올바르게 분리하는 것인지 고민하는 과정이 어려웠습니다. 아직도 어떠한 방법이 맞다라고 확신할 수 없지만, 그래도 조금씩 규칙을 가지고 진행해보았습니다.초대코드를 생성하는 기능이 있는데 이 기능은 요청이 들어오면 초대 코드 문자열을 자동으로 생성하는 기능이라 어떻게 테스트를 해야할지 고민이 되었습니다.TRY초대 코드 테스트 코드를 다시 작성해보기
백엔드
・
인프런
・
워밍업클럽
・
백엔드
・
Spring
・
Kotlin
2025. 03. 16.
0
[인프런 워밍업 클럽 3기 / 백엔드 프로젝트] 2주차 정리
해당글은 [입문자를 위한 Spring Boot with Kotlin - 나만의 포트폴리오 사이트 만들기: 정보근]https://www.inflearn.com/course/%EC%9E%85%EB%AC%B8%EC%9E%90-spring-boot-kotlin-%ED%8F%AC%ED%8A%B8%ED%8F%B4%EB%A6%AC%EC%98%A4/dashboard강의를 보고 공부한 내용입니다.2주차 부터는 실습 위주의 강의로 공부 내용의 경우 어노테이션 중심으로 정리했습니다. 공부 내용 정리1. 도메인 레이어도메인 레이어 설명Entity: 데이터베이스 테이블과 매핑되는 클래스.Repository: JPA를 활용하여 엔티티와 데이터베이스 간의 CRUD 작업을 수행하는 인터페이스.관련 어노테이션@Entity // JPA 엔티티 클래스 지정. @Id // 기본 키(PK) 지정. @GeneratedValue // PK 자동 생성 전략 설정. @Column // 데이터베이스 컬럼과 매핑. @CreatedDate // 엔티티 생성 날짜 자동 저장. @OneToMany // 1:N 관계 설정. @ManyToOne // N:1 관계 설정. @JoinColumn //외래 키 지정. @OneToOne //1:1 관계 설정. @ManyToMany // N:M 관계 설정. Spring Data JPA - JpaRepository 설명JpaRepository는 Spring Data JPA에서 제공하는 인터페이스로, 기본적인 CRUD 메서드를 제공합니다.public interface UserRepository extends JpaRepository {}기본 CRUD 메서드save(entity) // 엔티티 저장 또는 수정 findById(id) // ID(PK)로 조회 existsById(id) // 존재 여부 확인 delete(entity) // 엔티티 삭제 deleteById(id) // ID(PK)로 삭제 findAll() // 모든 데이터 조회 count() // 전체 데이터 개수 조회메서드 네이밍 규칙도메인에 종속되는 기능이라도 메소드명 네이밍 규칙을 따르면 그에 맞는 쿼리를 자동으로 생성해주기도 합니다. 따라서 기본적인 명명 규칙을 찾아 정리해보았습니다.findBy + 필드명 : 특정 필드로 조회 findBy + 필드명 + And/Or + 필드명 : 복합 조건 조회findBy + 필드명 + GreaterThan/LessThan : 비교 연산 findBy + 필드명 + Containing/StartsWith/EndsWith : Like 검색 findBy + 필드명 + IsNull/IsNotNul : NULL 처리 findBy + 필드명 + OrderBy + 필드명 + Asc/Desc : 정렬 findTopNBy + 필드명 : 상위 N개 조회 2. 프레젠테이션 레이어프레젠테이션 레이어 설명프레젠테이션 레이어는 HTTP 요청을 받아 서비스 계층과 상호작용하며, 클라이언트에 응답을 반환하는 역할을 수행합니다. 컨트롤러, DTO, 서비스, 인터셉터로 구성됩니다.Controller: HTTP 요청을 처리하는 역할.DTO: 데이터 전달을 위한 객체.Service: 비즈니스 로직을 처리하는 계층.Interceptor: 컨트롤러에 도달하기 전후에 요청을 가로채는 역할. 관련 어노테이션 정리@Controller // Spring MVC 컨트롤러 역할. 뷰를 반환. @RestController // @Controller + @ResponseBody 조합. JSON 반환. @RequestMapping // 특정 URL과 컨트롤러 메서드 매핑. @GetMapping // GET 요청 처리. @PostMapping // POST 요청 처리. @Service // 비즈니스 로직을 담당하는 서비스 클래스에 붙임. @Repository // 데이터베이스와 연동되는 DAO 클래스에 붙임. @Component // Spring Bean으로 등록하는 가장 기본적인 어노테이션. @Transactional // 트랜잭션 관리. DB 작업 중 실패 시 롤백. @Configuration // Spring 설정 클래스에 붙임. 4. 테스트 코드테스트 코드의 작성은 기능을 개발하는 것만큼 중요한 작업입니다.코드의 정확성, 유지보수성, 신뢰성을 보장하며, 개발 속도를 높이는 데에도 중요한 역할을 합니다.단위 테스트 vs 통합 테스트 비교단위 테스트 (Unit Test) : 개별 메서드, 클래스의 기능 검증. Mock 객체 사용. 실행 속도 빠름. 통합 테스트 (Integration Test) : 여러 계층(Controller → Service → Repository)의 연계를 테스트. 실제 DB 사용. 실행 속도 느림. 테스트 관련 어노테이션 정리@ExtendWith // JUnit5와 스프링 테스트 환경 통합. @InjectMocks // @Mock 객체를 테스트 대상 클래스에 주입. @Mock // 테스트에서 Mock 객체 생성. @SpringBootTest // Spring Boot 애플리케이션 컨텍스트 로드 후 테스트 실행. @AutoConfigureMockMvc // MockMvc 자동 설정. @DisplayName // 테스트 실행 시 표시될 이름 지정. 미션미션3 - REST API 설계하기API 명세서 작성 도구 선택API 명세서 작성 도구로 어떤 도구를 선택해야할지 미션 전 고민이 많았습니다. 클라이언트 개발을 했을떈 보통 백엔드 팀원 분들이 스웨거 문서로 프로젝트 진행 시 사용을 했었는데 현재 Swagger에 대한 학습이 부족한 상태였기에 다른 방법을 찾아보았습니다. 대안 도구 = 포스트맨 문서 활용포스트맨에서도 문서를 작성할 수 있고, 해당 내용을 공유할 수있음을 알게되었고 스웨거 적용 전 포스트맨 문서를 활용하기로 결정하였습니다. 200 외 오류 응답코드userId 혹은 capsuleId를 찾을 수 없는 경우와 접근 권한(ROLE) 이 허용되지 않는 경우에 따라 다른 처리를 해야하기에 해당 케이스들을 명확하게 구분해야 했습니다.특히, 프로젝트에서 작성자(OWNER) 와 참여자(MEMBER) 역할(Role)이 존재하기 때문에, 권한(Role) 기반 오류 처리 규칙을 정해야 했습니다.오류 코드 정리400 Bad Request : 잘못된 요청 -> userId 또는 capsuleId가 유효한 형식이 아닐 경우401 Unauthorized : 인증 실패 -> 로그인하지 않은 사용자가 보호된 API에 접근 시 (JWT Token 사용 시 주로 사용)403 Forbidden : 권한 없음 (인가 실패) -> 사용자는 존재하지만, role 에 따른 권한이 없어 접근 불가한 경우404 Not Found : 리소스 없음 -> 요청한 리소스가 존재하지 않는 경우코드 적용 규칙1. 권한(Role)에 따라 접근이 제한되는 경우 → 403 Forbidden - 예) 참여자(MEMBER)가 캡슐을 삭제하려고 하는 경우 → 삭제 기능은 OWNER만 가능하므로, 권한 부족 → 403 응답 반환1. 요청 데이터가 정상적으로 전달되었지만, 해당 리소스가 존재하지 않는 경우 → 404 Not Found - 예) 존재하지 않는 userId로 게시글 조회 시 → 해당 리소스가 없으므로 404 반환 회고GOOD단순히 아키텍쳐에 대한 이론만 들었을 때는 이해가 부족한 느낌이였는데 실습을 통해 뼈대를 잡으면서 점차 이해를 높일 수 있었습니다.PROBLEM처음 진행해보는 스프링 프로젝트기에 수많은 어노테이션들의 각 기능에 대해 개념이 섞이는 느낌이라 아직은 낯설게 느껴져 강의 자료를 참고하지않고 혼자서 작성하기에는 아직은 무리였습니다.처음 h2 확인 실습 시 콘솔에 접속되지 않는 문제가 있었는데 코드 레벨에서의 문제는 없어 꽤 많은 시간을 해결하는데 할애하였습니다. 단순히 인텔리제이 Build설정을 Intellij IDEA -> Gradle로 설정하니 해결되었습니다.성능 개선 부분에서 조금 이해가 어려웠습니다.TRY성능 개선 방법에 대해 개인적으로 더 공부해보고 고민해보기
백엔드
・
인프런워밍업클럽
・
백엔드
・
발자국
2025. 03. 09.
0
[인프런 워밍업 클럽 3기 / 백엔드 프로젝트] 1주차 정리
해당 글은 [입문자를 위한 Spring Boot with Kotlin - 나만의 포트폴리오 사이트 만들기: 정보근](https://www.inflearn.com/course/%EC%9E%85%EB%AC%B8%EC%9E%90-spring-boot-kotlin-%ED%8F%AC%ED%8A%B8%ED%8F%B4%EB%A6%AC%EC%98%A4/dashboard) 강의를 보고 공부한 내용입니다.웹 이론 정리웹서비스 구성 요소클라이언트 -- 서버 -- 데이터 베이스- 클라이언트 : 사용자와 상호작용하여 요청하는 주체로 일반적으로 브라우저 의미- 서버 : 요청한 작업을 응답하는 주체. 데이터베이스 데이터의 CRUD 작업 후 결과를 클라이언트에 반환- 데이터베이스 : 데이터의 집합- DBMS: 데이터를 저장하고 관리하는 프로그램으로 일반적으로 데이터베이스라고 하면 DBMS를 의미- DSN 서버: 클라이언트에서 요청을 보낸 도메인 주소를 IP주소로 매핑하여 반환해주는 서버주소를 브라우저에 입력하면?1. DNS에 도메인을 보낸 후 해당하는 IP주소를 받아온다.2. 해당 IP주소로 서버에 요청을 보낸다. 이 때 필요한 데이터가 있다면 함께 전달3. 요청을 받은 서버는 데이터베이스에 요청을 수행한다.4. 데이터베이스는 서버에서 요청한 작업을 완료 후 결과를 반환한다. (조회의 경우 조회 데이터 전달, 삽입 수정 삭제의 경우 성공 여부 응답)5. 서버는 받은 결과를 클라이언트에 전달웹 프레임워크- 웹프레임워크 : 동적 웹 서비스 개발을 편리하게 만들어주는 도구- Spring 프레임워크 : 자바 기반 웹 프레임워크로 웹서버 개발을 편리하게 할 수 있도록 모듈화 해놓음아키텍쳐 패턴MVC 패턴- 애플리케이션을 Model, View, Controller로 구분- Model : 애플리케이션의 비즈니스 로직과 데이터- View : 사용자에게 보여지는 화면을 담당, Model에서 데이터를 꺼내와 반영- Controller : 요청을 받아 처리하고 결과 데이터를 Model에 넣을 수 있음레이어드 아키텍처- 애플리케이션의 컴포넌트를 유사 관심사를 기준으로 레이어(계층)로 묶어 수평적으로 구성한 구조- 스프링 웹개발 시 대부분 레이어드 아키텍쳐 기반으로 개발- 프레젠테이션 (Controller) : 클라이언트의 요청을 해석하고 응답, 전달 받은 데이터를 검증하거나 가공 등의 과정을 담당하며 직접적인 비지니스 로직은 포함하지 않고 상호작용만을 담당- 비지니스 (Service) : 애플리케이션에서 제공하는 기능을 정의하고 목적에 맞게 데이터를 처리, Repository의 다양한 처리 메소드를 호출하여 저장, 수정, 조회, 삭제 등을 수행- 데이터 접근 (Repository) : 데이터 베이스에 직접 상호작용하여 작업을 요청 스프링 Bean과 의존성 주입스프링 빈 이란?- 빈(Bean)은 스프링 컨테이너에 의해 관리되는 재사용 가능한 소프트웨어 컴포넌트- 스프링에서 관리되는 객체 = 자바 클래스의 인스턴스- 빈을 사용하는 가장 큰 이유는 스프링 간 객체가 의존관계를 관리하도록 하는 것객체가 의존관계를 등록할 때 스프링 컨테이너에서 해당하는 빈을 찾고, 그 빈과 의존성을 만든다.의존성 주입이란?- 한 객체 내에서 사용하는 다른 객체를 클래스 내부에서 직접 만드는 것이 아니라 외부에서 주입받아 사용하는 방식ex) 컨트롤러에서 서비스를 사용하면 직접 컨트롤러내에서 서비스를 생성하는 것이 아니라 외부에서 서비스를 주입하는 것#### 의존성 주입 방법생성자 방식- 클래스 생성자에서 주입을 하는 방식- 다른 주입 방법에 비해 안전하므로 생성자 주입 방식 권장- 순환 참조 예방 -> 컴파일 에러가 발생하므로 런타임단계에서 발생하는 스택오버플로우 방지- 의존하는 빈 누락 방지 -> 이 또한 컴파일 에러 발생필드 주입 방식같은 경우 어노테이션을 누락했지만 넘어가 런타임 에러가 발생할 수도 있음수정자(setter) 방식- 클래스의 세터 메서드를 통해 의존성을 주입- 객체가 생성된 후 언제든지 호출될 수 있기때문에 lateinit 키워드를 사용하여 나중에 초기화할 수 있도록하며, @Autowired를 파악해 setter를 감지하고 주입할 수 있도록 함필드(Field) 방식- 클래스의 필드에 바로 의존성을 주입- 필드에 @Autowired 어노테이션을 사용하면 Spring은 해당 필드에 맞는 Bean을 자동으로 주입함- 가장 간단하지만 안정성을 보장하지 못하고 테스트가 어려움 HTTP와 REST APIHTTP- 네트워크로 통신하는 두 컴포넌트간의 통신 규약- 요청과 응답을 통해 작동함, 즉 어떻게 요청하고 응답할지에 대한 약속- 각 요청과 응답은 StartLine, Header, Body로 구성되어있음HTTP 요청 메서드GET (Read), POST(Create), PUT, PATCH(Update), DELETE(Delete)PUT : 리소스의 모든 것을 업데이트 /PATCH : 리소스의 일부를 업데이트 HTTP 상태 코드1. 2xx : 정상 처리 의미2. 3xx : 추가 행동 요구3. 4xx: 클라이언트측 에러4. 5xx : 서버측 에러 REST API- HTTP 통신으로 동작하는 애플리케이션 기능을 정의하는 규칙, 즉 API를 구축하기 위한 방법에 대한 약속핵심1. URL만으로도 어떤 자원에 대한 요청인지 이해할 수 있어야함2. HTTP메서드를 통해 어떤 행위를 할 것인지 파악 가능해야함3. HTTP 응답에 링크를 포함하여 클라이언트가 다음에 할 행동 가이드를 제시클라이언트에서 서버에 데이터를 보내는 방식1. Query Parameter : URL에 ? 로 연결된 데이터들, @RequestParam 어노테이션 사용2. Path Variable: URL에 / 를 통해 추가적으로 전달되는 데이터들, @PathVariable 어노테이션 사용3. Request Body: URL을 통해 전달하지 못함, @RequestBody 어노테이션 사용 데이터 베이스데이터 베이스 = 데이터의 집합, 일반적으로 데이터관리시스템인 DBMS 를 지칭데이터베이스 종류관계형 데이터 베이스 : 테이블로 이루어짐 (열과 행), 각 행은 1개의 데이터 각 열은 데이터의 필드후보키 : 데이터를 식별할 수 있는 컬럼의 최소 조합기본키 : 후보키 중 대표로 정한 것즉 각 데이터들을 구별하는 요소들이기에 겹칠 수 없음 -> 유일성을 가짐비관계형 데이터베이스, NoSQL키-값 형태, 문서형 등 존재대표적으로 MongoDB, Redis기본적으로 관계형에 데이터를 저장하고 속도가 빠른 비관계형의 이점을 살려 캐시용도로 비관계형 디비 사용 데이터 베이스 설계데이터 베이스 관계 종류1:1 관계 (One-to-One)한 개의 레코드가 다른 테이블의 오직 하나의 레코드와 연결되는 관계.예시: User (사용자) 테이블과 UserProfile (사용자 프로필) 테이블한 사용자는 한 개의 프로필만 가질 수 있음.UserProfile에서 user_id (FK, Unique)를 사용하여 관계 유지.1:N 관계 (One-to-Many)한 개의 레코드가 다른 테이블의 여러 레코드와 연결되는 관계.부모(1) 테이블과 자식(N) 테이블이 존재하며 자식 테이블은 부모 테이블을 참조하는 외래 키(FK) 를 가짐.예시: User (사용자) ↔ TimeCapsule (타임캡슐)한 사용자가 여러 개의 타임캡슐을 생성할 수 있음.TimeCapsule 테이블이 user_id (FK) 를 포함함.N:M 관계 (Many-to-Many)여러 개의 레코드가 다른 테이블의 여러 개의 레코드와 연결되는 관계.중간 테이블(Bridge Table, Join Table)이 필요함. -> 다대다 관계를 직접 설정할 수 없으므로 1:N + 1:N의 형태로 변환됨.예시: User (사용자) ↔ User_Capsule (사용자-타임캡슐 관계) ↔ TimeCapsule (타임캡슐)한 사용자는 여러 개의 타임캡슐에 참여 가능.하나의 타임캡슐도 여러 사용자가 참여 가능.=> 따라서 사용자와 타임캡슐간의 중간테이블 사용자-타임캡슐 관계를 생성User_Capsule이 user_id (FK) & capsule_id (FK) 를 가짐. 식별관계 vs 비식별관계테이블 간 관계를 설정할 때, 부모 테이블의 PK를 자식 테이블이 직접 사용하느냐에 따라 나뉨. 식별관계 (Identifying Relationship)자식 테이블이 부모 테이블의 PK를 포함하여 복합키(PK)로 사용하는 관계.부모 테이블이 삭제되면 자식 테이블도 삭제됨 (ON DELETE CASCADE 가능).자식 테이블이 부모 테이블의 존재 없이는 의미가 없음.보통 N:M 관계를 관리하는 중간 테이블에서 많이 사용됨.예시: User_Capsule이 user_id & capsule_id를 PK로 포함하는 경우 (복합키 사용). 비식별관계 (Non-Identifying Relationship)부모 테이블의 PK를 자식 테이블이 PK로 포함하지 않고, FK로만 유지하는 관계.부모 테이블이 없어도 자식 테이블이 독립적으로 존재 가능.데이터 확장성이 높아지고 관리가 용이함.자식 테이블이 자체적인 ID(PK) 를 가지므로, 유지보수성이 높아짐.예시: User_Capsule 테이블이 별도의 id (PK) 를 가지면서 user_id (FK), capsule_id (FK) 를 유지하는 경우,InviteCode 테이블이 capsule_id (FK) 를 가지지만 id (PK) 를 별도로 유지하는 경우. 트러블 슈팅1 - 식별 관계 VS 비식별 관계문제 상황초기 ERD 설계에서 User_Capsule(사용자-타임캡슐 관계) 테이블을 만들 때,• user_id와 capsule_id를 복합 PK(식별관계) 로 설정할지,• 별도의 id를 PK로 두고 user_id & capsule_id를 FK(비식별관계) 로 설정할지 고민이 발생. ✔ 만약 식별관계를 선택하면?• User_Capsule의 PK가 (user_id, capsule_id)가 되며, User 또는 TimeCapsule이 삭제되면 해당 관계도 삭제됨.• 하지만, 추가적인 필드를 넣거나 관계를 수정하기 어려움 (예: role 같은 필드 추가 시 관리 복잡). ✔ 만약 비식별관계를 선택하면?• User_Capsule이 별도의 id 필드를 PK로 가지며, user_id & capsule_id는 FK로만 존재.• 데이터 확장이 용이하고, 관계의 독립성이 보장됨 (예: 나중에 role 변경 가능). 해결 방법 (비식별관계 선택)• 결론적으로 User_Capsule에 별도의 id 필드를 PK로 설정하고, user_id & capsule_id를 FK로 두는 방식(비식별관계)을 채택!• InviteCode(초대 코드)도 TimeCapsule과 비식별관계로 설정하여 독립적인 관리 가능. 비식별관계를 선택한 이유:1. 확장성 용이 → 추가적인 필드(예: 역할 정보) 추가 가능.2. 데이터 무결성 유지 → 관계 삭제 시에도 유연한 처리가 가능.3. 관리 편리성 증가 → 식별자로 인해 불필요한 제약을 없애고, 독립적인 테이블 관리 가능. 1주차 회고이번 주에는 백엔드 프로젝트의 기본 개념부터 시작해서 실제로 환경을 세팅하고 엔티티를 개발하는 과정까지 진행했다.✅ 스스로 칭찬하고 싶은 점백엔드 실습이 처음인데도 적극적으로 따라갔다.iOS 개발을 주로 해왔기 때문에 백엔드 실습이 낯설었지만, 처음부터 하나하나 차근차근 따라가면서 익히려고 노력했다.기본 이론의 경우 전공 공부에서 배운 내용들이 많아 비교적 수월하게 이해할 수 있었다. ❌ 아쉬웠던 점실습에서 예상보다 시간이 걸렸다.특히 환경 세팅 과정에서 iOS에서는 Xcode 중심이기에 처음부터 세팅을 했어야했는데 예상치 못하게 시간을 많이 잡아먹었었다.데이터베이스 설계 실습을 하면서 생각보다 모르는 개념들이 많다는 것을 깨달았다. 🎯 다음 주 학습 목표강의를 들으면서 내 프로젝트에 응용하기 위해 궁금한 내용들을 찾아 공부하고 기록하기JPA와 데이터베이스 개념을 더 깊이 공부하기
백엔드
・
백엔드
・
Kotlin
・
Spring
・
인프런워밍업클럽