तेज़, सुरक्षित पर्सिस्टेंस के लिए better-sqlite3 का उपयोग प्रिपेयर्ड स्टेटमेंट, ट्रांज़ैक्शन और एक समर्पित रिपॉज़िटरी के साथ करें।
इस पाठ को Kodokon में खोलेंSQLite आपकी प्रोसेस के भीतर चलता है: कोई सर्वर नहीं, कोई नेटवर्क नहीं, प्रति-क्वेरी विलंब एक माइक्रोसेकंड के क्रम का। यही वह बात है जो better-sqlite3 की तुल्यकालिक (synchronous) API को न केवल स्वीकार्य बनाती है बल्कि अक्सर किसी अतुल्यकालिक ड्राइवर से तेज़ भी: एक टिक से छोटी रीड पर एक प्रॉमिस और एक इवेंट-लूप चक्र की कीमत चुकाने का कोई मतलब नहीं। समझौता राइट पर वास्तविक है: एक धीमी क्वेरी लूप को अवरुद्ध कर देती है। अपनी क्वेरी को इंडेक्स्ड और छोटा रखें, और SQLite प्रति सेकंड हज़ारों रीड संभाल लेता है।
npm install better-sqlite3डेटाबेस खोलते समय, दो सेटिंग्स अंतर पैदा करती हैं। WAL मोड (write-ahead logging) पूरी फ़ाइल को लॉक करने के बजाय एक राइट के दौरान रीड की अनुमति देता है। और स्कीमा को CREATE TABLE IF NOT EXISTS के साथ आइडेम्पोटेंट ढंग से लागू किया जाता है - किसी वास्तविक माइग्रेशन टूल को अपनाने से पहले यह पर्याप्त से अधिक है।
import Database from 'better-sqlite3';
export function createDb(path = 'app.db') {
const db = new Database(path);
db.pragma('journal_mode = WAL');
db.exec(`CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
email TEXT NOT NULL UNIQUE,
name TEXT NOT NULL
)`);
return db;
}डेटा एक्सेस परत - यानी रिपॉज़िटरी - एकमात्र मॉड्यूल है जो SQL बोलता है। क्वेरी निर्माण के समय एक बार प्रिपेयर की जाती हैं और फिर हर कॉल पर पुनः प्रयोग की जाती हैं: इंजन SQL टेक्स्ट को दोबारा पार्स नहीं करता, और वैल्यू प्लेसहोल्डर ? के ज़रिए गुज़रती हैं, कभी कॉन्कैटेनेशन के ज़रिए नहीं। यह ठीक वही findAll, findByEmail, insert इंटरफ़ेस है जिसकी पिछले पाठ की सर्विस अपेक्षा करती है।
export function createUserRepository(db) {
const insertStmt = db.prepare(
'INSERT INTO users (email, name) VALUES (?, ?)',
);
const byEmailStmt = db.prepare(
'SELECT * FROM users WHERE email = ?',
);
const allStmt = db.prepare(
'SELECT * FROM users ORDER BY id',
);
return {
insert(user) {
const info = insertStmt.run(user.email, user.name);
return { id: info.lastInsertRowid, ...user };
},
findByEmail(email) {
return byEmailStmt.get(email);
},
findAll() {
return allStmt.all();
},
};
}import { createDb } from './connection.js';
const db = createDb();
const insertStmt = db.prepare(
'INSERT INTO users (email, name) VALUES (?, ?)',
);
const insertMany = db.transaction((users) => {
for (const user of users) {
insertStmt.run(user.email, user.name);
}
});
insertMany([
{ email: 'ada@example.com', name: 'Ada' },
{ email: 'linus@example.com', name: 'Linus' },
]);? प्लेसहोल्डर क्या सुनिश्चित करते हैं?db.transaction क्या दोहरा लाभ लाता है?