5.5 KiB
5.5 KiB
title, source_type, status, related_branches, related_projects, tags, created, status_label
| title | source_type | status | related_branches | related_projects | tags | created | status_label | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| interview-prep / crown-one-query-vs-cqrs-lite-read-model | interview-prep | raw |
|
|
|
2026-07-15 | drafting |
interview-prep: crown-one-query-vs-cqrs-lite-read-model
Layer:
raw/interviews/— 면접 질문 원본 수집·연구 노트입니다. 다듬어진 답변은 canonical 문서를 만든 뒤wiki/interview/에 별도로 작성합니다.
Parent / 부모
- raw/branch-notes/experiment-nplus1-feed-api-replay — D3가 Crown의 one-query endpoint와 L12의 same-store CQRS-lite read port를 병존시킨 이유와 검증 범위를 소유합니다.
질문 / Question
- 질문 원문: Crown의 one native query와 L12의 same-store CQRS-lite read model은 무엇이 다르며, 어떤 경우에 각각을 선택하시겠습니까?
- 출처: N+1 replay 작업에서 예상한 면접 질문입니다.
- 받은 날짜·맥락: 실제 면접에서 받은 질문은 아닙니다.
질문 의도 추론 / Why this question
- 핵심 평가 대상: N+1 해결과 query 수 최소화를 동일시하지 않는지, read-model 경계와 트레이드오프를 설명할 수 있는지 평가합니다.
- 함정 / 흔히 빠지는 답변 패턴: 두 query라는 사실만으로 L12를 N+1이라고 부르거나, one query가 모든 read endpoint의 정답이라고 일반화하는 답변입니다.
- 따라올 만한 후속 질문: Crown이 L12를 대체하지 않는 이유는 무엇인가요? native query의 SQL과 결과 mapping은 어떻게 검증했나요?
답변 재료 / Raw answer material
- 사실 1: Crown 경로는 visible parent keyset과 parent별 Top-3 child를 하나의 native query로 읽는 endpoint-specific 최적화입니다. (근거: raw/branch-notes/experiment-nplus1-feed-api-replay D3)
- 사실 2: L12는 parent projection 한 번과 child Top-3 query 한 번을 사용하는 same-store application query port입니다. 해당 integration test에서는 entity/collection hydration이 0으로 기록됐지만, Crown의 one-query endpoint를 대체하지 않습니다. (근거: raw/branch-notes/experiment-nplus1-feed-api-replay D3, §3 Crown과 L12의 의도적 차이)
- 프로젝트 작업에서 확인한 경험: local Docker HTTP smoke에서 Crown은
prepared=1,entityLoads=0으로, L12는 20개 item과 parent당 최대 Top-3 child로 확인됐습니다. 이는 local 환경 증거입니다. (근거: raw/branch-notes/experiment-nplus1-feed-api-replay §Docker HTTP + PostgreSQL smoke — final L12 tag) - 트레이드오프: 이 작업에서는 query 수를 최소화하면서 Top-N + keyset + visibility를 한 endpoint에서 동시에 만족해야 할 때 Crown을 사용합니다. application read port의 분리를 보여 주거나 aggregate hydration 없이 두 projection query로 read shape를 조립할 때는 L12를 사용합니다. 업계 다수파·소수파에 관한 일반화는 이 raw note의 근거 범위 밖입니다. (근거: raw/branch-notes/experiment-nplus1-feed-api-replay D3)
- 한계 / "이건 안 해봤다": L12는 별도 read store나 outbox 동기화를 둔 Full CQRS가 아니며, Crown과 같은 visibility/keyset 기능을 모두 담지 않습니다. production 부하·latency SLA도 검증하지 않았습니다. (근거: raw/branch-notes/experiment-nplus1-feed-api-replay §Out of scope, D3)
Sources / 근거 (답변의 사실 근거)
- raw/branch-notes/experiment-nplus1-feed-api-replay D3 — Crown 1-query와 L12 2-query CQRS-lite를 병존시키는 결정과 선택 조건.
- raw/branch-notes/experiment-nplus1-feed-api-replay D5 —
addScalar는 runtime 결과 타입 mapping이며 Java compiler의 SQL syntax/schema 검증이 아니라는 경계.
미해결 / Unknown
- 실제 production 데이터 분포에서 Crown의 native query plan과 L12의 두 query가 어느 latency/throughput 경계에서 갈리는지 확인하지 않았습니다.
- physical read store와 동기화 계약이 필요한 시점의 Full CQRS 전환 기준은 이 작업 범위에 없습니다.
- 확인 방법: representative PostgreSQL 데이터에서
EXPLAIN (ANALYZE, BUFFERS)와 부하 측정을 수행하고, 별도 read store가 필요한 요구가 생기면 application query-bypass contract를 기준으로 새 설계를 작성합니다.
답변 경계 / Answer boundary
- 자신 있게 말할 수 있는 범위: local Docker PostgreSQL과 HTTP smoke, focused Gradle integration test에서 Crown의 one-query 관찰값과 L12의 two-query projection 동작을 확인한 범위입니다.
- "이 부분은 공식 문서를 다시 보고 답변드리겠습니다" 라고 해야 하는 부분: CQRS의 일반적 정의, physical read store를 둘 때의 동기화 방식, production scale의 성능 우위입니다.
- 절대 과장하지 말 것: Crown이 모든 상황에서 더 빠르다고 말하지 않습니다. L12를 Full CQRS나 Crown의 기능적 대체물로 말하지 않습니다. local 검증을 production 검증으로 말하지 않습니다.
addScalar가 SQL을 compile-time에 검증한다고 말하지 않습니다.
Related / 관련
- 관련 작업: raw/branch-notes/experiment-nplus1-feed-api-replay
- 후속 raw 질문 후보:
raw/interviews/native-query-addscalar-runtime-validation.md - 답변 derive 후 위치: canonical 문서가 준비된 뒤
wiki/interview/persistence/crown-one-query-vs-cqrs-lite-read-model.md