도입 문구
SQLite의 Full Text Search(FTS) 기능을 활용해 C++로 검색 엔진을 구현하는 방법에 대해 다룹니다. FTS는 텍스트 데이터를 빠르게 검색할 수 있도록 지원하는 기능으로, 대용량 데이터베이스에서의 효율적인 텍스트 검색이 가능합니다. 본 기사에서는 C++ 환경에서 SQLite의 FTS를 설정하고 활용하는 방법을 단계별로 안내합니다.
SQLite FTS란 무엇인가?
SQLite의 Full Text Search(FTS)는 대용량 텍스트 데이터에서 빠르고 효율적인 검색을 지원하는 기능입니다. SQLite는 내장형 데이터베이스로 가벼운 프로젝트에 적합하지만, 텍스트 검색에 있어 성능을 크게 향상시킬 수 있는 FTS 기능을 제공합니다.
SQLite FTS는 데이터베이스 내에 텍스트 데이터를 인덱싱하여, 특정 단어나 구문을 신속하게 찾을 수 있도록 합니다. 이 기능은 주로 문서, 블로그, 이메일, 뉴스 기사 등에서 검색 엔진을 구현할 때 유용하게 사용됩니다. FTS는 기본적인 LIKE 검색보다 훨씬 효율적이며, 큰 텍스트 파일이나 데이터셋을 다룰 때 뛰어난 성능을 발휘합니다.
FTS를 사용해야 하는 이유
FTS를 활용하면 대규모 데이터베이스에서 텍스트 검색 성능을 크게 향상시킬 수 있습니다. 일반적인 SQL 쿼리로 텍스트 검색을 수행할 경우, 각 레코드를 일일이 검사해야 하므로 시간이 오래 걸리고 성능 저하가 발생할 수 있습니다. 하지만 FTS는 텍스트 데이터를 인덱싱하여 이러한 문제를 해결합니다.
성능 향상
FTS는 데이터를 인덱스화하여 검색 속도를 비약적으로 향상시킵니다. 이를 통해 수백만 개의 레코드를 포함하는 데이터베이스에서도 검색 속도가 빠르고 효율적으로 처리됩니다.
정확한 검색 결과
FTS는 단어의 변형(어미 변화, 대소문자 구분 등)을 처리하고, 다수의 키워드가 포함된 복잡한 쿼리도 정확히 처리할 수 있습니다. 이로 인해 사용자는 정확한 검색 결과를 더 빠르게 얻을 수 있습니다.
메모리 효율성
SQLite는 서버 기반 데이터베이스와 달리 임베디드 시스템에서 실행되므로, 메모리와 디스크 공간이 제한적일 수 있습니다. FTS는 이러한 환경에서 효율적으로 작동하며, 데이터베이스가 크더라도 리소스를 최소화하면서도 빠른 검색을 제공합니다.
C++에서 SQLite 라이브러리 설정하기
C++에서 SQLite의 FTS 기능을 사용하려면 먼저 SQLite 라이브러리를 프로젝트에 포함시켜야 합니다. 이 과정은 다음과 같은 단계로 이루어집니다.
SQLite 라이브러리 다운로드
SQLite는 공식 웹사이트에서 라이브러리 파일을 다운로드할 수 있습니다. 다운로드 페이지에서 운영 체제에 맞는 파일을 선택하여 저장합니다. SQLite는 C/C++로 작성되어 있기 때문에, C++ 프로젝트에서도 직접 사용할 수 있습니다.
라이브러리 링크 설정
SQLite를 C++ 프로젝트에서 사용하려면, SQLite 헤더 파일을 포함하고, 라이브러리 파일을 링커에 추가해야 합니다. 일반적으로 다음과 같은 절차를 따릅니다:
- SQLite의
sqlite3.h
헤더 파일을 프로젝트에 포함시킵니다. - SQLite의
sqlite3.lib
또는sqlite3.a
(정적 라이브러리)를 링커에 추가합니다. - C++ 코드에서
#include <sqlite3.h>
를 추가하여 SQLite 기능을 사용할 수 있습니다.
FTS 확장 사용하기
SQLite의 FTS 기능은 기본적으로 포함되어 있지만, 특정 FTS 확장을 활성화하려면 SQLite를 컴파일할 때 FTS 관련 옵션을 사용해야 할 수 있습니다. 예를 들어, SQLite를 컴파일할 때 -DSQLITE_ENABLE_FTS5
플래그를 지정하여 FTS5 기능을 활성화할 수 있습니다.
CMake나 다른 빌드 시스템을 사용할 경우, 해당 시스템에서 SQLite 라이브러리를 어떻게 링크할지 지정해야 합니다.
FTS 테이블 생성과 설정
SQLite에서 FTS(Full Text Search) 테이블을 생성하는 과정은 일반적인 테이블 생성과 유사하지만, FTS 전용 테이블을 사용해야 합니다. FTS는 텍스트 검색을 최적화하기 위해 특수한 인덱스를 생성하며, 이를 통해 빠르고 정확한 검색을 구현할 수 있습니다.
FTS 테이블 생성
FTS 테이블을 생성하는 SQL 문법은 일반적인 CREATE TABLE
문과 비슷하지만, FTS 테이블을 위한 특정 키워드를 사용합니다. 예를 들어, FTS5 확장을 사용하여 텍스트를 검색할 수 있는 테이블을 생성하려면 다음과 같이 작성합니다:
const char* createTableSQL = "CREATE VIRTUAL TABLE documents USING fts5(title, content);";
이 예시에서는 documents
라는 이름의 FTS 테이블을 생성하며, title
과 content
라는 두 개의 열을 검색 대상으로 설정합니다. 이 테이블은 검색 쿼리가 빠르게 처리되도록 텍스트 인덱스를 자동으로 생성합니다.
FTS 테이블에 데이터 삽입
FTS 테이블에 데이터를 삽입할 때는 일반적인 INSERT
문을 사용합니다. 예를 들어, documents
테이블에 문서 제목과 내용을 삽입하려면 다음과 같이 작성합니다:
const char* insertDataSQL = "INSERT INTO documents (title, content) VALUES (?, ?);";
sqlite3_stmt* stmt;
sqlite3_prepare_v2(db, insertDataSQL, -1, &stmt, 0);
sqlite3_bind_text(stmt, 1, "SQLite FTS Tutorial", -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, "This is an example of using Full Text Search in SQLite.", -1, SQLITE_STATIC);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
이 코드는 title
과 content
에 데이터를 삽입하는 예시로, sqlite3_bind_text
를 사용해 문자열을 바인딩합니다. FTS 테이블에 데이터를 삽입하면, SQLite가 해당 데이터를 인덱싱하여 텍스트 검색에 적합한 형식으로 저장합니다.
FTS 인덱스 활용
FTS 테이블을 사용하면, 텍스트 검색 시 자동으로 인덱스를 활용하여 검색 속도를 높입니다. 예를 들어, documents
테이블에서 제목이나 내용에 “SQLite”라는 단어가 포함된 행을 찾으려면 다음과 같은 쿼리를 사용할 수 있습니다:
const char* searchSQL = "SELECT title, content FROM documents WHERE content MATCH ?;";
sqlite3_stmt* stmt;
sqlite3_prepare_v2(db, searchSQL, -1, &stmt, 0);
sqlite3_bind_text(stmt, 1, "SQLite", -1, SQLITE_STATIC);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
MATCH
연산자를 사용하면 FTS 인덱스를 기반으로 빠르고 효율적인 검색을 수행할 수 있습니다.
검색 기능 구현 예시
SQLite의 FTS 기능을 사용하여 C++에서 실제 검색 기능을 구현하는 방법을 구체적인 예시로 살펴보겠습니다. 이 예시에서는 documents
테이블에 저장된 문서 제목과 내용에서 키워드를 검색하는 방법을 다룹니다.
기본적인 텍스트 검색
FTS 테이블을 생성하고 데이터를 삽입한 후, 사용자가 입력한 키워드를 바탕으로 제목이나 내용에 포함된 문서를 검색하는 기능을 구현할 수 있습니다. 예를 들어, documents
테이블에서 “SQLite”라는 키워드가 포함된 문서를 검색하는 코드를 작성해 보겠습니다:
const char* searchSQL = "SELECT title, content FROM documents WHERE content MATCH ?;";
sqlite3_stmt* stmt;
sqlite3_prepare_v2(db, searchSQL, -1, &stmt, 0);
// 사용자로부터 검색어 입력 받기
std::string keyword = "SQLite"; // 예시 키워드
sqlite3_bind_text(stmt, 1, keyword.c_str(), -1, SQLITE_STATIC);
// 검색 결과 출력
while (sqlite3_step(stmt) == SQLITE_ROW) {
const char* title = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
const char* content = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
std::cout << "Title: " << title << "\n";
std::cout << "Content: " << content << "\n\n";
}
sqlite3_finalize(stmt);
위의 코드에서는 MATCH
연산자를 사용해 FTS 인덱스를 기반으로 텍스트 검색을 수행합니다. 사용자가 입력한 keyword
를 sqlite3_bind_text
로 바인딩하고, sqlite3_step
을 통해 검색 결과를 한 행씩 출력합니다. 검색된 문서의 제목과 내용을 콘솔에 출력하는 방식입니다.
부분 일치 검색
FTS의 가장 큰 장점은 부분 일치 검색이 가능하다는 점입니다. 예를 들어, 사용자가 “SQLite”라는 키워드로 검색하면, “SQLite FTS Tutorial” 또는 “Introduction to SQLite FTS”와 같은 여러 문서가 검색될 수 있습니다. FTS는 키워드가 포함된 모든 텍스트를 검색 결과로 반환하며, 이를 통해 보다 넓은 범위의 검색 결과를 얻을 수 있습니다.
구체적인 예시: 사용자 검색 인터페이스
이 예시에서는 사용자로부터 입력을 받고, 그에 맞는 검색 결과를 출력하는 간단한 콘솔 프로그램을 만들어 보겠습니다. 사용자가 입력한 키워드를 통해 documents
테이블을 검색하는 구조입니다:
std::string keyword;
std::cout << "Enter search keyword: ";
std::getline(std::cin, keyword);
const char* searchSQL = "SELECT title, content FROM documents WHERE content MATCH ?;";
sqlite3_stmt* stmt;
sqlite3_prepare_v2(db, searchSQL, -1, &stmt, 0);
sqlite3_bind_text(stmt, 1, keyword.c_str(), -1, SQLITE_STATIC);
while (sqlite3_step(stmt) == SQLITE_ROW) {
const char* title = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
const char* content = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
std::cout << "Title: " << title << "\n";
std::cout << "Content: " << content << "\n\n";
}
sqlite3_finalize(stmt);
이 코드는 사용자로부터 키워드를 입력받고, 해당 키워드를 MATCH
연산자와 함께 검색하여 결과를 출력하는 기능을 수행합니다. 사용자는 원하는 키워드를 입력하고, FTS 인덱스를 활용해 빠르고 정확한 검색을 할 수 있습니다.
성능 최적화 기법
SQLite의 FTS 기능을 사용할 때, 데이터가 많아질수록 성능 최적화가 중요합니다. 대용량 데이터베이스에서 효율적인 검색을 유지하려면 몇 가지 최적화 기법을 고려해야 합니다. 다음은 SQLite FTS를 사용할 때 성능을 최적화할 수 있는 주요 방법들입니다.
인덱스 최적화
FTS는 기본적으로 인덱스를 생성하여 빠른 검색을 지원하지만, 데이터가 많아질수록 인덱스 크기가 커지며 검색 성능이 저하될 수 있습니다. 이를 해결하기 위해 다음과 같은 방법을 사용할 수 있습니다:
- 부분 인덱싱: 특정 열만 인덱싱하여 검색 성능을 높일 수 있습니다. 예를 들어,
title
열만 인덱싱하고,content
열은 인덱싱하지 않으면, 검색 범위를 좁혀 성능을 향상시킬 수 있습니다. - FTS5 사용: FTS5는 FTS3 및 FTS4에 비해 성능이 향상된 버전으로, 특히 더 빠르고 효율적인 인덱싱을 제공합니다. FTS5는 토큰화 및 검색 최적화가 개선되어 대규모 데이터베이스에서 성능을 더욱 높여줍니다. FTS5를 사용하려면 SQLite를 컴파일할 때
-DSQLITE_ENABLE_FTS5
플래그를 활성화해야 합니다.
검색 범위 제한
대규모 데이터베이스에서 모든 데이터를 검색하는 대신, 검색 범위를 제한하여 성능을 향상시킬 수 있습니다. 예를 들어, 검색어가 포함된 특정 범위나 날짜, 범주 등을 추가하여 검색 범위를 줄이면 더 빠른 결과를 얻을 수 있습니다. 예시:
const char* searchSQL = "SELECT title, content FROM documents WHERE content MATCH ? AND date BETWEEN ? AND ?;";
이렇게 날짜나 특정 카테고리로 검색 범위를 좁히면 검색 속도가 개선됩니다.
트랜잭션 사용
SQLite에서 대량의 데이터를 삽입하거나 수정할 때는 트랜잭션을 활용하는 것이 성능을 크게 향상시킬 수 있습니다. 여러 개의 INSERT
문을 개별적으로 실행하는 대신, 트랜잭션으로 묶어서 실행하면 디스크 I/O 작업을 최소화할 수 있습니다. 예시:
sqlite3_exec(db, "BEGIN TRANSACTION;", 0, 0, 0);
for (int i = 0; i < numRows; ++i) {
// 데이터 삽입 코드
sqlite3_exec(db, insertSQL, 0, 0, 0);
}
sqlite3_exec(db, "COMMIT;", 0, 0, 0);
트랜잭션을 사용하면 데이터베이스에 대한 액세스를 효율적으로 관리할 수 있고, 삽입 성능을 크게 개선할 수 있습니다.
저장소 최적화
SQLite는 데이터가 커질수록 성능이 떨어질 수 있는데, 이를 해결하기 위해 VACUUM
명령을 사용하여 데이터베이스 파일의 크기를 최적화할 수 있습니다. VACUUM
명령은 사용되지 않는 공간을 정리하여 디스크 공간을 재구성합니다. 예시:
sqlite3_exec(db, "VACUUM;", 0, 0, 0);
정기적으로 VACUUM
을 실행하면 데이터베이스 파일의 크기를 줄이고, 읽기/쓰기 성능을 유지할 수 있습니다.
병렬 처리 및 캐싱 활용
대용량 데이터를 다룰 때는 병렬 처리나 캐싱을 사용하여 검색 성능을 더욱 개선할 수 있습니다. 예를 들어, 검색 결과를 메모리에 캐시하고, 동일한 검색어에 대해 반복적인 디스크 I/O를 줄일 수 있습니다. 또한, 멀티스레딩을 활용하여 검색 작업을 병렬로 처리하면, 여러 CPU 코어를 효과적으로 사용할 수 있습니다.
이와 같은 최적화 기법을 적용하면, 대규모 데이터베이스에서도 SQLite의 FTS 기능을 빠르고 효율적으로 사용할 수 있습니다.
고급 검색 기능 및 확장
SQLite의 FTS(Full Text Search) 기능은 기본적인 텍스트 검색 외에도 다양한 고급 검색 기능을 제공합니다. 이를 활용하면 더욱 정교한 검색을 구현할 수 있습니다. 이 섹션에서는 고급 검색 기능과 그 확장 방법을 다룹니다.
불완전한 일치 검색 (Fuzzy Search)
FTS는 기본적으로 완전 일치 검색을 지원하지만, 유사한 단어나 철자가 비슷한 단어를 검색할 때도 유용한 “Fuzzy Search” 기능을 구현할 수 있습니다. FTS5에서는 NEAR
연산자를 사용하여 인접한 단어를 검색하거나, 특정 거리를 두고 검색하는 방식으로 근사치 검색을 할 수 있습니다.
예시: “SQLite”와 “SQL”이 서로 가까운 단어로 간주되는 경우, NEAR
연산자를 사용하여 두 단어가 가까운 문서들을 찾을 수 있습니다.
const char* searchSQL = "SELECT title, content FROM documents WHERE content MATCH 'SQLite NEAR SQL';";
이 방식은 특히 철자 오류나 비슷한 의미의 단어를 포함하는 데이터를 찾을 때 유용합니다.
우선순위 검색 (Ranking)
SQLite의 FTS5는 검색 결과에 순위를 매겨 중요도가 높은 문서부터 표시하는 기능을 제공합니다. FTS에서 순위는 기본적으로 각 문서의 관련성 점수로 계산됩니다. 사용자가 검색한 키워드와 얼마나 관련이 있는지를 바탕으로 순위를 매깁니다.
const char* searchSQL = "SELECT title, content, rank FROM documents WHERE content MATCH ? ORDER BY rank DESC;";
위 예시에서는 rank
를 계산하여 가장 관련성 높은 결과부터 출력하는 쿼리입니다. rank
값은 자동으로 계산되며, 검색어와의 일치 정도에 따라 점수가 부여됩니다. 이 기능은 검색 결과의 품질을 높이고, 중요한 문서를 우선적으로 보여주는 데 유용합니다.
정규 표현식 (Regular Expressions) 활용
SQLite는 FTS 기능을 사용할 때 정규 표현식을 통한 검색을 지원하지 않지만, FTS5에서는 REGEXP
연산자를 사용하여 정규 표현식 검색을 확장할 수 있습니다. 이를 통해 더욱 복잡한 패턴 기반 검색을 할 수 있습니다.
const char* searchSQL = "SELECT title, content FROM documents WHERE content REGEXP ?;";
정규 표현식을 사용하면 특정 패턴에 맞는 텍스트를 검색하는 데 유용하며, 예를 들어 이메일 주소나 날짜 형식 등 정해진 형식을 따르는 텍스트를 검색할 때 유용합니다.
검색어 자동 완성 (Autocomplete)
검색어 자동 완성 기능은 사용자 경험을 향상시키는 중요한 요소입니다. FTS의 특성상, 검색어 자동 완성은 사용자가 입력한 텍스트와 유사한 단어나 문장을 실시간으로 검색하는 방식으로 구현할 수 있습니다. 예를 들어, 사용자가 “SQL”을 입력하면, “SQLite”, “SQL Server”, “SQLAlchemy”와 같은 관련된 단어들이 자동으로 추천될 수 있습니다.
const char* searchSQL = "SELECT title FROM documents WHERE title MATCH ?;";
이 방식은 검색어를 입력할 때마다 자동으로 결과를 보여주며, 실시간으로 사용자가 선택할 수 있는 항목을 제공합니다. 이를 통해 더욱 직관적이고 빠른 검색 경험을 제공할 수 있습니다.
동적 텍스트 검색 (Dynamic Text Search)
FTS를 사용한 검색이 단순히 한 번의 쿼리 실행으로 끝나는 것이 아니라, 지속적으로 데이터베이스의 변화에 따라 동적으로 텍스트를 검색할 수 있습니다. 예를 들어, 사용자가 입력할 때마다 실시간으로 쿼리가 실행되고, 결과가 자동으로 업데이트되는 방식입니다. 이를 구현하려면, C++에서 이벤트 기반 검색을 처리하거나, 폴링 메커니즘을 사용하여 주기적으로 쿼리를 실행할 수 있습니다.
// 예시: 검색어가 변경될 때마다 실시간으로 검색 결과를 업데이트
std::string keyword;
while (true) {
std::cout << "Enter search keyword: ";
std::getline(std::cin, keyword);
const char* searchSQL = "SELECT title, content FROM documents WHERE content MATCH ?;";
sqlite3_stmt* stmt;
sqlite3_prepare_v2(db, searchSQL, -1, &stmt, 0);
sqlite3_bind_text(stmt, 1, keyword.c_str(), -1, SQLITE_STATIC);
while (sqlite3_step(stmt) == SQLITE_ROW) {
const char* title = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
const char* content = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
std::cout << "Title: " << title << "\n";
std::cout << "Content: " << content << "\n\n";
}
sqlite3_finalize(stmt);
}
이 코드는 사용자가 키워드를 입력할 때마다 실시간으로 검색 쿼리를 실행하여 결과를 표시합니다. 동적 텍스트 검색을 구현하면, 검색 속도와 사용자 경험을 향상시킬 수 있습니다.
SQLite FTS 기능을 활용한 검색 엔진 구축 실습
이 섹션에서는 SQLite의 FTS 기능을 사용하여 간단한 검색 엔진을 구현하는 방법을 실습해보겠습니다. 이 예제에서는 C++와 SQLite를 활용하여 텍스트 데이터를 저장하고, 이를 FTS로 검색하는 과정까지 다룹니다.
1. 데이터베이스 설정 및 FTS 테이블 생성
먼저, SQLite 데이터베이스를 설정하고 FTS 테이블을 생성합니다. FTS5를 활성화하여 더 빠르고 효율적인 검색을 지원합니다.
#include <sqlite3.h>
#include <iostream>
int main() {
sqlite3* db;
int rc = sqlite3_open("search_engine.db", &db);
if (rc) {
std::cerr << "Can't open database: " << sqlite3_errmsg(db) << std::endl;
return 1;
}
const char* createTableSQL =
"CREATE VIRTUAL TABLE IF NOT EXISTS documents USING FTS5(title, content);";
rc = sqlite3_exec(db, createTableSQL, 0, 0, 0);
if (rc != SQLITE_OK) {
std::cerr << "SQL error: " << sqlite3_errmsg(db) << std::endl;
}
sqlite3_close(db);
return 0;
}
이 코드는 documents
라는 FTS5 테이블을 생성합니다. title
과 content
두 열을 인덱싱하여, 이들에 대해 텍스트 검색을 할 수 있게 됩니다.
2. 데이터 삽입
이제 FTS 테이블에 데이터를 삽입하는 방법을 살펴보겠습니다. 사용자가 추가할 문서의 제목과 내용을 데이터베이스에 삽입할 수 있습니다.
#include <sqlite3.h>
#include <iostream>
int main() {
sqlite3* db;
sqlite3_open("search_engine.db", &db);
const char* insertSQL = "INSERT INTO documents (title, content) VALUES (?, ?);";
sqlite3_stmt* stmt;
// 예시 데이터 삽입
const char* title = "SQLite Basics";
const char* content = "SQLite is a C-language library that implements a small, fast, self-contained, high-reliability, full-featured SQL database engine.";
sqlite3_prepare_v2(db, insertSQL, -1, &stmt, 0);
sqlite3_bind_text(stmt, 1, title, -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, content, -1, SQLITE_STATIC);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
위 코드는 documents
테이블에 제목과 내용을 삽입하는 방법을 보여줍니다. 여러 개의 문서를 삽입하려면 INSERT
문을 반복적으로 실행하면 됩니다.
3. 검색 쿼리 실행
FTS5 기능을 활용하여 삽입된 데이터에서 검색을 실행합니다. 사용자가 입력한 키워드에 대해 MATCH
연산자를 이용한 쿼리를 실행합니다.
#include <sqlite3.h>
#include <iostream>
int main() {
sqlite3* db;
sqlite3_open("search_engine.db", &db);
const char* searchSQL = "SELECT title, content FROM documents WHERE content MATCH ?;";
sqlite3_stmt* stmt;
// 사용자가 입력한 검색어
const char* keyword = "SQLite";
sqlite3_prepare_v2(db, searchSQL, -1, &stmt, 0);
sqlite3_bind_text(stmt, 1, keyword, -1, SQLITE_STATIC);
while (sqlite3_step(stmt) == SQLITE_ROW) {
const char* title = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
const char* content = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
std::cout << "Title: " << title << "\n";
std::cout << "Content: " << content << "\n\n";
}
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
위 예시는 content
열에서 사용자가 입력한 검색어와 일치하는 문서를 찾는 쿼리입니다. 검색어 SQLite
에 해당하는 제목과 내용이 출력됩니다.
4. 검색 결과 처리 및 출력
검색 결과는 sqlite3_step()
함수로 하나씩 가져오며, 각 열의 값을 sqlite3_column_text()
함수를 사용하여 읽어옵니다. 이 데이터를 사용자에게 출력하면 검색 결과를 확인할 수 있습니다.
5. 전체 코드 예제
이제 앞서 설명한 내용들을 종합하여 간단한 SQLite 기반 텍스트 검색 엔진을 완성한 전체 코드를 제공합니다.
#include <sqlite3.h>
#include <iostream>
int main() {
sqlite3* db;
sqlite3_open("search_engine.db", &db);
// 테이블 생성
const char* createTableSQL =
"CREATE VIRTUAL TABLE IF NOT EXISTS documents USING FTS5(title, content);";
sqlite3_exec(db, createTableSQL, 0, 0, 0);
// 데이터 삽입
const char* insertSQL = "INSERT INTO documents (title, content) VALUES (?, ?);";
sqlite3_stmt* stmt;
const char* title = "SQLite Basics";
const char* content = "SQLite is a C-language library that implements a small, fast, self-contained, high-reliability, full-featured SQL database engine.";
sqlite3_prepare_v2(db, insertSQL, -1, &stmt, 0);
sqlite3_bind_text(stmt, 1, title, -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, content, -1, SQLITE_STATIC);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
// 검색 쿼리 실행
const char* searchSQL = "SELECT title, content FROM documents WHERE content MATCH ?;";
const char* keyword = "SQLite";
sqlite3_prepare_v2(db, searchSQL, -1, &stmt, 0);
sqlite3_bind_text(stmt, 1, keyword, -1, SQLITE_STATIC);
while (sqlite3_step(stmt) == SQLITE_ROW) {
const char* title = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
const char* content = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
std::cout << "Title: " << title << "\n";
std::cout << "Content: " << content << "\n\n";
}
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
이 코드는 SQLite 데이터베이스를 사용하여 FTS 기능으로 텍스트 검색을 구현하는 방법을 단계별로 설명합니다. 기본적인 삽입과 검색 쿼리 실행을 통해 텍스트 기반 검색 엔진을 구축할 수 있습니다.
요약
본 기사에서는 C++에서 SQLite의 FTS(Full Text Search) 기능을 사용하여 검색 엔진을 구축하는 방법을 소개했습니다. SQLite의 FTS5 기능을 활용하여 텍스트 검색을 효율적으로 처리할 수 있으며, 이를 통해 문서 데이터를 빠르게 인덱싱하고 검색할 수 있습니다.
FTS의 주요 기능인 기본 검색, 근사치 검색, 우선순위 검색, 정규 표현식, 검색어 자동 완성 및 동적 텍스트 검색 등의 고급 기능을 활용하여 더욱 정교한 검색 엔진을 구현할 수 있습니다. 실습 예제를 통해 데이터베이스 설정, 데이터 삽입, 검색 쿼리 실행 및 결과 처리까지 전반적인 구현 절차를 다루었습니다.
SQLite의 FTS 기능을 이용하면 검색 엔진 구축이 용이하고, 확장성 있는 검색 시스템을 개발할 수 있습니다. 이를 통해 텍스트 데이터를 빠르게 검색하고, 사용자가 원하는 정보를 효율적으로 추출할 수 있습니다.