김영한
@yh
수강생
587,615
수강평
41,283
강의 평점
5.0
교육자
전: 우아한형제들 기술이사, 카카오, SK플래닛
진짜 실무에 필요한 제대로 된 개발자가 될 수 있도록, 교육하는 것이 저의 목표입니다.
저의 개발 인생 이야기
EO 인터뷰 영상
개발바닥 - 시골 청년 개발왕 되다
취업과 이직에 대한 고민 해결
강의
로드맵
전체 4수강평
- 김영한의 실전 데이터베이스 - 설계 2편, 실무에서 반드시 마주치는 9가지 설계 패턴
- 김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
- 스프링 부트 - 핵심 원리와 활용
게시글
질문&답변
코드 자료
안녕하세요. 여비님이번 강의는 코드를 처음부터 따라하면서 이해하는 것을 목표로 하기 때문에 의도적으로 코드를 제공하지 않습니다 🙂화이팅!
- 좋아요수
- 0
- 댓글수
- 2
- 조회수
- 31
질문&답변
간단한 오타 제보입니다.
최형석님 감사합니다^^!다음 버전에 패치할게요!
- 좋아요수
- 0
- 댓글수
- 1
- 조회수
- 21
질문&답변
실제 FK제약조건을 설정하지 않는이유
안녕하세요. 오승환님모든 곳에서 다 FK를 빼고 사용하는 것은 아니고, 다음과 같은 이유로 FK를 빼는 경우들이 있습니다. 1. 운영이 불편함배치, 데이터 이관, 테스트 셋업할 때 INSERT/DELETE 순서 맞춰야 하고, 조금만 꼬이면 제약 위반으로 실패합니다. FK 끄고 작업하는 일이 많아집니다.2. 스키마 변경이 무거워짐부모 테이블 구조 바꾸려면 자식 FK 드롭 → 작업 → 재생성하는 과정이 필요합니다.3. 확장성 — DB 분리 대비MSA로 쪼개면 DB 레벨 FK는 못 씁니다. 어차피 애플리케이션이 정합성을 책임져야 하니, 처음부터 그 구조로 갑니다. 하지만 트레이드오프를 고려해야 합니다.FK를 빼면 운영 유연성과 확장성을 얻고, 대신 정합성 책임이 애플리케이션으로 넘어옵니다. 모든 검증 로직을 명확하게 애플리케이션 로직에서 책임져야 하는데, 시간이 지날수록 보통 잘 오염되고, 이상한 중복 데이터나, 자식이 반드시 필요한데 없는 경우가 발생합니다. 이 문제 때문에 또 방어 코드를 추가해야 하는 경우들도 생깁니다.제가 추천하는 방법은 '기본적으로는 FK를 사용해 데이터 무결성을 보호하되, 시스템의 규모와 도메인 특성에 맞춰 유연하게 제거하는 것'입니다.실무적인 관점에서 다음과 같이 접근해 보시길 권장합니다.정합성이 최우선인 코어 도메인 (결제, 정산 등): 데이터가 틀어질 때의 비즈니스 리스크가 매우 크므로 DB 레벨의 FK 제약조건을 굳건히 걸어두고 2중, 3중으로 보호하는 것이 좋습니다.대규모 트래픽 및 유연성이 필요한 도메인: 잦은 스키마 변경과 성능 최적화가 중요하거나, 향후 MSA 분리가 예상되는 서비스라면 FK를 물리적으로 제거하여 운영의 유연성을 확보합니다.논리적 관계 유지 및 보정 배치: DB에서 물리적인 제약조건CONSTRAINT)은 제거하더라도, ERD 상의 논리적 연관관계는 명확히 남겨두어야 합니다. JPA 같은 ORM을 사용한다면 애플리케이션 레벨에서 연관관계를 철저히 매핑하여 검증하고, 주기적으로 백그라운드 배치(Batch)를 돌려 고아 데이터나 정합성이 깨진 데이터를 모니터링하고 정리하는 안전장치를 함께 마련하는 것이 좋습니다.결국 서비스 규모가 커지고 아키텍처가 복잡해질수록 무결성 유지의 책임은 DB에서 애플리케이션으로 넘어오게 됩니다. 현재 프로젝트의 단계, 트래픽 규모, 그리고 팀의 방어 코드 작성 역량을 종합적으로 고려하여 적절한 트레이드오프를 선택하시길 바랍니다.감사합니다.
- 좋아요수
- 0
- 댓글수
- 2
- 조회수
- 39
질문&답변
RepositoryTest의 패키지 위치가 domain인 이유
안녕하세요. dev.rudevico님오타가 맞습니다 🙂다음에 한번 정리해야겠네요.감사합니다^^!
- 좋아요수
- 0
- 댓글수
- 2
- 조회수
- 30
질문&답변
구현체가 동적으로 정해질 때, 팩토리 기법을 사용하나요?
안녕하세요. 김강민님 🙂궁금해하시는 부분을 딱 섹션 7. 조회한 빈이 모두 필요할 때 List, Map에서 설명합니다 🙂감사합니다.
- 좋아요수
- 0
- 댓글수
- 2
- 조회수
- 52
질문&답변
spring initialiser 어떤걸 선택해야될지 모르겠어요
안녕하세요. 최준환님 🙂강의 내용과 같이 Gradle groovy를 선택하시면 됩니다.Spring boot (4.05 vs 3.5.13): 둘다 선택 가능합니다 🙂java 21 vs 17: 둘다 선택 가능합니다 🙂 가급적 최신 버전을 선택하시는 것을 권장드려요.감사합니다.
- 좋아요수
- 0
- 댓글수
- 2
- 조회수
- 32
질문&답변
BCNF 질문
안녕하세요. escho94님 🙂결론부터 말씀드리면, 이 구조는 제1정규형부터 BCNF까지 어떠한 정규형도 위반하지 않은 상태입니다. 이유는 다음과 같습니다.데이터베이스의 정규화(1NF ~ BCNF)는 기본적으로 테이블 내 컬럼 간의 함수 종속성(Functional Dependency)을 분석하여 이상 현상을 제거하는 과정입니다.professor_bcnf 테이블은 기본 키(PK)인 professor_name을 알면 lecture_name을 알 수 있는 구조입니다.여기에는 부분 함수 종속(2NF 위반)이나 이행적 함수 종속(3NF 위반)이 없으며, 기본 키가 아닌 일반 컬럼이 다른 컬럼을 결정하는 BCNF 위반 요소도 존재하지 않으므로 정규형을 완벽하게 만족합니다. 그렇다면 말씀하신 갱신 이상과 같은 문제는 왜 발생하는 것일까요?이는 정규화 이론의 위반 때문이 아니라, 자연 키(Natural Key) 성격을 가진 문자열 데이터를 직접 사용했기 때문에 발생하는 한계입니다.해당 BCNF 예제는 정규화의 원리(결정자와 종속자의 관계) 자체를 가장 직관적으로 설명하기 위해 '과목명'이라는 비즈니스 의미를 가진 데이터를 그대로 사용한 학술적인 예시입니다.만약 실무에서 이와 같이 설계한다면, 비즈니스 요건(과목명 변경)이 바뀔 때 관련된 모든 레코드를 찾아서 연쇄적으로 업데이트해야 하는 심각한 문제가 발생하게 됩니다.이를 현대적인 데이터베이스 설계 방식으로 완벽하게 해결하려면, 강의에서 설명드린 것 처럼 대리 키(Surrogate Key)를 도입하여 테이블을 한 번 더 분리해야 합니다.감사합니다.
- 좋아요수
- 0
- 댓글수
- 2
- 조회수
- 50
질문&답변
문제풀이 시간마다 방향성
안녕하세요. 정현수님AI 인턴이 잘 답변을 해주었는데요.처음에는 저도 그랬습니다 🙂하지만 이런 과정을 반복하면서 익숙해지면 나중에는 자연스럽게 진행하실 수 있을거에요.제가 추천하는 방법은 처음에는 10분 정도 스스로 고민해보고 그래도 답이 안나오면 답을 보고 따라서 코딩하세요. 그리고 이후에 스스로 한번 풀어보는 것입니다 🙂응원합니다!
- 좋아요수
- 0
- 댓글수
- 2
- 조회수
- 41
질문&답변
H2데이터베이스 파일 생성
안녕하세요. 김주현님해당 선택은 사실 URL을 편리하게 적도록 도와주는 템플릿 기능입니다.URL에 적는 내용이 중요하기 때문에 해당 내용은 무시하셔도 괜찮습니다 🙂감사합니다.
- 좋아요수
- 0
- 댓글수
- 2
- 조회수
- 51
질문&답변
히스토리 관련 질문
안녕하세요. 김재연님 🙂강의를 더 진행해보시면 생각하신 구조로 진행이 될거에요.추가로 각각의 사용 상황을 말씀드리면 다음과 같습니다. 히스토리를 애플리케이션 단(코드)에서 트랜잭션으로 직접 INSERT 하고, 변경 사유가 단순 감사(Audit) 및 이력 추적용이라면:질문자님 생각대로 히스토리 테이블에만 사유 컬럼을 두는 것이 베스트 프랙티스입니다. 원본 테이블을 깔끔하게 유지하세요.히스토리를 DB 트리거로 자동 적재해야 하거나, 현재 상태의 변경 사유를 메인 화면에서 JOIN 없이 빠르게 읽어야 한다면:원본 테이블에도 사유 컬럼을 추가하는 것을 고려하셔야 합니다.감사합니다 🙂
- 좋아요수
- 0
- 댓글수
- 2
- 조회수
- 58










