Category: reference
SQLite สำหรับ Web Developer — ใช้ได้ทั้ง local และ edge
คู่มือใช้ SQLite ใน Node.js, Cloudflare Workers (D1) และ LibSQL — database ที่ไม่ต้องการ server
สารบัญ
ทำไม SQLite ถึงเหมาะกับ Personal Projects
- ไม่ต้องการ server — เป็นแค่ไฟล์
.db - เร็วมากสำหรับ read-heavy workload — query ส่วนใหญ่เร็วกว่า Postgres ถ้า dataset ไม่ใหญ่มาก
- Zero configuration — deploy ได้เลยพร้อม app
- ใช้ได้บน edge — Cloudflare D1, Turso (LibSQL)
Node.js — better-sqlite3
npm install better-sqlite3
import Database from 'better-sqlite3';
const db = new Database('./data.db');
// สร้าง table
db.exec(`CREATE TABLE IF NOT EXISTS notes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
body TEXT,
date TEXT DEFAULT (date('now'))
)`);
// Insert
const insert = db.prepare('INSERT INTO notes (title, body) VALUES (?, ?)');
const result = insert.run('My Note', 'Note content here');
console.log(result.lastInsertRowid);
// Query
const notes = db.prepare('SELECT * FROM notes ORDER BY date DESC').all();
const note = db.prepare('SELECT * FROM notes WHERE id = ?').get(1);
// Transaction
const addMany = db.transaction((items) => {
const stmt = db.prepare('INSERT INTO notes (title) VALUES (?)');
for (const item of items) stmt.run(item);
});
addMany(['Note A', 'Note B', 'Note C']);
Cloudflare D1 (SQLite บน Edge)
// wrangler.toml
// [[d1_databases]]
// binding = "DB"
// database_name = "my-db"
export default {
async fetch(request, env) {
const results = await env.DB.prepare(
'SELECT * FROM notes WHERE id = ?'
).bind(1).all();
return Response.json(results);
}
};
Drizzle ORM — type-safe SQL
npm install drizzle-orm better-sqlite3
npm install -D drizzle-kit @types/better-sqlite3
import { sqliteTable, integer, text } from 'drizzle-orm/sqlite-core';
import { drizzle } from 'drizzle-orm/better-sqlite3';
const notes = sqliteTable('notes', {
id: integer('id').primaryKey({ autoIncrement: true }),
title: text('title').notNull(),
date: text('date').default(sql`(date('now'))`),
});
const db = drizzle(sqliteDb);
const allNotes = await db.select().from(notes).orderBy(desc(notes.date));
เมื่อไหร่ไม่ควรใช้ SQLite
- มีหลาย process เขียนพร้อมกัน (WAL mode ช่วยบ้างแต่ไม่สมบูรณ์)
- Dataset ขนาดใหญ่มาก (หลาย GB ขึ้นไป) ที่ต้องการ concurrent reads สูง
- ต้องการ full-text search ขั้นสูง (ใช้ FTS5 extension ได้แต่จำกัด)