SQLite 면접 질문 및 답변

SQLiteBeginner
지금 연습하기

소개

SQLite 면접 질문 및 답변에 대한 종합 가이드에 오신 것을 환영합니다! 숙련된 개발자로서 지식을 새로 고치려는 분, 다음 커리어 단계를 준비하는 데이터베이스 관리자, 또는 임베디드 데이터베이스를 마스터하려는 열정적인 전문가이든, 이 문서는 여러분이 탁월한 성과를 거두는 데 필요한 통찰력을 제공하도록 설계되었습니다. 기본 개념과 고급 기능부터 실용적인 문제 해결 시나리오, 애플리케이션 개발 고려 사항 및 중요한 관리 측면에 이르기까지 광범위한 주제를 다룹니다. 저희의 목표는 면접에 합격하는 데 도움이 될 뿐만 아니라 SQLite 의 기능과 실제 애플리케이션을 위한 모범 사례에 대한 이해를 심화시키는 강력한 리소스를 제공하는 것입니다.

SQLITE

SQLite 의 기본 개념 및 아키텍처

SQLite 란 무엇이며 주요 특징은 무엇인가요?

답변:

SQLite 는 자체 포함형 (self-contained), 서버리스 (serverless), 제로 구성 (zero-configuration), 트랜잭션 (transactional) SQL 데이터베이스 엔진입니다. 임베디드 데이터베이스로, 데이터베이스 엔진이 애플리케이션 자체의 일부가 되어 이식성이 높고 배포가 용이합니다.


SQLite 의 '서버리스' 특성에 대해 설명해주세요.

답변:

SQLite 에서 서버리스라는 것은 작동을 위해 별도의 서버 프로세스가 필요 없다는 것을 의미합니다. 애플리케이션은 디스크 상의 데이터베이스 파일과 직접 상호 작용하며, 클라이언트 - 서버 통신이 필요 없어 배포가 단순화됩니다.


SQLite 는 동시성 (concurrency) 과 여러 사용자가 동일한 데이터베이스에 접근하는 것을 어떻게 처리하나요?

답변:

SQLite 는 파일 레벨 잠금 (file-level locking) 을 사용하여 동시성을 관리합니다. 여러 읽기 작업은 동시에 허용되지만, 한 번에 하나의 쓰기 작업만 데이터베이스에 접근할 수 있습니다. 쓰기 작업은 트랜잭션이 커밋될 때까지 다른 읽기 및 쓰기 작업을 차단합니다.


SQLite 맥락에서 ACID 속성을 설명해주세요.

답변:

SQLite 는 ACID 속성 (원자성, 일관성, 고립성, 지속성) 을 완벽하게 지원합니다. 원자성 (Atomicity) 은 트랜잭션이 모두 성공하거나 모두 실패함을 보장합니다. 일관성 (Consistency) 은 데이터 무결성을 보장합니다. 고립성 (Isolation) 은 동시 트랜잭션이 서로 간섭하지 않도록 합니다. 지속성 (Durability) 은 커밋된 변경 사항이 영구적임을 의미합니다.


SQLite 에서 단일 데이터베이스 파일의 중요성은 무엇인가요?

답변:

단일 데이터베이스 파일 (.db 또는 .sqlite) 에는 테이블, 인덱스, 트리거 및 뷰를 포함한 전체 데이터베이스가 포함됩니다. 이는 전체 데이터베이스가 단 하나의 파일이므로 백업, 복제 및 이식을 단순화합니다.


PostgreSQL 또는 MySQL 과 같은 클라이언트 - 서버 데이터베이스 대신 SQLite 를 선택하는 경우는 언제인가요?

답변:

SQLite 는 임베디드 시스템, 모바일 애플리케이션, 데스크톱 애플리케이션 및 소규모 웹 애플리케이션과 같이 단순성, 제로 구성 및 이식성이 중요한 경우에 이상적입니다. 고동시성, 다중 사용자 환경 및 전용 서버가 필요한 경우에는 적합하지 않습니다.


SQLite 아키텍처의 주요 구성 요소는 무엇인가요?

답변:

주요 구성 요소에는 SQL 파서 (SQL Parser), 쿼리 최적화기 (Query Optimizer), 데이터 저장을 위한 B-tree 구현, 페이저 (Pager, 디스크 I/O 및 캐싱 처리), OS 인터페이스 계층 (OS Interface layer) 이 있습니다. 이들은 함께 작동하여 SQL 명령을 처리하고 데이터를 관리합니다.


SQLite 는 외래 키 제약 조건 (foreign key constraints) 을 지원하나요? 지원한다면 어떻게 활성화하나요?

답변:

네, SQLite 는 외래 키 제약 조건을 지원합니다. 하지만 하위 호환성을 위해 기본적으로 비활성화되어 있습니다. 각 데이터베이스 연결에 대해 PRAGMA foreign_keys = ON; 문을 사용하여 런타임에 활성화할 수 있습니다.


SQLite 데이터베이스 파일의 최대 크기는 얼마인가요?

답변:

SQLite 데이터베이스 파일의 최대 크기는 이론적으로 281 테라바이트 (2^47 바이트) 입니다. 그러나 실제 제한은 SQLite 자체보다는 기본 파일 시스템이나 사용 가능한 디스크 공간에 의해 종종 부과됩니다.


고급 SQLite 기능 및 최적화

SQLite 에서 VACUUM 사용의 목적과 이점은 무엇인가요?

답변:

VACUUM은 데이터베이스 파일을 재구축하여 삭제된 데이터의 사용되지 않는 공간을 회수하고 데이터베이스를 조각 모음합니다. 이를 통해 데이터베이스 파일 크기를 줄이고 성능을 향상시킬 수 있으며, 특히 많은 업데이트나 삭제 작업 후에 효과적입니다.


SQLite 의 WAL(Write-Ahead Log) 모드란 무엇이며, 기존 롤백 저널 (rollback journal) 에 비해 어떤 장점이 있나요?

답변:

WAL 모드는 변경 사항을 메인 데이터베이스에 적용하기 전에 별도의 로그 파일에 기록합니다. 장점으로는 동시성 향상 (읽기 작업이 쓰기 작업을 차단하지 않음), 더 나은 충돌 복구, 그리고 적은 디스크 탐색으로 인한 향상된 쓰기 성능이 있습니다.


SQLite 에서 대량의 행에 대한 INSERT 성능을 어떻게 최적화할 수 있나요?

답변:

BEGIN TRANSACTIONCOMMIT을 사용하여 여러 INSERT 문을 단일 트랜잭션으로 묶으세요. 이는 각 행마다 커밋하는 대신 한 번만 커밋함으로써 디스크 I/O 오버헤드를 크게 줄여줍니다.


SQLite 에서 'EXPLAIN QUERY PLAN'의 개념과 최적화를 위해 어떻게 사용되는지 설명해주세요.

답변:

EXPLAIN QUERY PLAN은 SQLite 의 쿼리 최적화기가 특정 SQL 문에 대해 선택하는 실행 계획을 보여줍니다. 전체 테이블 스캔이나 누락된 인덱스와 같은 성능 병목 현상을 식별하는 데 도움이 되어, 대상 최적화를 가능하게 합니다.


SQLite 에서 부분 인덱스 (partial indexes) 를 사용하는 것을 고려해야 하는 경우는 언제인가요?

답변:

부분 인덱스 (또는 필터링된 인덱스) 는 특정 조건에 따라 테이블의 행 하위 집합을 자주 쿼리할 때 유용합니다. 전체 인덱스보다 작고 유지 관리가 빠르므로 저장 공간 및 쓰기 오버헤드를 줄여줍니다.


SQLite 에서 PRAGMA journal_mode의 중요성은 무엇이며, 일반적인 값은 무엇인가요?

답변:

PRAGMA journal_mode는 SQLite 가 롤백 저널 또는 WAL 파일을 처리하는 방식을 제어합니다. 일반적인 값으로는 DELETE(기본값), TRUNCATE, PERSIST, MEMORY, OFF, WAL이 있습니다. WAL은 성능 및 동시성 측면에서 자주 선호됩니다.


SQLite 는 동시 액세스, 특히 여러 읽기 및 쓰기 작업자를 어떻게 처리하나요?

답변:

기존 롤백 저널 모드에서는 쓰기 작업자가 읽기 작업자와 다른 쓰기 작업자를 차단합니다. WAL 모드에서는 단일 쓰기 작업자가 활성화된 동안 여러 읽기 작업자가 데이터베이스에 동시에 액세스할 수 있어 동시성이 크게 향상됩니다. 쓰기 작업자는 여전히 직렬화됩니다.


SQLite 최적화에서 ANALYZE의 역할에 대해 설명해주세요.

답변:

ANALYZE는 테이블 및 인덱스의 데이터 분포에 대한 통계를 수집합니다. 쿼리 최적화기는 이러한 통계를 사용하여 쿼리 계획에 대한 더 나은 결정을 내리며, 특히 복잡한 쿼리의 경우 더 효율적인 실행으로 이어집니다.


SQLite 에서 성능을 위한 스키마 설계 시 일반적인 함정은 무엇인가요?

답변:

일반적인 함정으로는 적절한 데이터 유형을 사용하지 않는 것, 작은 데이터에 TEXT 또는 BLOB을 과도하게 사용하는 것, 자주 쿼리되는 열에 인덱스를 사용하지 않는 것, 과도한 정규화로 인해 너무 많은 조인 (join) 이 발생하는 것, 그리고 불충분한 정규화로 인해 중복 데이터가 발생하는 것 등이 있습니다.


언제 인메모리 SQLite 데이터베이스 (:memory:) 를 사용하는 것을 선택할 수 있나요?

답변:

인메모리 데이터베이스는 임시 데이터 저장, 단위 테스트 또는 영속성 없이 고속의 일시적인 데이터 처리가 필요한 시나리오에 이상적입니다. 연결이 닫히면 모든 데이터가 손실됩니다.


SQLite 를 사용한 시나리오 기반 문제 해결

시나리오: products 테이블에 product_id, product_name, price 컬럼이 있습니다. 가장 비싼 상위 5 개 제품을 어떻게 찾을 수 있나요?

답변:

ORDER BYLIMIT를 사용할 수 있습니다. SELECT product_name, price FROM products ORDER BY price DESC LIMIT 5; 이 쿼리는 제품을 가격의 내림차순으로 정렬하고 처음 5 개를 가져옵니다.


시나리오: 'Electronics' 카테고리에 속하는 제품의 가격을 10% 인상해야 합니다. products 테이블에 category_id 외래 키가 있고, categories 테이블에는 category_idcategory_name이 있다고 가정합니다.

답변:

UPDATE 문과 JOIN 또는 서브쿼리를 사용합니다. UPDATE products SET price = price * 1.10 WHERE category_id = (SELECT category_id FROM categories WHERE category_name = 'Electronics'); 이 쿼리는 지정된 카테고리의 가격을 효율적으로 업데이트합니다.


시나리오: sales 테이블에 sale_id, product_id, sale_date, quantity 컬럼이 있습니다. 지난 30 일 동안 각 제품별 총 판매 수량을 어떻게 계산할 수 있나요?

답변:

SUM()GROUP BY, 그리고 날짜 필터를 사용합니다. SELECT product_id, SUM(quantity) AS total_quantity_sold FROM sales WHERE sale_date >= date('now', '-30 days') GROUP BY product_id; 이 쿼리는 지정된 기간 동안의 판매 데이터를 집계합니다.


시나리오: 3 개 이상의 주문을 한 고객을 찾아야 합니다. customers (customer_id, customer_name) 및 orders (order_id, customer_id, order_date) 테이블이 있습니다.

답변:

GROUP BYHAVING을 사용합니다. SELECT c.customer_name FROM customers c JOIN orders o ON c.customer_id = o.customer_id GROUP BY c.customer_id HAVING COUNT(o.order_id) > 3; 이 쿼리는 주문 횟수를 기준으로 그룹을 필터링합니다.


시나리오: 사용자가 products 테이블의 일부 제품 이름에 선행 또는 후행 공백이 있다고 보고했습니다. 이 데이터를 어떻게 정리할 수 있나요?

답변:

UPDATE 문에서 TRIM() 함수를 사용합니다. UPDATE products SET product_name = TRIM(product_name); 이 쿼리는 product_name 컬럼의 선행 및 후행 공백을 제거합니다.


시나리오: orders 테이블에서 1 년 이상 된 모든 주문을 archived_orders라는 새 테이블로 이동한 다음, 원본 테이블에서 삭제해야 합니다. 단계를 설명해주세요.

답변:

먼저, CREATE TABLE archived_orders AS SELECT * FROM orders WHERE order_date < date('now', '-1 year');를 실행합니다. 그런 다음, DELETE FROM orders WHERE order_date < date('now', '-1 year');를 실행합니다. 이 단계는 삭제 전에 데이터를 이동하여 데이터 무결성을 보장합니다.


시나리오: 판매된 적이 없는 제품을 찾고 싶습니다. productssales 테이블이 있습니다.

답변:

LEFT JOINWHERE IS NULL 절을 사용합니다. SELECT p.product_name FROM products p LEFT JOIN sales s ON p.product_id = s.product_id WHERE s.product_id IS NULL; 이 쿼리는 해당 판매 기록이 없는 제품을 식별합니다.


시나리오: 지난 1 년 동안 월별 평균 주문 금액을 보여주는 보고서를 생성해야 합니다. orders 테이블에는 order_id, customer_id, order_date, total_amount 컬럼이 있다고 가정합니다.

답변:

그룹화를 위해 STRFTIME을, 평균 계산을 위해 AVG()를 사용합니다. SELECT STRFTIME('%Y-%m', order_date) AS month, AVG(total_amount) AS average_order_value FROM orders WHERE order_date >= date('now', '-1 year') GROUP BY month ORDER BY month; 이 쿼리는 집계를 위해 연 - 월을 추출합니다.


시나리오: users 테이블에 user_id, username, last_login_date 컬럼이 있습니다. 90 일 이상 로그인하지 않은 사용자를 찾아 새 status 컬럼에 계정을 'inactive'로 표시하려면 어떻게 해야 하나요?

답변:

먼저, ALTER TABLE users ADD COLUMN status TEXT DEFAULT 'active';를 실행합니다. 그런 다음, UPDATE users SET status = 'inactive' WHERE last_login_date < date('now', '-90 days');를 실행합니다. 이 단계는 컬럼을 추가하고 로그인 활동을 기반으로 상태를 업데이트합니다.


시나리오: 각 고객별로 판매된 고유 제품 수를 계산해야 합니다. customerssales 테이블이 있습니다.

답변:

COUNT(DISTINCT ...)GROUP BY를 사용합니다. SELECT c.customer_name, COUNT(DISTINCT s.product_id) AS distinct_products_sold FROM customers c JOIN sales s ON c.customer_id = s.customer_id GROUP BY c.customer_id; 이 쿼리는 고객별 고유 제품 수를 제공합니다.


애플리케이션 개발자를 위한 SQLite

모바일 또는 데스크톱 애플리케이션을 위한 임베디드 데이터베이스로 SQLite 를 사용하는 주요 이점은 무엇인가요?

답변:

SQLite 는 서버리스 (serverless), 제로 구성 (zero-configuration), 자체 포함 (self-contained) 방식으로 임베디드 사용에 이상적입니다. 가볍고 빠르며 별도의 서버 프로세스가 필요 없어 애플리케이션 개발자의 배포 및 유지 관리를 단순화합니다.


애플리케이션 내에서 여러 스레드 또는 프로세스가 SQLite 데이터베이스에 동시 액세스하는 경우 어떻게 처리해야 하나요?

답변:

SQLite 는 파일 수준 잠금 (file-level locking) 을 사용하여 동시성을 관리합니다. 쓰기 작업의 경우 일반적으로 전체 데이터베이스 파일을 잠급니다. 읽기 작업은 동시에 진행될 수 있지만, 쓰기 작업은 직렬화됩니다. 개발자는 충돌을 최소화하기 위해 적절한 트랜잭션 관리 및 연결 풀링 (connection pooling) 을 사용해야 합니다.


SQLite 의 WAL(Write-Ahead Logging) 모드 개념과 애플리케이션 성능에 대한 이점을 설명해주세요.

답변:

WAL 모드는 변경 사항을 메인 데이터베이스에 커밋하기 전에 별도의 WAL 파일에 기록하여 쓰기 작업과 읽기 작업을 분리합니다. 이를 통해 쓰기 작업이 진행되는 동안에도 동시 읽기가 가능해져, 특히 읽기 작업이 많은 애플리케이션의 동시성과 성능을 향상시킵니다.


PostgreSQL 또는 MySQL 과 같은 클라이언트 - 서버 데이터베이스 대신 SQLite 를 애플리케이션에 선택하는 경우는 언제인가요?

답변:

애플리케이션이 별도의 서버 프로세스 없이 로컬 임베디드 데이터베이스를 필요로 하는 경우 (예: 모바일 앱, 데스크톱 소프트웨어, IoT 장치) SQLite 를 선택합니다. 단일 사용자 또는 낮은 동시성 시나리오에 적합하며, 단순성과 제로 구성이 중요한 경우에 사용됩니다.


SQLite 기반 애플리케이션에서 데이터베이스 마이그레이션 또는 스키마 업데이트는 어떻게 처리하나요?

답변:

데이터베이스 마이그레이션은 일반적으로 스키마 버저닝 (versioning) 을 통해 처리됩니다. 애플리케이션이 시작될 때 현재 데이터베이스 버전을 확인하고 필요한 ALTER TABLE 문 또는 기타 DDL 명령을 점진적으로 적용하여 스키마를 최신 버전으로 업그레이드합니다.


SQLite 에서 PRAGMA foreign_keys = ON;의 중요성은 무엇이며, 언제 사용해야 하나요?

답변:

PRAGMA foreign_keys = ON;은 외래 키 제약 조건 (foreign key constraint) 적용을 활성화합니다. 기본적으로 SQLite 는 하위 호환성을 위해 외래 키를 강제하지 않습니다. 데이터 무결성을 보장하기 위해 항상 데이터베이스 연결 시작 시점에 사용해야 합니다.


SQLite 에서 대규모 데이터셋을 처리하거나 쿼리 성능을 최적화하는 일반적인 전략을 설명해주세요.

답변:

대규모 데이터셋의 경우, WHERE 절, JOIN 조건 또는 ORDER BY 절에 자주 사용되는 컬럼에 적절한 인덱싱을 사용합니다. EXPLAIN QUERY PLAN을 사용하여 쿼리 성능을 분석하고 병목 현상을 식별합니다. 필요한 경우 보고를 위해 비정규화 (denormalization) 또는 사전 집계 (pre-aggregation) 를 고려합니다.


SQLite 애플리케이션에서 충돌 발생 시 데이터 내구성 (durability) 을 보장하고 데이터 손실을 방지하려면 어떻게 해야 하나요?

답변:

트랜잭션 (BEGIN TRANSACTION; ... COMMIT;) 을 사용하여 원자성 (atomicity) 을 보장합니다. 더 나은 충돌 복구를 위해 WAL 모드를 활성화합니다. PRAGMA synchronous = FULL; (또는 WAL 과 함께 NORMAL) 이 설정되어 있는지 확인하여 트랜잭션이 커밋되기 전에 쓰기가 디스크에 플러시 (flush) 되도록 보장하고, 전원 장애 시 데이터 손실을 방지합니다.


SQLite 에서 준비된 문 (prepared statements) 이란 무엇이며, 애플리케이션 개발에 왜 중요한가요?

답변:

준비된 문 (예: C 언어의 sqlite3_prepare_v2) 은 SQL 쿼리를 미리 컴파일하여 반복 실행 시 성능을 향상시킵니다. 가장 중요한 것은 사용자 입력과 SQL 로직을 분리하여 SQL 인젝션 취약점을 방지하는 안전한 매개변수 바인딩 (parameter binding) 방법을 제공한다는 것입니다.


애플리케이션에서 SQLite 를 사용하여 데이터베이스 연결을 효율적으로 관리하는 방법을 설명해주세요.

답변:

대부분의 애플리케이션에서는 단일 데이터베이스 연결을 열고 여러 작업에 걸쳐 재사용하는 것이 효율적입니다. 멀티스레드 애플리케이션의 경우, 각 스레드는 이상적으로 자체 연결을 가져야 하거나, 연결 풀 (connection pool) 을 사용하여 연결을 안전하게 관리하고 재사용해야 합니다.


SQLite 관리 및 DevOps 고려 사항

프로덕션 환경에서 SQLite 애플리케이션의 데이터베이스 백업은 어떻게 처리하나요?

답변:

SQLite 의 경우 백업은 일반적으로 데이터베이스 파일 (.db) 을 복사하여 수행합니다. 복사 중에 데이터베이스에 활발하게 쓰기가 이루어지지 않도록 하는 것이 중요하며, 데이터 일관성을 유지하기 위해 온라인 백업을 위해서는 sqlite3 .backup 명령 또는 C API sqlite3_backup_init를 사용해야 합니다.


멀티 사용자 동시 액세스 시나리오에서 SQLite 데이터베이스를 배포할 때 주요 고려 사항은 무엇인가요?

답변:

SQLite 는 단일 쓰기, 다중 읽기 동시성을 위해 설계되었습니다. 멀티 사용자 시나리오의 경우, 더 나은 동시성을 위해 WAL(Write-Ahead Logging) 모드를 고려해야 합니다. 여러 프로세스에서 높은 쓰기 동시성이 필요한 경우, 클라이언트 - 서버 데이터베이스가 더 적합할 수 있습니다.


SQLite 의 Write-Ahead Logging(WAL) 모드 목적과 DevOps 에 대한 이점을 설명해주세요.

답변:

WAL 모드는 쓰기 작업과 읽기 작업을 분리하여, 쓰기 작업자가 활성 상태일 때도 읽기 작업자가 계속 진행할 수 있도록 합니다. 이는 동시성을 향상시키고 SQLITE_BUSY 오류의 발생 가능성을 줄입니다. DevOps 측면에서는 동시 액세스 패턴 하에서 데이터베이스를 더 강력하게 만들어 배포를 단순화합니다.


프로덕션 애플리케이션에서 SQLite 데이터베이스의 성능 및 상태를 어떻게 모니터링하나요?

답변:

SQLite 모니터링은 일반적으로 쿼리 실행 시간 및 SQLITE_BUSY 오류와 같은 애플리케이션 수준 메트릭을 추적하는 것을 포함합니다. sqlite_analyzer와 같은 도구는 스키마 및 인덱스 분석에 도움이 될 수 있습니다. 임베디드 시스템의 경우, 파일 시스템 I/O 및 디스크 공간 모니터링도 중요합니다.


SQLite 기반 애플리케이션에서 스키마 마이그레이션 및 버전 관리를 위해 어떤 전략을 사용하나요?

답변:

스키마 마이그레이션은 일반적으로 ALTER TABLE 문을 적용하는 마이그레이션 스크립트를 사용하여 처리됩니다. Alembic (Python) 또는 Flyway (Java) 와 같은 도구는 버전 관리를 관리하고 마이그레이션을 점진적으로 적용할 수 있습니다. 마이그레이션을 철저히 테스트하고 롤백 전략을 갖는 것이 중요합니다.


SQLite 파일의 데이터베이스 손상을 어떻게 처리하나요?

답변:

데이터베이스 손상은 때때로 PRAGMA integrity_check를 사용하여 수정할 수 있습니다. 이것이 실패하면, 주요 복구 방법은 가장 최근의 유효한 백업에서 복원하는 것입니다. 중요한 데이터의 경우, 가능한 경우 부분적으로 손상된 파일에서 데이터를 추출하기 위해 sqlite3 .dump를 사용하는 것을 고려합니다.


새로운 프로젝트에 대해 PostgreSQL 또는 MySQL 과 같은 클라이언트 - 서버 데이터베이스 대신 SQLite 를 선택하는 경우는 언제인가요?

답변:

SQLite 는 완전한 클라이언트 - 서버 설정이 과도한 임베디드 시스템, 모바일 애플리케이션, 데스크톱 애플리케이션 및 중소 규모 웹 애플리케이션에 이상적입니다. 제로 구성, 서버리스 특성, 쉬운 배포 및 유지 관리 때문에 선택됩니다.


컨테이너화 (예: Docker) 에 대한 SQLite 의 파일 기반 특성의 의미는 무엇인가요?

답변:

컨테이너화할 때, SQLite 데이터베이스 파일은 컨테이너 재시작 및 업데이트에 걸쳐 데이터 지속성을 보장하기 위해 Docker 볼륨에 저장해야 합니다. 볼륨이 없으면 컨테이너가 제거될 때 데이터가 손실됩니다. 이는 백업을 더 쉽게 만드는 데도 도움이 됩니다.


SQLite 트랜잭션에서 데이터 무결성 및 원자성을 어떻게 보장하나요?

답변:

SQLite 는 트랜잭션 메커니즘을 통해 ACID 속성을 보장합니다. BEGIN TRANSACTION; ... COMMIT; 블록 내의 모든 변경 사항은 원자적입니다. 애플리케이션이 충돌하거나 ROLLBACK;이 호출되면 모든 변경 사항이 취소되어 데이터 무결성이 유지됩니다.


SQLite 관리에서 VACUUM의 중요성은 무엇인가요?

답변:

VACUUM은 전체 데이터베이스 파일을 재구축하여 압축하고 삭제된 데이터로 인해 남은 사용되지 않는 공간을 회수합니다. 이는 파일 크기를 줄이고 성능을 향상시킬 수 있으며, 특히 많은 삭제 또는 업데이트 후에 효과적입니다. 데이터베이스에 대한 독점적인 액세스가 필요합니다.


실용적인 SQLite 쿼리 및 데이터 조작

'products' 테이블의 'category'라는 이름의 컬럼에서 모든 고유 값을 검색하는 방법은 무엇인가요?

답변:

SELECT와 함께 DISTINCT 키워드를 사용할 수 있습니다. 예시: SELECT DISTINCT category FROM products; 이 쿼리는 테이블에 존재하는 각 고유 카테고리를 반환합니다.


SQLite 에서 DELETE FROM tableTRUNCATE TABLE table의 차이점을 설명해주세요.

답변:

SQLite 에는 TRUNCATE TABLE 명령이 없습니다. DELETE FROM table은 모든 행을 제거하지만 롤백 (rollback) 이 가능하며 삭제 트리거 (delete trigger) 를 발생시킵니다. TRUNCATE와 유사한 성능을 얻으려면 테이블을 삭제하고 다시 생성하거나 DELETE FROM table; VACUUM;을 사용할 수 있습니다.


'items'라는 기존 테이블에 REAL 데이터 타입과 기본값 0.0 을 가진 'price'라는 새 컬럼을 추가하는 방법은 무엇인가요?

답변:

ALTER TABLE ADD COLUMN 문을 사용할 수 있습니다. 예시: ALTER TABLE items ADD COLUMN price REAL DEFAULT 0.0; 이 쿼리는 지정된 데이터 타입과 기본값을 가진 컬럼을 추가합니다.


'orders' 테이블에서 '2023-01-01' 이전에 주문된 모든 주문의 'status'를 'completed'로 업데이트하는 쿼리를 작성해주세요.

답변:

WHERE 절과 함께 UPDATE 문을 사용합니다. 예시: UPDATE orders SET status = 'completed' WHERE order_date < '2023-01-01'; 이 쿼리는 일치하는 레코드만 업데이트하도록 보장합니다.


'users'라는 테이블에서 'is_active' 컬럼이 true 인 행의 수를 세는 방법은 무엇인가요?

답변:

WHERE 절과 함께 COUNT() 집계 함수를 사용할 수 있습니다. 예시: SELECT COUNT(*) FROM users WHERE is_active = 1; (부울 컬럼의 경우 1 이 true 를 나타낸다고 가정).


GROUP BY 절의 목적은 무엇이며, 예시를 들어 설명해주세요.

답변:

GROUP BY 절은 지정된 컬럼에서 동일한 값을 가진 행들을 요약 행으로 그룹화합니다. 종종 집계 함수와 함께 사용됩니다. 예시: 카테고리별 제품 수를 세기 위한 SELECT category, COUNT(*) FROM products GROUP BY category;


'products' 테이블에서 가격을 기준으로 내림차순으로 정렬했을 때 가장 비싼 상위 5 개 제품을 검색하는 방법은 무엇인가요?

답변:

ORDER BYDESC, LIMIT를 함께 사용할 수 있습니다. 예시: SELECT product_name, price FROM products ORDER BY price DESC LIMIT 5; 이 쿼리는 상위 N 개의 레코드를 효율적으로 가져옵니다.


SQLite 에서 JOIN 절의 사용법을 설명하고, INNER JOINLEFT JOIN의 차이점을 설명해주세요.

답변:

JOIN은 관련 컬럼을 기반으로 두 개 이상의 테이블에서 행을 결합합니다. INNER JOIN은 두 테이블 모두에서 일치하는 행만 반환합니다. LEFT JOIN (또는 LEFT OUTER JOIN) 은 왼쪽 테이블의 모든 행과 오른쪽 테이블의 일치하는 행을 반환하며, 일치하지 않는 경우 NULL 값을 사용합니다.


'logs'라는 테이블에 'event_time'과 'message' 컬럼을 사용하여 단일 SQL 문으로 여러 행을 삽입하는 방법은 무엇인가요?

답변:

여러 값 세트와 함께 INSERT INTO 문을 사용할 수 있습니다. 예시: INSERT INTO logs (event_time, message) VALUES ('2023-10-26 10:00:00', 'Login success'), ('2023-10-26 10:05:00', 'Page view');


SQLite 에서 VIEW란 무엇이며, 언제 사용해야 하나요?

답변:

VIEW는 SQL 쿼리 결과 집합을 기반으로 하는 가상 테이블입니다. 자체적으로 데이터를 저장하지는 않지만 복잡한 쿼리에 액세스하는 간소화된 방법을 제공합니다. 보안 (컬럼 액세스 제한), 복잡한 쿼리 단순화 또는 애플리케이션 간 데이터 일관성 보장을 위해 사용합니다.


SQLite 문제 해결 및 디버깅

SQLite 에서 'database is locked' 오류의 일반적인 원인과 해결 방법은 무엇인가요?

답변:

이 오류는 일반적으로 여러 연결이 동시에 데이터베이스에 쓰려고 하거나, 장기 실행 트랜잭션이 잠금을 유지할 때 발생합니다. 해결하려면 적절한 트랜잭션 관리 (COMMIT/ROLLBACK) 를 보장하고, 동시 쓰기를 줄이거나, 더 나은 동시성을 위해 WAL 모드를 사용해야 합니다.


'malformed database schema' 또는 'database disk image is malformed' 오류를 어떻게 디버깅하나요?

답변:

이러한 오류는 데이터베이스 손상을 나타냅니다. 먼저 PRAGMA integrity_check;를 사용하여 문제를 식별합니다. 손상된 경우 백업에서 복원합니다. 백업이 없는 경우, sqlite3 .dump > backup.sql을 사용하여 데이터를 추출한 다음 데이터베이스를 다시 생성하고 가져옵니다.


쿼리가 매우 느리게 실행됩니다. 성능 병목 현상을 진단하기 위해 어떤 단계를 거치나요?

답변:

먼저 EXPLAIN QUERY PLAN을 사용하여 쿼리의 실행 경로를 분석하고 누락된 인덱스나 전체 테이블 스캔을 식별합니다. 그런 다음 WHERE, JOIN, ORDER BY 절에 사용된 컬럼에 적절한 인덱스가 있는지 확인합니다. 데이터 분포를 분석하고 쿼리 구조를 최적화하는 것을 고려합니다.


애플리케이션에서 사용 중인 SQLite 데이터베이스 버전과 SQLite 라이브러리 버전을 확인하는 방법은 무엇인가요?

답변:

SQLite 내부에서는 SELECT sqlite_version();을 사용하여 데이터베이스 엔진 버전을 얻습니다. 라이브러리의 경우, 대부분의 프로그래밍 언어 바인딩은 연결된 라이브러리 버전을 보고하는 함수 (예: Python 의 sqlite3.sqlite_version) 를 제공합니다.


디버깅을 위해 SQLite 의 PRAGMA 문을 활성화하고 해석하는 방법을 설명해주세요.

답변:

PRAGMA 문은 SQLite 를 구성하거나 내부 상태를 쿼리합니다. 디버깅을 위해 PRAGMA integrity_check;는 데이터베이스 일관성을 확인하고, PRAGMA foreign_key_check;는 외래 키 제약 조건을 확인하며, PRAGMA journal_mode;는 동시성 및 복구에 영향을 미치는 저널링 모드를 표시합니다.


Write-Ahead Logging(WAL) 모드란 무엇이며, SQLite 에서 동시성 및 복구에 어떻게 도움이 되나요?

답변:

WAL 모드는 쓰기 작업과 읽기 작업을 분리하여, 쓰기 작업자가 별도의 로그 파일에 추가하는 동안 읽기 작업자가 계속 진행할 수 있도록 합니다. 이는 'database is locked' 오류를 줄여 동시성을 향상시키고, 일관된 메인 데이터베이스 파일을 유지하여 충돌 복구를 강화합니다.


'no such table' 또는 'no such column' 오류가 발생합니다. 일반적인 이유는 무엇이며 어떻게 수정하나요?

답변:

이러한 오류는 일반적으로 테이블/컬럼 이름에 오타가 있거나, 대소문자가 잘못되었거나 (대소문자 구분 시), 테이블/컬럼이 단순히 존재하지 않음을 의미합니다. SQLite CLI 의 .schema를 사용하거나 sqlite_master 테이블을 쿼리하여 스키마를 확인합니다. 액세스 중인 데이터베이스 파일이 올바른 파일인지 확인합니다.


애플리케이션이 충돌하여 SQLite 데이터베이스가 일관되지 않은 상태로 남는 상황을 어떻게 처리하나요?

답변:

SQLite 는 원자성과 내구성을 위해 설계되었습니다. 트랜잭션 중에 충돌이 발생하면, SQLite 의 저널링 메커니즘 (롤백 저널 또는 WAL) 은 다음 연결 시 불완전한 트랜잭션을 자동으로 롤백하여 데이터베이스를 마지막 일관된 상태로 복원합니다.


SQLite 데이터베이스 파일을 직접 검사하기 위해 어떤 도구나 기법을 사용하나요?

답변:

sqlite3 명령줄 인터페이스가 직접 검사를 위한 주요 도구입니다. .tables, .schema, SELECT 쿼리 및 .dump를 사용할 수 있습니다. GUI 검사를 위해서는 DB Browser for SQLite 또는 SQLiteStudio 와 같은 도구가 훌륭합니다.


특정 인덱스가 쿼리에서 사용되고 있는지 어떻게 식별할 수 있나요?

답변:

SELECT 문 앞에 EXPLAIN QUERY PLAN을 사용합니다. 출력은 테이블 스캔, 정렬 또는 필터링에 사용되는 인덱스 (있는 경우) 를 포함한 쿼리 계획을 보여줍니다. 계획에서 USING INDEX를 찾습니다.


SQLite 성능 튜닝 및 모범 사례

SQLite 에서 인덱스를 사용하는 주된 이점은 무엇이며, 언제 추가를 고려해야 하나요?

답변:

인덱스는 전체 테이블을 스캔하지 않고도 행을 빠르게 찾을 수 있도록 하여 데이터 검색 작업 (SELECT 쿼리) 을 크게 가속화합니다. WHERE 절, JOIN 조건, ORDER BY 절 또는 GROUP BY 절에 자주 사용되는 컬럼에 인덱스 추가를 고려해야 합니다.


SQLite 에서 VACUUM 의 개념과 성능에 미치는 영향에 대해 설명해주세요.

답변:

VACUUM 은 전체 데이터베이스 파일을 재구축하여 삭제된 데이터로 인해 남은 사용되지 않는 공간을 회수하고 데이터베이스를 조각 모음합니다. 파일 크기를 줄이고 데이터를 더 연속적으로 만들어 읽기 성능을 향상시킬 수 있지만, 시간이 많이 소요되는 작업이며 데이터베이스를 잠그므로 유지 관리 시간에 실행해야 합니다.


PRAGMA 는 SQLite 성능을 어떻게 최적화하며, 튜닝에 유용한 PRAGMA 명령어를 하나 명명해주세요.

답변:

PRAGMA 명령어를 사용하면 SQLite 의 내부 구성을 쿼리하고 수정할 수 있습니다. 저널링, 캐싱 및 무결성 검사와 같은 다양한 측면을 최적화하는 데 사용할 수 있습니다. 유용한 명령어는 PRAGMA journal_mode = WAL;로, 더 나은 동시성과 충돌 복구를 위해 저널링 모드를 변경합니다.


Write-Ahead Logging(WAL) 모드란 무엇이며, 성능 면에서 왜 전통적인 롤백 저널 모드보다 선호되는 경우가 많나요?

답변:

WAL 모드는 변경 사항을 메인 데이터베이스 파일에 적용하기 전에 별도의 WAL 파일에 기록합니다. 이를 통해 쓰기 작업자가 활성 상태일 때도 읽기 작업자가 데이터베이스에 계속 액세스할 수 있어, 쓰기 작업 중에 전체 데이터베이스를 잠그는 전통적인 롤백 저널에 비해 동시성이 크게 향상되고 쓰기 충돌이 줄어듭니다.


대량 삽입을 수행할 때 성능 향상을 위한 일반적인 모범 사례는 무엇인가요?

답변:

대량 삽입의 경우, 여러 INSERT 문을 단일 트랜잭션으로 묶습니다. 이렇게 하면 각 개별 문을 커밋하는 오버헤드가 줄어듭니다. SQLite 는 여러 번의 커밋 작업 대신 한 번의 트랜잭션 커밋 작업만 수행하면 되기 때문입니다. 예시: BEGIN TRANSACTION; INSERT ...; INSERT ...; COMMIT;


SQLite 에서 ANALYZE의 목적과 쿼리 최적화에서의 역할에 대해 설명해주세요.

답변:

ANALYZE는 테이블 및 인덱스의 데이터 분포에 대한 통계를 수집합니다. SQLite 쿼리 최적화 프로그램은 이러한 통계를 사용하여 가장 효율적인 쿼리 계획 (예: 인덱스 사용 여부 또는 전체 테이블 스캔 수행 여부) 을 선택하여 쿼리 실행 속도를 높입니다.


SELECT *를 사용할 때 성능에 미치는 영향은 무엇이며, 더 나은 대안은 무엇인가요?

답변:

SELECT *는 테이블의 모든 컬럼을 검색하는데, 몇 개의 컬럼만 필요한 경우에는 비효율적일 수 있습니다. 네트워크 트래픽, 메모리 사용량 및 디스크 I/O 를 증가시킵니다. 더 나은 대안은 필요한 컬럼만 명시적으로 나열하는 것입니다. 예시: SELECT id, name FROM users;


EXPLAIN QUERY PLAN은 성능 병목 현상을 식별하는 데 어떻게 도움이 되나요?

답변:

EXPLAIN QUERY PLAN은 SQLite 최적화 프로그램이 주어진 SQL 쿼리에 사용할 단계별 실행 계획을 보여줍니다. 계획을 분석함으로써 전체 테이블 스캔, 불필요한 임시 테이블 또는 최적이 아닌 인덱스 사용과 같은 비효율적인 작업을 식별하여 최적화 노력을 안내할 수 있습니다.


성능을 위해 PRAGMA synchronous = OFF;를 사용할 때의 절충점에 대해 논의해주세요.

답변:

PRAGMA synchronous = OFF;는 데이터의 디스크 동기화를 비활성화하여 쓰기 작업을 훨씬 빠르게 만듭니다. 그러나 시스템 충돌 또는 전원 장애 시 데이터베이스 손상 및 데이터 손실 위험을 크게 증가시킵니다. 중요하지 않거나 임시적이거나 읽기 전용 시나리오에서만 사용해야 합니다.


정규화 규칙을 위반함에도 불구하고, 언제 비정규화 (denormalization) 를 SQLite 의 성능 최적화로 고려할 수 있나요?

답변:

비정규화는 빈번한 쿼리에 필요한 JOIN 작업 수를 줄이기 위해 의도적으로 데이터를 복제하거나 테이블을 결합하는 것을 포함합니다. 데이터 중복성과 업데이트 복잡성이 증가하지만, 특히 읽기 작업이 많은 애플리케이션에서 비용이 많이 드는 조인을 피함으로써 특정 중요 쿼리의 읽기 성능을 크게 향상시킬 수 있습니다.


요약

인터뷰를 위해 SQLite 를 마스터하는 것은 여러분의 헌신과 데이터베이스 기본 원리에 대한 이해를 증명하는 것입니다. 일반적인 질문에 대한 철저한 준비와 실제 시나리오에 대한 깊이 있는 탐구를 통해, 여러분은 기술적 숙련도뿐만 아니라 견고하고 효율적인 애플리케이션을 구축하려는 의지를 보여줍니다. 이러한 준비는 여러분의 지식을 명확하고 효과적으로 설명할 수 있는 자신감을 갖추게 해주는 귀중한 것입니다.

기술 분야에서의 학습 여정은 끊임없다는 것을 기억하십시오. 성공적인 인터뷰 후에도 새로운 기능, 모범 사례 및 진화하는 데이터 관리 환경을 계속 탐색하십시오. 도전을 성장의 기회로 받아들이고, 호기심이 더 깊은 통찰력으로 여러분을 이끌도록 하십시오. 여러분의 꾸준한 학습은 의심할 여지 없이 소프트웨어 개발에서 보람 있는 경력을 쌓는 길을 열어줄 것입니다.