Fast SQL 시작하기
Copy a setup prompt with the install steps and the full markdown guide for this plugin.
Set up this Capacitor plugin in the project.
Use the package manager already used by the project.
Install these package(s): `@capgo/capacitor-fast-sql`
Run the required Capacitor sync/update step after installation.
Read this markdown guide for the full setup steps: https://raw.githubusercontent.com/Cap-go/website/refs/heads/main/apps/docs/src/content/docs/ko/docs/plugins/fast-sql/getting-started.mdx
Use that guide for platform-specific steps, native file edits, permissions, config changes, imports, and usage setup.
If that guide references other docs pages, read them too.
이 가이드는 고성능 SQLite 데이터베이스 액세스를 위한 @capgo/capacitor-fast-sql 플러그인의 설치 및 구성을 도와드립니다.
Fast SQL을 사용하는 이유는?
Section titled “Fast SQL을 사용하는 이유는?”Capacitor용 기존 SQLite 플러그인은 웹 코드와 네이티브 코드 간의 통신을 위해 표준 JavaScript 브리지에 의존합니다. 이는 작은 작업에는 문제없이 작동하지만, 대량의 데이터를 전송해야 할 때 브리지가 상당한 병목 현상이 됩니다. 모든 데이터는 JSON으로 직렬화되고, 브리지를 통해 전송되며, 반대편에서 역직렬화되어야 합니다. 이 직렬화 오버헤드로 인해 수천 개의 행이나 대용량 바이너리 데이터를 처리하는 작업이 매우 느려집니다.
Fast SQL은 이 문제를 해결합니다 기기에 로컬 HTTP 서버를 구축하여 네이티브 SQLite 데이터베이스와 직접 통신합니다. 이 사용자 정의 프로토콜은 Capacitor의 브리지를 완전히 우회하여 직렬화 오버헤드를 제거하고 다음을 가능하게 합니다:
- 배치 작업 및 대규모 데이터셋에 대해 최대 25배 빠른 성능
- base64 인코딩 없는 효율적인 바이너리 데이터 전송
- 메모리 문제 없이 대용량 결과 스트리밍
- CRDT 및 operational transforms와 같은 동기화 시스템에 최적의 성능
이는 Fast SQL을 로컬 우선 애플리케이션, 오프라인 동기화 시스템 및 IndexedDB를 더 안정적이고 성능이 뛰어난 솔루션으로 교체해야 하는 시나리오에 이상적으로 만듭니다.
npm install @capgo/capacitor-fast-sqlnpx cap sync플랫폼 구성
Section titled “플랫폼 구성”iOS 구성
Section titled “iOS 구성”로컬 네트워킹을 허용하려면 Info.plist에 다음을 추가하세요:
<key>NSAppTransportSecurity</key><dict> <key>NSAllowsLocalNetworking</key> <true/></dict>Android 구성
Section titled “Android 구성”필요한 경우 AndroidManifest.xml에 추가하세요:
<application android:usesCleartextTraffic="true"> ...</application>Web 구성
Section titled “Web 구성”웹 플랫폼 지원을 위해 sql.js를 설치하세요:
npm install sql.js기본 사용법
Section titled “기본 사용법”데이터베이스에 연결
Section titled “데이터베이스에 연결”import { FastSQL } from '@capgo/capacitor-fast-sql';
// 데이터베이스에 연결 (파일이 없으면 생성)const db = await FastSQL.connect({ database: 'myapp'});
console.log('Connected to database on port:', db.port);테이블 생성
Section titled “테이블 생성”// 테이블 생성await db.execute(` CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, email TEXT UNIQUE, created_at INTEGER DEFAULT (strftime('%s', 'now')) )`);데이터 삽입
Section titled “데이터 삽입”// 단일 행 삽입const result = await db.run( 'INSERT INTO users (name, email) VALUES (?, ?)', ['John Doe', 'john@example.com']);
console.log('Inserted row ID:', result.insertId);console.log('Rows affected:', result.rowsAffected);데이터 쿼리
Section titled “데이터 쿼리”// 매개변수를 사용한 쿼리const users = await db.query( 'SELECT * FROM users WHERE name LIKE ?', ['John%']);
console.log('Found users:', users);
// users는 객체 배열입니다:// [{ id: 1, name: 'John Doe', email: 'john@example.com', created_at: 1234567890 }]데이터 업데이트
Section titled “데이터 업데이트”const result = await db.run( 'UPDATE users SET email = ? WHERE id = ?', ['newemail@example.com', 1]);
console.log('Updated rows:', result.rowsAffected);데이터 삭제
Section titled “데이터 삭제”const result = await db.run( 'DELETE FROM users WHERE id = ?', [1]);
console.log('Deleted rows:', result.rowsAffected);트랜잭션은 원자성을 보장합니다 - 모든 작업이 성공하거나 모두 롤백됩니다:
try { await db.transaction(async (tx) => { // 이 블록의 모든 작업은 트랜잭션의 일부입니다 await tx.run('INSERT INTO accounts (name, balance) VALUES (?, ?)', ['Alice', 1000]); await tx.run('INSERT INTO accounts (name, balance) VALUES (?, ?)', ['Bob', 500]);
// 송금 await tx.run('UPDATE accounts SET balance = balance - 100 WHERE name = ?', ['Alice']); await tx.run('UPDATE accounts SET balance = balance + 100 WHERE name = ?', ['Bob']); });
console.log('Transaction committed successfully!');} catch (error) { console.error('Transaction rolled back:', error); // 오류 발생 시 모든 변경 사항이 자동으로 롤백됩니다}트랜잭션 격리 수준
Section titled “트랜잭션 격리 수준”import { FastSQL, IsolationLevel } from '@capgo/capacitor-fast-sql';
await db.transaction(async (tx) => { // 작업}, IsolationLevel.Serializable);사용 가능한 격리 수준:
ReadUncommitted- 최저 격리, 최고 성능ReadCommitted- 더티 읽기 방지RepeatableRead- 반복 불가능한 읽기 방지Serializable- 최고 격리, 모든 이상 현상 방지
여러 문을 효율적으로 실행:
const results = await db.executeBatch([ { statement: 'INSERT INTO logs (message, level) VALUES (?, ?)', params: ['App started', 'INFO'] }, { statement: 'INSERT INTO logs (message, level) VALUES (?, ?)', params: ['User logged in', 'INFO'] }, { statement: 'INSERT INTO logs (message, level) VALUES (?, ?)', params: ['Error occurred', 'ERROR'] },]);
console.log('Executed', results.length, 'statements');바이너리 데이터 (BLOB)
Section titled “바이너리 데이터 (BLOB)”Uint8Array를 사용하여 바이너리 데이터 저장 및 검색:
// 바이너리 데이터 저장const imageData = new Uint8Array([0xFF, 0xD8, 0xFF, 0xE0, /* ... */]);
await db.run( 'INSERT INTO images (name, data) VALUES (?, ?)', ['photo.jpg', imageData]);
// 바이너리 데이터 검색const rows = await db.query('SELECT data FROM images WHERE name = ?', ['photo.jpg']);const retrievedData = rows[0].data; // Uint8Array암호화 (iOS/Android)
Section titled “암호화 (iOS/Android)”안전한 저장을 위해 SQLCipher 암호화 활성화:
const db = await FastSQL.connect({ database: 'secure_db', encrypted: true, encryptionKey: 'your-secure-encryption-key'});읽기 전용 모드
Section titled “읽기 전용 모드”수정을 방지하기 위해 읽기 전용 모드로 데이터베이스 열기:
const db = await FastSQL.connect({ database: 'myapp', readOnly: true});작업이 완료되면 항상 데이터베이스 연결을 닫으세요:
await FastSQL.disconnect('myapp');직접 HTTP 프로토콜
Section titled “직접 HTTP 프로토콜”대규모 데이터셋에서 최대 성능을 위해 HTTP 프로토콜을 직접 사용:
const { port, token } = await FastSQL.getServerInfo({ database: 'myapp' });
// localhost:port로 직접 HTTP 요청 만들기// Authorization 헤더에 토큰 포함const response = await fetch(`http://localhost:${port}/execute`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ statement: 'SELECT * FROM users', params: [] })});
const result = await response.json();import { FastSQL } from '@capgo/capacitor-fast-sql';
try { const db = await FastSQL.connect({ database: 'myapp' });
await db.run('INSERT INTO users (name, email) VALUES (?, ?)', ['John', 'john@example.com']);
} catch (error) { if (error.message.includes('UNIQUE constraint failed')) { console.error('Email already exists'); } else if (error.message.includes('no such table')) { console.error('Table does not exist'); } else { console.error('Database error:', error); }}일반적인 SQL 패턴
Section titled “일반적인 SQL 패턴”테이블 존재 여부 확인
Section titled “테이블 존재 여부 확인”const result = await db.query( "SELECT name FROM sqlite_master WHERE type='table' AND name=?", ['users']);
const tableExists = result.length > 0;테이블 스키마 가져오기
Section titled “테이블 스키마 가져오기”const schema = await db.query('PRAGMA table_info(users)');console.log('Columns:', schema);행 개수 세기
Section titled “행 개수 세기”const result = await db.query('SELECT COUNT(*) as count FROM users');const count = result[0].count;페이지네이션
Section titled “페이지네이션”const pageSize = 20;const page = 1;const offset = (page - 1) * pageSize;
const users = await db.query( 'SELECT * FROM users ORDER BY created_at DESC LIMIT ? OFFSET ?', [pageSize, offset]);- 트랜잭션 사용 여러 작업에 대해 - 개별 커밋보다 훨씬 빠릅니다
- 배치 작업 사용 대량 삽입에 대해 - 루프보다 효율적입니다
- 인덱스 생성 자주 쿼리하는 열에
- 매개변수가 있는 준비된 문 사용 (?) - SQL 인젝션을 방지하고 성능을 향상시킵니다
- HTTP 프로토콜 직접 사용 매우 큰 결과 집합에 대해
- 연결 닫기 사용하지 않을 때 리소스를 해제합니다
다음을 포함한 고급 패턴에 대한 전체 튜토리얼을 확인하세요:
- 데이터베이스 서비스 아키텍처
- 마이그레이션 시스템
- 동기화 엔진
- 복잡한 쿼리 및 조인
- 성능 최적화