feat: 가상화 문서들 추가

This commit is contained in:
DongHyeonka
2026-09-10 08:54:05 +09:00
parent e9f6a93327
commit 43e1aadef0
695 changed files with 153404 additions and 12754 deletions
@@ -2,7 +2,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1236" height="421" viewBox="0 0 1236 421" role="img" aria-labelledby="diagram-title diagram-description">
<title id="diagram-title">두 형제 문제는 Fetch Join에서 합류한 뒤 단계별 해법으로 최종 구조가 된다</title>
<desc id="diagram-description">왼쪽에서 과제 요구사항, 도메인·데이터 모델, 최초 피드 조회 기준선 순으로 시작한다. 기준선에서 컬렉션 N+1(N1)과 User·Page 연관의 숨은 쿼리(N2)가 서로 앞뒤가 아닌 형제 문제로 동시에 갈라지고, 두 경로는 Fetch Join 시도에서 합류한다. 이 시도는 다중 컬렉션·페이징 실패로 이어진다. 마지막 노드는 Batch Fetch, DTO Projection, 아이템별 Top-3, Keyset Pagination, 가시성 조건 인덱싱을 거쳐 최종 피드 조회 구조에 도달하는 순서를 담는다.</desc>
<metadata>{&quot;techviz&quot;:{&quot;spec_version&quot;:&quot;1.1&quot;,&quot;id&quot;:&quot;strategy-journey&quot;,&quot;profile&quot;:&quot;component-flow&quot;},&quot;source_context&quot;:{&quot;document&quot;:&quot;/home/donghyeon/workspace/ai-tool/topic-arrange/n+1liner/n+1liner.md&quot;,&quot;document_sha256&quot;:&quot;1bb38964ca2a849690f5355646c1aa988111b4cd4e1055c6cb05cf7e5fc35cde&quot;,&quot;anchor&quot;:{&quot;kind&quot;:&quot;marker&quot;,&quot;value&quot;:&quot;strategy-journey&quot;,&quot;line&quot;:27}},&quot;evidence_policy&quot;:&quot;Each factual element cites source lines or is marked assumption.&quot;,&quot;diagram_only&quot;:true}</metadata>
<metadata>{&quot;techviz&quot;:{&quot;spec_version&quot;:&quot;1.1&quot;,&quot;id&quot;:&quot;strategy-journey&quot;,&quot;profile&quot;:&quot;component-flow&quot;},&quot;source_context&quot;:{&quot;document&quot;:&quot;docs/n+1liner/final/document.md&quot;,&quot;document_sha256&quot;:&quot;f9e048a68db0ab82078955bf611b06a71a0033539e0c87ff0aa0d620a3126e36&quot;,&quot;anchor&quot;:{&quot;kind&quot;:&quot;heading&quot;,&quot;value&quot;:&quot;2. 조회 전략의 전체 여정&quot;,&quot;line&quot;:30}},&quot;evidence_policy&quot;:&quot;Each factual element cites source lines or is marked assumption.&quot;,&quot;diagram_only&quot;:true}</metadata>
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" />
@@ -50,23 +50,23 @@
</style>
</defs>
<rect class="canvas" width="1236" height="421" />
<polyline class="edge kind-problem style-solid emphasis-normal" points="220.0,209.0 301.8,209.0 301.8,121.0 383.5,121.0" data-evidence="25-25" />
<rect class="edge-label-bg" x="286.6" y="151.0" width="78.3" height="22" rx="3" />
<text class="edge-label" x="325.8" y="166.0">준선에서 갈라짐</text>
<polyline class="edge kind-problem style-solid emphasis-normal" points="220.0,227.0 300.0,227.0 300.0,315.0 380.0,315.0" data-evidence="25-25" />
<rect class="edge-label-bg" x="284.9" y="257.0" width="78.3" height="22" rx="3" />
<text class="edge-label" x="324.0" y="272.0">준선에서 갈라짐</text>
<polyline class="edge kind-improvement style-solid emphasis-normal" points="864.0,218.0 944.0,218.0 944.0,218.0 1024.0,218.0" data-evidence="25-25" />
<polyline class="edge kind-problem style-solid emphasis-normal" points="220.0,209.0 305.2,209.0 305.2,121.0 390.5,121.0" data-evidence="32-33" />
<rect class="edge-label-bg" x="303.5" y="151.0" width="51.5" height="22" rx="3" />
<text class="edge-label" x="329.2" y="166.0">동시 분</text>
<polyline class="edge kind-problem style-solid emphasis-normal" points="220.0,227.0 300.0,227.0 300.0,315.0 380.0,315.0" data-evidence="32-33" />
<rect class="edge-label-bg" x="298.2" y="257.0" width="51.5" height="22" rx="3" />
<text class="edge-label" x="324.0" y="272.0">동시 분</text>
<polyline class="edge kind-improvement style-solid emphasis-normal" points="864.0,218.0 944.0,218.0 944.0,218.0 1024.0,218.0" data-evidence="34-36" />
<rect class="edge-label-bg" x="898.1" y="176.0" width="91.7" height="22" rx="3" />
<text class="edge-label" x="944.0" y="191.0">실패 뒤 단계별 개선</text>
<polyline class="edge kind-flow style-solid emphasis-normal" points="550.5,121.0 632.2,121.0 632.2,209.0 714.0,209.0" data-evidence="25-25" />
<rect class="edge-label-bg" x="597.0" y="151.0" width="118.5" height="22" rx="3" />
<text class="edge-label" x="656.2" y="166.0">Fetch Join으로 합류</text>
<polyline class="edge kind-flow style-solid emphasis-normal" points="554.0,315.0 634.0,315.0 634.0,227.0 714.0,227.0" data-evidence="25-25" />
<rect class="edge-label-bg" x="598.8" y="257.0" width="118.5" height="22" rx="3" />
<text class="edge-label" x="658.0" y="272.0">Fetch Join으로 합류</text>
<polyline class="edge kind-flow style-solid emphasis-normal" points="543.5,121.0 628.8,121.0 628.8,209.0 714.0,209.0" data-evidence="34-34" />
<rect class="edge-label-bg" x="630.8" y="151.0" width="44.0" height="22" rx="3" />
<text class="edge-label" x="652.8" y="166.0">합류</text>
<polyline class="edge kind-flow style-solid emphasis-normal" points="554.0,315.0 634.0,315.0 634.0,227.0 714.0,227.0" data-evidence="34-34" />
<rect class="edge-label-bg" x="636.0" y="257.0" width="44.0" height="22" rx="3" />
<text class="edge-label" x="658.0" y="272.0">합류</text>
<g id="node-requirements-model-baseline">
<rect class="node-shape kind-journey-stage emphasis-normal role-source" data-evidence="25-25" x="70.0" y="165.5" width="150.0" height="105.0" rx="7" />
<rect class="node-shape kind-journey-stage emphasis-normal role-source" data-evidence="23-26,42-42" x="70.0" y="165.5" width="150.0" height="105.0" rx="7" />
<text class="node-label" x="145.0" y="192.5">요구사항·모델·기준선</text>
<line class="node-detail-divider" x1="84.0" y1="213.5" x2="206.0" y2="213.5" />
<text class="node-detail" x="86.0" y="230.5">1 과제 요구사항</text>
@@ -74,32 +74,32 @@
<text class="node-detail" x="86.0" y="262.5">3 최초 피드 조회</text>
</g>
<g id="node-collection-n-plus-one">
<rect class="node-shape kind-problem emphasis-normal role-service" data-evidence="25-25" x="383.5" y="60.0" width="167.0" height="122.0" rx="7" />
<rect class="node-shape kind-problem emphasis-normal role-service" data-evidence="32-34" x="390.5" y="60.0" width="153.0" height="122.0" rx="7" />
<text class="node-label" x="467.0" y="87.0">컬렉션 N+1 (N1)</text>
<line class="node-detail-divider" x1="397.5" y1="108.0" x2="536.5" y2="108.0" />
<text class="node-detail" x="399.5" y="125.0">유형: 컬렉션 N+1</text>
<text class="node-detail" x="399.5" y="141.0">발생: 기준선과 동시에</text>
<text class="node-detail" x="399.5" y="157.0">관계: N2와 형제 문제</text>
<text class="node-detail" x="399.5" y="173.0">진행: Fetch Join으로 합류</text>
<line class="node-detail-divider" x1="404.5" y1="108.0" x2="529.5" y2="108.0" />
<text class="node-detail" x="406.5" y="125.0">유형: 컬렉션 N+1</text>
<text class="node-detail" x="406.5" y="141.0">발생: 기준선과 동시에</text>
<text class="node-detail" x="406.5" y="157.0">관계: N2와 형제 문제</text>
<text class="node-detail" x="406.5" y="173.0">진행: Fetch Join 합류</text>
</g>
<g id="node-hidden-to-one-queries">
<rect class="node-shape kind-problem emphasis-normal role-service" data-evidence="25-25" x="380.0" y="254.0" width="174.0" height="122.0" rx="7" />
<rect class="node-shape kind-problem emphasis-normal role-service" data-evidence="32-34" x="380.0" y="254.0" width="174.0" height="122.0" rx="7" />
<text class="node-label" x="467.0" y="281.0">User·Page 숨은 쿼리 (N2)</text>
<line class="node-detail-divider" x1="394.0" y1="302.0" x2="540.0" y2="302.0" />
<text class="node-detail" x="396.0" y="319.0">유형: User·Page 숨은 쿼리</text>
<text class="node-detail" x="396.0" y="335.0">발생: 기준선과 동시에</text>
<text class="node-detail" x="396.0" y="351.0">관계: N1과 형제 문제</text>
<text class="node-detail" x="396.0" y="367.0">진행: Fetch Join으로 합류</text>
<text class="node-detail" x="396.0" y="367.0">진행: Fetch Join 합류</text>
</g>
<g id="node-fetch-join-failure">
<rect class="node-shape kind-query-strategy emphasis-warning role-service" data-evidence="25-25" x="714.0" y="174.0" width="150.0" height="88.0" rx="7" />
<rect class="node-shape kind-query-strategy emphasis-warning role-service" data-evidence="34-35" x="714.0" y="174.0" width="150.0" height="88.0" rx="7" />
<text class="node-label" x="789.0" y="201.0">Fetch Join → 실패</text>
<line class="node-detail-divider" x1="728.0" y1="222.0" x2="850.0" y2="222.0" />
<text class="node-detail" x="730.0" y="239.0">1 N1·N2 합류</text>
<text class="node-detail" x="730.0" y="255.0">2 다중 컬렉션·페이징 실패</text>
</g>
<g id="node-improvement-chain">
<rect class="node-shape kind-query-strategy emphasis-primary role-sink" data-evidence="25-25" x="1024.0" y="140.0" width="167.0" height="156.0" rx="7" />
<rect class="node-shape kind-query-strategy emphasis-primary role-sink" data-evidence="32-32,35-36" x="1024.0" y="140.0" width="167.0" height="156.0" rx="7" />
<text class="node-label" x="1107.5" y="168.0">후속 개선 → 최종 구조</text>
<line class="node-detail-divider" x1="1038.0" y1="189.0" x2="1177.0" y2="189.0" />
<text class="node-detail" x="1040.0" y="206.0">1 Batch Fetch</text>

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB