Hong
@jhong
Học viên
7,224
Đánh giá khóa học
447
Đánh giá khóa học
4.7
자기 소개
집에서 빈둥대다 개발에 흥미를 느껴 개발 공부를 시작하였고 현재는 판교에서 플랫폼 서버 개발을 담당하여 진행하고 있습니다. 제가 공부를 했던 방법과 실무에서 접하실 수 있는 여러가지 문제점들과 해결책을 여러분들에게 제공하고 싶어 지식공유자 활동을 이어나가고 있습니다.
강의는 오로지 저만의 지식을 통해 만들어지지 않습니다. 모든 강의는 함께하시는 분들이 계십니다.
지식공유자 경력
[前] 샌드박스IP 관련 블록체인 개발자
[前] 메타버스 백엔드 개발자
[現] 판교에서 고여가는 서버 개발자
인터뷰 이력
기타 문의
unduck2022@gmail.com
Khóa học
Đánh giá khóa học
- Học MySQL từ các nhà phát triển Toss xử lý hơn 500 tỷ dữ liệu tài chính
- Hệ thống phân tán nhắn tin và độ trễ cực thấp NATS được sử dụng bởi người phỏng vấn Naver
byeongseogi492130
·
Môi trường phân tán (Distributed Environment) bạn nhất định phải biết - được chia sẻ bởi phỏng vấn viên KakaoMôi trường phân tán (Distributed Environment) bạn nhất định phải biết - được chia sẻ bởi phỏng vấn viên Kakaobyeongseogi492130
·
Hệ thống phân tán nhắn tin và độ trễ cực thấp NATS được sử dụng bởi người phỏng vấn NaverHệ thống phân tán nhắn tin và độ trễ cực thấp NATS được sử dụng bởi người phỏng vấn Naver- Các mẫu giao dịch phân tán từ góc nhìn MSA do phỏng vấn viên Kakao chia sẻ
Bài viết
Hỏi & Đáp
service 를 interface 로 두는 이유
안녕하세요 쵸잉님 질문 주셔서 감사합니다. 말씀해주신부분처럼 굳이 인터페이스를 사용하지 않아도 됩니다. 이건 개인적인 스타일에 가까운거 같아요. 그래서 제 코드가 옳다고 말씀드리기에는 좀 조심스러운 부분이 있습니다. 근데 분리하게 되었을 떄 가질 수 있는 장점은 몇개 있습니다. 대표적으로 CGLIB 같은 문제로 인해서 생성자 제약을 피할 수도 있고, DIP 원칙의 관점에서 구현체가 바뀐다는 부분도 가정했을 떄 변경하기도 편하죠. 뭐 굳이 따지자면 이런 이유들이 다양하게 있는데, 우리가 현실적으로 코드 작성할 떄 막 이런 케이스까지 고려하지는 않습니다. 그래서 쵸잉님이 원하시는 스타일로 작성하셔도 큰 문제는 없을꺼같네요. 어디까지나 개발은 각자만의 스타일이 있으니깐요 ㅎㅎ 이정도면 이해가 되셨을까요??감사합니다!
- 0
- 1
- 28
Hỏi & Đáp
강의에서 작성한 코드 제공 문의
안녕하세요. 강의 초기에 소스코드 챕터가 있는데 거기에서 다운로드 하시면 됩니다!! 감사합니다!!
- 0
- 1
- 31
Hỏi & Đáp
21강에서 이해하기 어려운 부분들이 있습니다!
안녕하세요 제우님 질문 남겨주셔서 감사합니다. 하나하나 나눠서 설명드려보도록 할게요. 근본적인 아키텍처에 어떤 문제점이 생기는지, 잘 모르겠습니다.이거는 비지니스 요구사항에 따라 스키마 변경이 야기하는 다양한 문제입니다. 즉 테이블 구조 변경이 요구사항을 모두 처리하지 못하는 상황이 예시가 될 꺼 같아요. 예를 들어 is_vip, is_blocked, is_verified, is_dormant ... 이런 식으로 컬럼이 계속 추가되면 테이블이 비즈니스 로직의 변화에 종속되고, 나중에 "이 컬럼이 왜 있지?"를 추적하기 어려워집니다. 즉 확장성과 유지보수성 에 집중한 문제로 이해하시면 됩니다. ALTER로 스키마를 변경하는 것으로 문제가 야기되는 부분이 정확히 어떤 부분이라고 생각하시는지 궁금합니다. 이미 많은 레코드가 있는 테이블의 스키마를 변경함으로써 생겨나는 I/O 부하를 생각하시는 걸까요? 맞게 이해하신겁니다. Lock을 유발하는게 문제인거에요. MySQL InnoDB 기준으로 컬럼 추가 시 Online DDL이 지원되긴 하지만, 상황에 따라 테이블 전체를 리빌드 할 수 있죠. 그러면 수천만 건 테이블이면 이 작업 자체가 수십 분이고, 그 동안 쓰기가 블로킹되거나 서비스에 영향을 주는 부분을 피해갈 수가 없어요. 이게 Boolean 컬럼이 추가될 때마다 이 비용이 반복되면 문제가 되겠죠. I/O 비용의 증가가 발생한다는 부분은 2번에서의 비용 증가를 말씀해주신 걸까요? SELECT 비용 증가라면 사실 저장해야 하는 정보가 늘어나면서 자연스러운게 아닌가 싶은데 어떤 관점에서의 문제를 짚어주신 건지 궁금합니다. 뭐 부하는 어떻게든 발생 가능한 구조로 이해하시면 됩니다. SELECT 부분에 대해서도 페이지 단위로 인한 부하가 있을 수 있고, 저장하는 정보가 많아지니깐 사실상 매우 자연스러운 행동이죠 다만 Boolean 컬럼의 특성상 대부분 NULL 또는 false인 경우가 많아서 실제로 의미 있는 데이터 밀도가 낮은데 row 크기만 커지는 비효율이 생길 수 있다는 부분도 같이 얻어가보시면 좋지 안흥ㄹ까 싶어요. 논리 모델 vs 물리 모델, 그리고 세 가지 기법 네 이해하신 방향이 틀리지 않습니다. 다시 정리해보죠. 논리 모델은 "어떤 데이터를 저장할 것인가"이고, 물리 모델은 "실제 DB에 어떻게 저장할 것인가"로 생각을 하시면 됩니다. 이 상황에서 Boolean 속성이 많아지는 문제를 논리 모델 레벨에서 "이 엔티티는 여러 속성을 가진다"로 정의 할 수 있고, 물리 모델 레벨에서 그걸 어떻게 테이블로 구현할지를 선택하는 단계를 거치는 거죠. 이 떄 구현 방법은 3가지가 있을겁니다.One Table per Anchor: 기본 테이블 하나에 핵심 속성만 두는 방식Side Table: Boolean이나 부가 속성을 별도 테이블로 분리 (ex. user_flags 테이블)EAV (Entity-Attribute-Value): user_id | attribute_name | value 형태로 속성 자체를 행으로 저장 그래서 제가 말씀드리고 싶은 부분은 무작정 Boolean을 추가하는건 논리 모델을 그대로 물리 모델로 박아버리는 행위라고 말씀드리고 싶었어요. 뭐 상황에 따라서 나쁜 선택은 아닐 수 있다고는 생각합니다. 하지만 과연 이 방식이 가장 좋은 방식인가?? 이건 제가 판단하기에는 어려운 부분일꺼 같네요. 질문에 답이 좀 되셨을까요?? 혹시 추가적인 질문이 있다면 남겨주세요!! 좋은 하루보내세요~~
- 0
- 1
- 24
Hỏi & Đáp
혹시 오픈카톡 링크는 어디서 볼수 있을까요?
안녕하세요!! 현재 준비중에 있습니다 ㅠㅠ 아무래도 다른분들도 바쁘다보니... 생각보다 빠르게 진행이되지 않네요 ㅠㅠ 최대한 빠른시일에 준비하여 새소식을 통해 공유드리도록 하겠습니다. 감사합니다!
- 0
- 1
- 36
Hỏi & Đáp
칼럼명
안녕하세요 SJ님 질문 주셔서 감사합니다. 새해 복 많이 받으세요 ㅎㅎ 일단 무엇이 틀렸다 맞다라는 논쟁은 아닌거 같고 개인적인 취향과 가독성 측면에서 차이가 있을거같습니다.저는 어느정도 JOIN을 하는데에 있어서 의미가 더 명확한거 같아서 다음과 같이 수행한 바도 있어요. 예를들어서SELECT * FROM Posts p JOIN Users u ON p.user_id = u.user_id;이런 쿼리만 봐도 어떤 테이블의 키인지 명확하고 다중 조인하는 상황이 발생해도 가독성이 좋다고 생각합니다. 근데 만약 pk를 id로 둔다면JOIN Users u ON p.user_id = u.id이런 형태인건데, 이게 틀린건 절대 아니에요. 근데 테이블이 많아진다면 가독성이 안좋아질꺼 같아요. 예를들면 이렇게 되는거죠u.id p.id t.id c.id저는 개인적으로 가독성이 중요한 성격이라서 이 쿼리만을 보고 어떤 쿼리인지 의미가 명확하게 와닿지 않을꺼 같습니다. 자기참조 측에서를 고려해 볼까요?? 예를들어서 User가 이런 구조라고 해보죠parent_user_id INT FOREIGN KEY (parent_user_id) REFERENCES Users(user_id)여기서도 사실 크게 다를바가 없습니다. 근데 만약 PK가 id라면??FOREIGN KEY (parent_user_id) REFERENCES Users(id)사용하는데에는 문제는 없지만 앞서 제가 말씀드린 저의 곤점에서의 모델링 문서나 ERD 작성 측면에서 명확성이 더 떨어지는거 같아요. 하지만 어디까지나 이건 제 취향일뿐 원하시는대로 해도 무방합니다. 사용하는데에 무방하고 취향적인 부분이 들어간 주제라고 생각해서 이걸 제가 맞다 틀리다라고 하고 싶지는 않아요. 질문 감사합니다!
- 0
- 2
- 30
Hỏi & Đáp
프로시저
안녕하세요 SJ님 질문 주셔서 감사합니다. 새해 복 많이 받으세요 ㅎㅎ 일단 프로시저를 저는 권장하는 성격은 아닙니다. 단순히 코드수준을 넘어서서 쿼리 수준에서 디버깅하는것과 기능을 추가하는 작업이 더 어렵기 떄문이에요. 그래서 저는 코드단에서 사용하시는 것을 추천드립니다. 제가 강의에서도 언급한거 같은데, 상황에 따라 프로시저가 유용한겁니다. 이 구조를 추천드리지는 않아요.예를들면 다른 팀의 DB에 접근해서 데이터를 가져와야하는데, DB의 데이터가 유출되는것을 방지하기 위해 프로시저 권한만을 사용해 데이터를 가져와야 한다던지 등등보안적인 측면에서의 고려사항이 아니라면 일반 플랫폼에서 프로시저를 사용하는걸 전 비추천드릴꺼 같아요. 질문 감사합니다!
- 0
- 2
- 29
Hỏi & Đáp
인덱스 분할, 병합에 따른 인덱스 적용 기준과 OPTIMIZE TABLE
안녕하세요 soap님 질문주셔서 감사합니다!! 먼저 새해가 지났지만 복 많이 받으시고 건강하시기를 바랄게요 ㅎㅎ 하나하나 개요를 나눠서 설명드릴게요. 질문1 : 인덱스 분할/병합 관점에서 “걸어도 된다”는 결론에 도달하는 과정 현실적으로 그런 케이스는 거의 없습니다. 저도 그렇게 사용해 본적이 없고 저와 함께 강의를 만드시는 분들도 그런 과정을 통해서 판단을 하지 않아요. 왜냐하면 그건 트래픽의 유형에 따라서 너무나도 달라지는 값이기 떄문입니다. 그래서 무언가 기준을 잡고 이 기준을 넘어서면 설정한다. 이런식의 사고 과정이 아니라 그냥 읽기 트래픽에 집중한다. 이 부분만을 명심하시면 좋을꺼같아요. 그래서 저는 보통 다음 순서로 판단합니다:실제 쿼리 패턴 확인 (슬로우 쿼리, 실행 계획)풀스캔 비용 추정해당 인덱스가 선택될 가능성 확인 (Cardinality, Selectivity)쓰기 부하 패턴 분석 (INSERT/UPDATE 비율) 그래서 핵심은 "이 인덱스가 없으면 실제로 서비스가 느려지는가?" 이 부분에 집중하시면 되는 겁니다. 읽기 쿼리가 문제가 없다면 굳이 쓰기 비용을 늘릴 필요는 없기 떄문이에요. 질문2 : 인덱스 분할(split)이 실제로 문제가 되는 경우 여러분들이 일반적으로 사용하는 MySQL은 InnoDB를 사용하고 있고, 이 InnoDB의 B-Tree 인덱스는 삽입하는 과정에서 페이지가 가득 차다면 분할이 발생하게 됩니다. 이 과정에서는 여러가지 작업이 일어나죠페이지 복사포인터 재정렬redo log 증가잠금 범위 확장 등등 근데 여기서 중요한거는 이 많은 과정에서 우리는 이 두가지에 집중을 해야하는거에요.PK가 AUTO_INCREMENT라면 → 대부분 우측 삽입 → split 빈도 낮음랜덤 키(UUID 등)라면 → 중간 삽입 → split 빈도 높음 그래서 UUID를 PK로 사용했을 떄에는 인덱스를 조심하셔야 하고, 조회가 압도적으로 많다면 그냥 인덱스를 걸어버리는 과정으로 이해하시면 됩니다. 무작위성만을 조심하면 될 꺼 같아요. 질문3 : 라이브 환경에서의 OPTIMZE TABLE 이건 이해하신것처럼 최후의 수단이 맞습니다. 왜냐하면 사실상 해당 과정을 진행하면 테이블 재생성인덱스 재구성데이터 재정렬메타데이터 락 발생이런 문제들이 존재하기 떄문이에요.물론 8.0이상에서는 online DDL이 가능하죠. 그래서 가능은 하지만 갑작스럽게 리소스 사용량이 급증한다는 문제가 있습니다. 그래서 OPTIMZE TABLE이 어떤 부분에서 위험한지 이해하시고 내가 이걸 이 상황에 적용해도 문제가 없는지 객관적인 부분들을 검토해보시면 좋지 않을까싶어요. 질문 감사합니다!!
- 0
- 2
- 42
Hỏi & Đáp
커서 기반 페이징 조건 대상으로 AUTO_INCREMENT vs ULID
안녕하세요 제우님 질문 주셔서 감사합니다. 일단 커서 기반의 페이징은 쉽게 말하면 WHERE 조건절에 값을 추가함으로써 탐색하는 Raw의 갯수를 줄이는 대표적인 튜닝 기법입니다.MySQL의 쿼리 실행순서가 우선 WHERE 조건 절이 동작한다는 부분을 이용하는거죠. 그래서 본질은 "마지막으로 본 지점 이후의 데이터를 이어서 본다" 라는걸 이해하셔야 해요.이 명제가 성립하려면, 제우님이 말씀해주신 조건(유니크하고 정렬 가능함)에 더해, 값이 단조적으로 증가해야 한다는 전제가 필요합니다. 단순히 숫자가 증가하는 것처럼 보이더라도, 중간 값이 비어 있다는 것은 곧 삽입과 값의 흐름이 완전히 일치하지 않을 가능성을 배제 할 수 없다는거에요. 예를 들어 AUTO_INCREMENT 컬럼에서 트랜잭션이 롤백되거나, 동시성 환경에서 먼저 번호를 선점한 트랜잭션이 나중에 커밋되는 상황이 발생할 수도 있고요. 이 경우 숫자는 증가하지만 실제 데이터가 생성된 시간 순서와 값의 순서가 어긋날 수 있습니다. 기본적으로 WHERE id > last_id 이 조건이 안전하려면 last_id 이후에 생성된 데이터는 반드시 id 값도 더 커야 한다는 보장이 필요한데.... 중간 값이 비어 있게 된다면 어떤 값이 건너 뛰어졌거나 순서가 엇갈릴 수 있다는걸 의미하고 이게 곧 값이 증가한다는게 생성하는 순서가 맞다라는 가정이 성립하지 않는다는 관점으로 이해하시면 좋을꺼 같아요. 즉 그래서 예시를 들어보자면 사용자가 1페이지, 2페이지를 조회한 이후 새로운 데이터가 들어왔는데, 그 데이터의 값이 이미 지나간 구간에 속해버린다면 해당 데이터는 영원히 노출되지 않을 수 있는거죠. 커서 기반 페이징은 OFFSET처럼 다시 처음부터 훑는 방식이 아니기 때문에, 한 번 지나간 구간은 다시 탐색하지 않는다는 특징이 있기 떄문이에요. 어떻게 이해가 좀 되셨을까요?? 혹시 이해가 안되는 부분이 있다면 편하게 질문 주세요. 감사합니다!
- 0
- 2
- 35
Hỏi & Đáp
이벤트 발행이 불필요한 것은 어떻게 구분하나요?
안녕하세요 지찬님 질문 주셔서 감사합니다. 자 일단 CDC 라는 기법은 DB에 변경되는 이벤트들을 탐지하고 이를 이벤트로 전송하고 다루는 기술을 의미 합니다. 이떄 다룰 수 있는 기술은 CREATE, UPDATE, DELETE 이 3가지를 다룰 수 있을거고요. 여기서 CDC가 불필요하다?? 그러면 지찬님이 생성하시는 CDC Connector ( Kafka Connector )에 해당 기능은 뺴면 됩니다.즉 예를들어서 A라는 테이블에 발생하는 이벤트만 잡고 싶어. -> A 테이블만 포함B라는 테이블에 발생하는 이벤트는 잡기 싫어 -> B 테이블을 제외 이러면 끝나는거에요.! 간단한 설정값을 통해서 원하는 테이블만 확인하실 수 있으니 이 부분 참고하시면 질문에 대한 답이 되지 않을까 싶습니다. 감사합니다!
- 0
- 2
- 34
Hỏi & Đáp
13강에서 말씀하신 엄청난 쿼리가 어떤 쿼리일까요?
안녕하세요 제우님 질문 주셔서 감사합니다. 음.. 어느정도 제가 추상적으로 표현한바가 있어서 확 와닿지 못하실만한거 같아요. 제가 말씀드린 복잡한 분석을 하는 경우에 엄청난 쿼리를 전송하는 경우도 있고~ 에 대한 쿼리는 사실 정해진 틀이 없어서 저렇게 설명드린 바가 있습니다. 예를들어서, 말씀해주신것처럼 플랫폼에서 복잡한 연산을 수행해야 하는 쿼리가 있을겁니다. 그런 부분들에 대한것도 해당 부분에 포함되는것이고, 팀마다 각자 혼용해서 운영이 되어야 할 떄 보안상의 이유로 프로시저를 통해서만 데이터를 가공해서 받는 경우가 있을꺼에요. 이걸 SP라고 실무에서는 자주 줄여서 부르는데, 이런 경우에는 쿼리 자체가 굉장히 복잡하게 구성되는 케이스도 있습니다. 말씀하신 부분처럼 쿼리가 길고 뚱뚱한 쿼리도 해당 할 수 있어요. 대개 이런 쿼리는 복잡한 연산이나 작업을 수행하기 떄문이죠. 또한 CTE와 같은 쿼리 형태도 일부 해당 될 수 있습니다. 현실적으로 CTE는 단계가 나눠져있기 떄문에 포함시키기는 좀 애매한거 같기는한데... CTE의 쿼리가 얼마나 되는지에 따라서 달라질꺼 같아요. 그래서 그냥 제우님이 봤을 떄 아 쿼리가 뭐가 이렇게 계산하는게 많고 연관해서 가져오는게 많아?? 라고 느끼실 수 있는 쿼리가 대부분 저 내용에 해당할꺼같습니다.아무래도 딱 기준이 없다보니 설명하기 좀 어려운 부분이 있네요 ㅠㅠ 질문 감사합니다!!
- 0
- 1
- 38





