SQLite 신입 시스템 설계 면접
새 면접Q. 간단한 개인 일정 관리 모바일 앱을 만든다고 가정합니다. 사용자의 일정 데이터를 저장하기 위해 SQLite를 선택했을 때, 어떤 테이블 구조로 설계하시겠습니까? 그리고 왜 SQLite가 이 상황에 적합한지 설명해주세요.
일정 앱에 필요한 핵심 데이터와 SQLite의 임베디드 특성을 고려해보세요.
일정 테이블(events)에는 id, title, description, start_time, end_time, location, created_at 같은 컬럼을 두고, 필요시 카테고리 테이블(categories)을 별도로 분리하여 1:N 관계로 설계하겠습니다. SQLite는 서버 없이 앱 내부에 임베디드되어 동작하므로 네트워크 연결 없이도 빠르게 데이터를 읽고 쓸 수 있습니다. 모바일 환경에서 가벼운 용량과 낮은 메모리 사용량이 장점이며, 단일 사용자 환경이므로 동시성 문제가 적습니다. 또한 별도의 설치나 설정 없이 파일 기반으로 동작하여 배포와 관리가 간편합니다.
- • events 테이블과 categories 테이블로 정규화된 구조 설계
- • SQLite의 임베디드 특성으로 네트워크 불필요
- • 모바일 환경에 적합한 가벼운 용량과 메모리 사용량
- • 단일 사용자 환경에서 동시성 문제 최소화
모바일 앱에서 오프라인 우선 전략을 구현할 때 SQLite로 로컬 데이터를 관리하고 네트워크 연결 시 서버와 동기화하는 구조로 많이 사용됩니다.
만약 이 앱이 여러 기기에서 동기화가 필요한 요구사항으로 변경된다면, SQLite 기반 아키텍처를 어떻게 수정하시겠습니까?
Q. SQLite를 사용하는 게시판 애플리케이션에서 게시글 목록 조회 API가 점점 느려지고 있습니다. 게시글이 1만 건 이상 쌓였을 때 검색과 페이징 성능을 개선하기 위한 설계 전략을 제시해주세요. 인덱스, 쿼리 최적화, 캐싱 측면에서 각각 설명해주세요.
자주 조회되는 컬럼에 대한 인덱스 전략과 결과를 재사용하는 방법을 생각해보세요.
인덱스 측면에서는 검색에 자주 사용되는 컬럼(제목, 작성일, 카테고리)에 인덱스를 생성하고, 복합 인덱스가 필요한 경우 WHERE 절과 ORDER BY에 함께 사용되는 컬럼 조합을 고려합니다. 쿼리 최적화로는 SELECT * 대신 필요한 컬럼만 명시하고, LIMIT과 OFFSET을 활용한 페이징을 구현하되 OFFSET이 큰 경우 WHERE id > last_id 방식의 커서 기반 페이징을 사용합니다. 캐싱 전략으로는 자주 조회되는 첫 페이지나 인기 게시글 목록을 메모리 캐시에 저장하고, TTL을 설정하여 일정 시간 후 갱신하도록 합니다. 게시글 작성이나 수정 시에는 관련 캐시를 무효화하여 데이터 정합성을 유지합니다.
- • 검색 조건과 정렬 기준 컬럼에 인덱스 생성
- • 커서 기반 페이징으로 대량 데이터 조회 최적화
- • 필요한 컬럼만 SELECT하여 I/O 감소
- • 메모리 캐시 활용과 캐시 무효화 전략
실제 서비스에서 게시판이나 상품 목록 같은 대량 데이터 조회 시 인덱스와 캐싱을 조합하여 응답 속도를 수십 배 개선할 수 있습니다.
인덱스를 너무 많이 생성하면 어떤 부작용이 있을까요? 인덱스 설계 시 고려해야 할 트레이드오프는 무엇인가요?
Q. 오프라인에서도 동작해야 하는 메모 작성 앱을 개발 중입니다. SQLite로 로컬 데이터를 관리하고, 네트워크가 연결되면 서버와 동기화하는 시스템을 설계해야 합니다. 로컬과 서버 간 데이터 충돌을 어떻게 처리하고, 동기화 상태를 어떻게 관리할지 설계 방안을 제시해주세요.
각 데이터의 변경 시간과 동기화 상태를 추적하는 메타데이터를 고려해보세요.
각 메모 레코드에 created_at, updated_at, synced_at, sync_status 같은 메타데이터 컬럼을 추가하여 동기화 상태를 추적합니다. sync_status는 pending, synced, conflict 같은 상태값을 가지며, 로컬에서 수정된 데이터는 pending으로 표시합니다. 네트워크 연결 시 pending 상태의 데이터를 서버로 전송하고, 서버의 updated_at과 로컬의 updated_at을 비교하여 충돌을 감지합니다. 충돌 발생 시 최종 수정 시간 기준(Last Write Wins) 또는 사용자 선택 방식으로 해결하며, 중요한 경우 양쪽 버전을 모두 보존합니다. 동기화 큐 테이블을 별도로 두어 실패한 동기화 작업을 재시도하고, 백그라운드 작업으로 주기적인 동기화를 수행합니다.
- • 메타데이터 컬럼으로 동기화 상태와 타임스탬프 관리
- • sync_status로 pending, synced, conflict 상태 추적
- • 타임스탬프 비교로 충돌 감지 및 해결 전략 적용
- • 동기화 큐와 재시도 메커니즘 구현
노션, 에버노트 같은 협업 도구나 구글 드라이브 같은 클라우드 서비스에서 오프라인 편집과 자동 동기화 기능을 구현할 때 이런 설계 패턴을 사용합니다.
Last Write Wins 방식 대신 다른 충돌 해결 전략에는 어떤 것들이 있고, 각각 어떤 상황에 적합한가요?
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!