묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
PK 생성 전략의 '유니크 문자열 또는 숫자' 단점 부분 질문있습니다.
안녕하세요. 오늘도 인덱스 관련해서 질문을 들고 왔습니다!(선생님이 "이런것도 질문해? 제발 질문 하지마 제발" 이라고 들 정도의 질문을 하는 학생들이 대부분 실력이 상승 한다고 해서 물음표 살인마가 되기로 했습니다. 지인들한테 강의 마구마구 홍보중입니다.. 한번만 봐주셉요..) 데이터 삽입 필요한 인덱스 페이지가 가득 찼다면 ,B+ tree 재구성 및 페이지 분할로 디스크 I/O 증가정렬된 상태를 유지하기 때문에 삽입시마다 B+tree 재구성으로 인해 정렬로 인한 성능 저하 된다는건 이해가 되었습니다.(맞다면..) 허나 페이지 분할은 잘 이해가 안가네요 ㅠ 페이지 분할에 대해 제가 이해한 바인 아래 내용이 맞는지 궁금합니다.PK가 AUTO_INCREMENT일 경우데이터가 항상 B+ Tree의 마지막(오른쪽 끝)에 삽입됨.하나의 페이지가 꽉 차면, 새로운 페이지가 오른쪽에 생성됨.1. [ Page 1 ] (꽉 참) → 데이터 추가 시 분할 필요 2. [ Page 1 (반) ] → [ Page 2 (새로운 페이지 생성) ] PK가 유니크 문자열 또는 숫자일 경우랜덤한 값이 삽입될 때, 페이지가 꽉 차지 않았더라도 균형을 맞추기 위해 강제적으로 새로운 페이지가 만들어질 수 있음.1. [ Page 1 ] (데이터 60% 차 있음) → 중간에 랜덤 값 삽입 시 균형 유지 필요 2. 균형 유지 과정에서 일부 데이터를 새로운 페이지로 이동하여 분산 3. [ Page 1 (30%) ] → [ Page 2 (새로운 페이지 생성) ] 즉, 유니크 문자열 또는 숫자는 페이지가 “완전히 가득 차지 않아도” 새로운 페이지가 생성될 수'도' 있다.
-
해결됨[말 한마디로 뚝딱!] AI와 함께 나만의 수익화 웹사이트를 만드는 법
강의 순서
1강부터 차례대로 듣고 있는데 3강부터 막히네요.영상으로만 보면 따라갈수가 없습니다.보니까 3강 이후 강의를 먼저 들어야 진행이 가능한거 같은데,우선순위를 한번 자세히 설명해주시면 좋겠습니다. 그리고, 영상만 봐서 진행이 안되는부분은https://banbu.kr/free/35 해당페이지 순서를 우선적으로 따라해야하는건지도요?
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
rows per chunk 에 대해서 궁금합니다.
이번에 커버링 인덱스를 설명하시면서 아 대충 왜 빠르게 조회가 되는지 이해가 되기 시작했습니다. 그런데 최근에 했던 프로젝트 중에 이와 비슷한데 왜 성능이 개선되었는지 모르는 것이 하나 있습니다. 아래 부분인데요..일단 created_at 은 index 가 적용되지 않았음을 알려드립니다. select ep1_0.employee_post_id, ep1_0.access_url, ep1_0.contact, ep1_0.contents, ep1_0.member_id, m1_0.member_id, m1_0.access_url, m1_0.authority, m1_0.birth_day, m1_0.email, m1_0.login_id, m1_0.name, m1_0.nick_name, m1_0.password, m1_0.personal_link, m1_0.personal_statement, m1_0.sex, m1_0.tmp_password, m1_0.twitter_link, m1_0.youtube_link, ep1_0.payment_amount, ep1_0.payment_method, ep1_0.title, wft1_0.work_field_tag_id, wft1_0.name, ep1_0.career_year, ep1_0.created_at, ep1_0.updated_at from employee_post ep1_0 left join work_field_tag wft1_0 on wft1_0.work_field_tag_id=ep1_0.work_field_tag_id join member m1_0 on m1_0.member_id=ep1_0.member_id where wft1_0.work_field_tag_id=1 order by ep1_0.created_at desc, ep1_0.employee_post_id desc limit 0,10;이것을 explain analyze 한다면 Limit: 10 row(s) (cost=1088 rows=10) (actual time=39.1..39.1 rows=10 loops=1) -> Nested loop inner join (cost=1088 rows=1968) (actual time=39.1..39.1 rows=10 loops=1) -> Sort: ep1_0.created_at DESC, ep1_0.employee_post_id DESC (cost=399 rows=1968) (actual time=39..39 rows=10 loops=1) -> Index lookup on ep1_0 using FK_work_field_tag_TO_employee_post (work_field_tag_id=1) (cost=399 rows=1968) (actual time=0.0949..7.91 rows=1968 loops=1) -> Single-row index lookup on m1_0 using PRIMARY (member_id=ep1_0.member_id) (cost=0.25 rows=1) (actual time=0.011..0.011 rows=1 loops=10)이렇게 나오고 성능이 무척 안좋은 것을 볼 수 있었습니다(using filesort 가 직접적인 원인) 근데 문제는 member 에 대한 inner join 을 빼면 -> Limit: 10 row(s) (cost=398 rows=10) (actual time=10.5..10.5 rows=10 loops=1) -> Sort: ep1_0.created_at DESC, ep1_0.employee_post_id DESC, limit input to 10 row(s) per chunk (cost=398 rows=1968) (actual time=10.5..10.5 rows=10 loops=1) -> Index lookup on ep1_0 using FK_work_field_tag_TO_employee_post (work_field_tag_id=1) (cost=398 rows=1968) (actual time=0.0712..6.03 rows=1968 loops=1) 위와 같이 나오면서 성능이 무척 개선된다는 점입니다. 제가 보았을 떄 핵심적인 부분은 10 rows per chunk 입니다. 혹시 10 rows per chunk 같은 키워드는 언제 언제 발생하는지 알 수 있을까요??(왜 member에 대한 join 을 빼면 나타나구, wft1_0 을 left outer join 을 하는 것은 영향이 없는지..)mysql 공식 문서를 계속 뒤져도 발견하지 못했습니다. 강의와 관련 없는 부분이라고도 생각하실 수 있는데 이런 질문 해서 정말 죄송합니다.. 관련해서 블로그 정리한 거 혹시 필요한 정보가 있을 수도 있으니 링크 남겨놓겠습니다...https://velog.io/@dionisos198/Query-DSL-%EC%84%B1%EB%8A%A5-%EA%B0%9C%EC%84%A0-%EB%B0%8F-fetch-join-%EA%B3%A0%EC%B0%B0
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
테스트 코드 실행에서 URL을 인식 못하면서 500 에러 발생 시 관련 참고 글
https://velog.io/@ghwns9991/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-3.2-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98-%EC%9D%B4%EB%A6%84-%EC%9D%B8%EC%8B%9D-%EB%AC%B8%EC%A0%9C스프링 3.2 부터 uri 관련 매개변수 어노테이션을 잘 인식하지 못한다고 하나 봅니다. 저는 윗 글의 두 번째(-parameters) 방법으로 해결했습니다.
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
'soft Delete 시 index 설정' 답변한 내용에서 질문 있습니다.
https://www.inflearn.com/community/questions/1516484해당 게시글의 답변중 아래 문장이 이해가 잘 안갑니다 ㅠ 물론, 삭제된 데이터가 극히 적다면, 위 비용은 딱히 문제가 안될 수도 있긴 합니다.삭제되지 않은 데이터가 훨씬 많다면, 조건에 일치(isDeleted=false)하는 데이터를 빠르게 찾을 수 있으므로, 스캔하는 범위는 어차피 적을테니깐요.하지만 삭제된 데이터가 많아질수록 조건에 일치하는 데이터를 찾기 위해 스캔하는 범위가 길어질 수 있으므로, 인덱스를 걸어둬야 빠르게 조회가 가능합니다!인덱스를 걸지 않았을때 삭제되지 않은 데이터(isDeleted = false)가 훨씬 많다면 스캔하는 범위가 적은 이유를 잘 모르겠습니다..인덱스가 없으면 삭제된 데이터가 많든, 많지 않든 무조껀 풀 스캔을 해서 스캔 범위는 똑같은게 아닌걸까요?또한, 데이터 연속성도 스캔할시 관련이 있는건지 궁금합니다.인덱스가 없을때 where isDeleted = false 쿼리 실행시 id가 4번까지만 스캔해서 스캔 범위가 적은걸까요?ㄸ직전 조건와 같을때 위와 같이 데이터가 흐트러져있다면 풀스캔을 하는 걸까요? 인덱스 공부좀 해야겠네요 흙흙
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
테스트 실행 시 "ClassNotFoundException" 에러
테스트 실행 시 "ClassNotFoundException" 에러 나시는 분들은 https://bit.ly/4hIOchi 이 글 한번 참고해보세요. 이 글 보고 해결했습니다.
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
무한 스크롤 쿼리 질문 있습니다.
학습 관련 질문을 최대한 상세히 남겨주세요!고민 과정도 같이 나열해주셔도 좋습니다.먼저 유사한 질문이 있었는지 검색해보세요.인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.안녕하세요.select * from article where board_id = 1 order by article_id desc limit 30;해당 쿼리에서 강사님은 Extra에 null인데 제가 실행하면 using where가 나오네요.using filesort는 안나오는데 크게 상관 없는 부분일까요?
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
@Value 추가 시 에러 발생
학습 관련 질문을 최대한 상세히 남겨주세요!고민 과정도 같이 나열해주셔도 좋습니다.먼저 유사한 질문이 있었는지 검색해보세요.인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.좋아요 수 구현 부분 강의를 듣고 따라하던 도중 문제가 생겼습니다.ArticleLikeCount의 엔티티에서 version에 @Version을 붙이고 난 후, 테이블의 값을 모두 삭제하고 나서 테스트를 돌리면 에러가 발생합니다. 계속해서..Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect):위 에러가 계속 발생하네요.테스트는 like 메서드를 실행했습니다.이상하게도 강사님 코드로는 정상 작동이 되어서, 그대로 복사해서 붙여넣기로 가져와서 돌려보면 안되네요.테이블에 데이터가 이미 존재하면 그때부터는 정상적으로 되는 것 같은데, 테이블이 비어있으면 에러가 발생합니다 ㅜㅜ혹시라도 확인하실 수 있도록 제 프로젝트 파일을 압축해서 올려놓은 링크 공유하겠습니다. ㅜㅜhttps://drive.google.com/file/d/1H9UR9UXZhgmBH-XrXoXPc2-dgrixF7b-/view?usp=drive_link
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
프론트에서 페이지네이션 count 계산법 질문드립니다!
페이지 번호 공식은 다음 버튼 활성화 유무만 판단하는 거고 이전 버튼 유무는 프론트에서'만' 제어하는 걸까요? 프론트에서도 페이지 번호 공식을 알고 있는걸까요? 2:50초 11~20번 페이지에 있을때프론트에서 계산한값(601) == 백엔드에서 내려준 값(601)=> 같으므로 '다음' 버튼 활성화 프론트에서 계산한값(601) == 백엔드에서 내려준 값(500)=> 601 미만 이므로 '다음' 버튼 비활성화 (강의 넘 재밌어요. 게임 하는거 보다 재밌다..)
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
대규모 트래픽 환경에서는 Jpa 보단 서브쿼리를 활용하시나요?
22:40에 서브 쿼리를 제시해주셨는데요.쿼리를 분리하여 애플리케이션 로직으로 풀수 없을때만 nativeQuery를 사용해서 서브쿼리를 즉시 적용하시는 걸까요? 아니면 서브쿼리를 적극적으로 사용하시는 걸까요? 대규모 트래픽 환경에서는 Jpa, Querydsl를 단순한 기능에 사용할때도 조심해서 써야할 것 같아요.. 팀 컨벤션이 도메인을 풍부하게 활용하는 거라면 nativeQuery는 지양해야 할것 같기두 하네요. 지식이 부족해서 가정만 하게 되네요 ㅠ.ㅠ답변 부탁드립니다~ (반복 학습 필수네요. 강의 1분 1초를 씹고 뜯고 맛보고 즐기면서 공부하겠습니닷!)
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
XxxResponse를 service 패키지에 두신 이유가 궁금합니다.
XxxRequest / XxxResponse 클래스를 controller 패키지 하위가 아닌 Service 패키지 하위에 두신 이유가 궁금합니다. 의존성 방향을 Controller부터 단방향을 유지하기 위해 하신것으로 유추 하는 바입니다. 하지만 XxxRequest / XxxResponse가 service 패키지 클래스에 있는게 조금 어색해 보여서요. 저는 controller 하위 패키지에 requeset / response를 두고facade 혹은 service에 클래스로 묶어서 넘길경우 에는는 domain 계층에 만든 dto를 생성해서 넘깁니다. 제가 생각한게 맞는지 답변 부탁드립니다~ (강의 최고입니다. 저만 듣고 싶어요 흙흙)
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
조회수 어뷰징 방지 부분에서 질문이 있습니다.
안녕하세요."조회수 어뷰징 방지 정책 구현" 강의의 ViewApiTest.viewTesst를 실행한 다음redis가 동작하는 docker에 접속해 redis-cli를 실행하고 "keys *" 명령어를 실행하면,distributed lock이나 조회수에 관련된 key를 찾을 수 없습니다.database 0~15를 돌며 "keys *"를 실행 했을 때 (empty array)를 응답 받고 있습니다.어떤 방법으로 결과를 확인할 수 있을까요?
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
댓글 api delete test 에러
학습 관련 질문을 최대한 상세히 남겨주세요!고민 과정도 같이 나열해주셔도 좋습니다.먼저 유사한 질문이 있었는지 검색해보세요.인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.안녕하세요 댓글 최대 2 depth - CUD API 테스트 & 테스트 데이터 삽입 강의 시청 중 Test 코드에서 void delete()를 실행하면 이미지와 같이 테스트는 통과를 합니다그런데 mysql에서 명령어를 입력을 하면 deleted에는 그대로 0으로 되어 1로 변경되지 않는 문제가 있어 이전 영상을 다시 보며 모든 코드를 확인하였는데 코드는 동일하고 create, read test는 생성되고 조회되며 delete만 테스트만 실행되고 넘어가고 있습니다. 지금까지 작성한 코드 첨부합니다.https://drive.google.com/file/d/1O51-OdLHnOVnMoywcGP_h1aWoroFleF3/view?usp=drive_link
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
댓글 테스트 작성 시 에러 발생
학습 관련 질문을 최대한 상세히 남겨주세요!고민 과정도 같이 나열해주셔도 좋습니다.먼저 유사한 질문이 있었는지 검색해보세요.인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.안녕하세요. 강의를 따라가던 도중 테스트 코드에서 에러가 발생해 질문 드립니다.섹션 3. 댓글 최대 2depth - CUD API 구현 강의를 들으며void deleteShouldMarkDeletedIfHashChildren() 테스트에서 에러가 발생했습니다.에러 내용은 PotentialStubbingProblem 에 관련된 내용으로 org.mockito.exceptions.misusing.PotentialStubbingProblem: Strict stubbing argument mismatch. Please check: - this invocation of 'countBy' method: commentRepository.countBy(1L, 0L, 2L); -> at shoon.board.comment.service.CommentService.hasChildren(CommentService.java:70) - has following stubbing(s) with different arguments: 1. commentRepository.countBy(1L, 2L, 2L); 위와 같이 에러가 발생했습니다.이 내용을 토대로 살펴보았을 때, 강의에서 제공된 코드가 아래와 같은데 @Test @DisplayName("삭제할 댓글이 자식 있으면, 삭제 표시만 한다.") void deleteShouldMarkDeletedIfHasChildren() { // given Long articleId = 1L; Long commentId = 2L; Comment comment = createComment(articleId, commentId); given(commentRepository.findById(commentId)) .willReturn(Optional.of(comment)); given(commentRepository.countBy(articleId, commentId, 2L)).willReturn(2L); // //when commentService.delete(commentId); // // //then verify(comment).delete(); }이때 comment는 mock 객체로 articleId와 commentId만 가지고 있는 상황이며 getArticleId와 getCommentId만 mocking이 되어있는데, 실제 countBy 메서드가 서비스 객체에서 private boolean hasChildren(Comment comment) { return commentRepository.countBy(comment.getArticleId(), comment.getParentCommentId(), 2L) == 2; }위와 같이 호출이 되는데, 이때 getParentCommentId()의 값이 존재하지 않는데 테스트가 정상적으로 작동할 수 있나요? 테스트 코드에서는 countyBy(articleId(1), commentId(2), 2)로 고정해두었는데, 실제 호출은 이와 달라지기 때문에 에러가 발생한다고 생각이 들었는데 맞을까요? 강사님 코드에서는 정상 작동하고 제 코드는 작동이 에러가 나서 이유를 정확히 모르겠네요 ㅜㅜ혹시 제 코드가 필요하실 수도 있을까봐 구글 드라이브 링크로 제 코드 파일도 남기도록 하겠습니다.https://drive.google.com/file/d/1tqV1PkvwpnaRqI9msxEj4X_t7iqg_CFr/view?usp=drive_link
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
게시글 CRUD API 구현 부분에서 gradle 관련 에러가 발생합니다.
학습 관련 질문을 최대한 상세히 남겨주세요!고민 과정도 같이 나열해주셔도 좋습니다.먼저 유사한 질문이 있었는지 검색해보세요.인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' runtimeOnly 'com.mysql:mysql-connector-j' implementation project(':common:snowflake') }이렇게 설정 하고 gradle 싱크를 맞췄을때 A problem occurred evaluating project ':service:article'.> Project with path ':common:snowflake' could not be found in project ':service:article'. 이렇게 에러가 발생합니다.
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
개인적인 궁금증입니다
강사님께서는 실무에서 JPA를 잘 사용하지 않으신다고 하신 걸 댓글에서 봤습니다.그러면 MyBatis나 JDBC를 주로 사용하시는 건가요?아니면 JPA는 사용하시는데 쿼리 메소드 기능 대신 @Query로 직접 native query를 작성하시는 건가요?
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
무한 스크롤 쿼리와 페이지 번호 쿼리 질문 있습니다.
학습 관련 질문을 최대한 상세히 남겨주세요!고민 과정도 같이 나열해주셔도 좋습니다.먼저 유사한 질문이 있었는지 검색해보세요.인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 페이지 넘버 쿼리무한 스크롤 쿼리 안녕하세요위 두 쿼리 모두 (board_id, article_id)를 인덱스로 설정해놔서 secondary index만 접근해도 될 것 같은데 페이지 넘버 쿼리에서 clustered index도 접근하는 것은 offset의 특성(?) 때문일까요? 무한 스크롤 쿼리에서는 secondary index의 정보(board_id, article_id)만으로 기준점을 찾아내고, limit 개수만큼 clustered index에 접근하는 것 같아서페이지 넘버 쿼리에서도 secondary index의 정보(board_id, article_id)만으로도 offset의 위치를 찾을 수 있을 것 같은데 왜 clustered index까지 접근하는 걸까요??
-
미해결비전공자도 이해할 수 있는 DB 설계 입문/실전
주문수량과 재고량 관련하여 테이블 분리시
안녕하세요, 선생님.강의 감사히 잘 보고 있습니다. 주문수량에 따라 재고량 반영다는 기획일시 테이블 분리는 어떻게 할 수 있을까요?(다른 질문에 답변 올려주신 것 봤는데 직접 하려니 안되서요) 현업에서 일반적으로 매입도 존재할텐데 이 경우까지 포함한다면 재고에 대한 테이블 구성은 어떻게 되는지요? 감사합니다.
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
soft Delete 시 index 설정
학습 관련 질문을 최대한 상세히 남겨주세요!고민 과정도 같이 나열해주셔도 좋습니다.먼저 유사한 질문이 있었는지 검색해보세요.인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.안녕하세요. 먼저 강의 들으면서 정말 많은 것을 배우고 있습니다. 감사합니다.아직 index나 쿼리에 대해 이해도가 많이 부족하다 보니 궁금한 점이 있는데요. 실제 게시글이나 댓글 삭제 시 물리적 삭제가 아닌 논리적 삭제(soft delete)를 구현하게 되는 경우가 많았는데요. 이때 isDeleted같은 필드를 두고 true, false 의 boolean 값으로 관리했습니다.이후 데이터를 조회할 때는 isDeleted가 false인 것들만 조회하는 방식이었는데, 이때도 isDeleted를 복합 index의 키값으로 넣어서 관리를 하는 경우가 많을까요? 성능 향상에 많은 도움이 될 지가 궁금하네요.
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
강사님 쿼리 설명중에 로그시간 이라는 단어를 사용하시는데, 이 로그시간이라는 말의 의미를 알수 있을까요?
안녕하세요. 강의 잘 보고 있습니다.강사님 쿼리 관련 설명에서, 로그시간이라는 단어를 사용하시는데, 이 로그시간이라는 것에 의미를 좀 알수 있을까요?ex: 정확한 데이터 기준점(board_id =1, article_id=5)이 있기 때문에, 인덱스에서 로그 시간에 기존점을 찾을 수 있다.