在瀏覽器裡跑 SQL 引擎 - SQLite WASM
| | | 5 | |
用 Kaggle 上的最受歡迎 Github 專案資料集當練習,67MB 大小的 CSV 檔包含 210,180 個 Github 專案的 Id、名稱、說明、URL、星星數、Fork 數、關注數、程式語言、開源授權... 等欄位。
如何寫個網頁可以下 SQL 即興查詢前十大程式語言、最多專案用的授權,像以下這樣:

感覺一點也不稀奇,對吧?寫個網頁,後端接 ASP.NET/Node.js/Python/PHP 或任何網站伺服器程式,將資料匯入 SQLite、MySQL、PostgreSQL,大家小學二年級就會了。
等等,程式寫成這幅德行,後端資料庫任人 SELECT/UPDATE/DELETE 不會出事嗎?
但如果我說,這個 SQL 引擎只活在當前的瀏覽器記憶體,不依賴任何伺服器端程序,網頁全靠靜態檔案運行,是不是就有點意思了?
這一切都要感謝 sql.js 開源專案 - SQLite compiled to JavaScript。
sql.js 使用 emscripten 將 SQLite 編譯為 WebAssembly,可想像將 SQLite 的 C 語言編輯成可在瀏覽器跑的低階二進位程式碼格式,執行速度逼近原生執行程式的效能。sql-wasm.wasm 大小僅 600KB,載入後我們就可以用 JavaScript 建資料表、用標準 SQLite SQL 語法查詢新增修改刪除資料,整個過程都在網頁裡,不需連線伺服器,在某些必須在本地端處理複雜大量資料操作的情境,是核彈等級的利器。
以下是個最簡單的示範,透過 CDN 載入 sql-wasm.js、.wasm 檔案,然後建 Table、INSERT 資料、下 SELECT 查詢:線上展示
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SQLite WASM 展示</title>
<script src="https://cdn.jsdelivr.net/npm/sql.js@1.13.0/dist/sql-wasm.js"></script>
<script>
(async () => {
const SQL = await initSqlJs({
// 傳入 .wasm 檔名,對應下載網址
locateFile: file => `https://cdn.jsdelivr.net/npm/sql.js@1.13.0/dist/${file}`
});
// 初始化 SQLite 資料庫
const db = new SQL.Database();
// 建資料表
db.run("CREATE TABLE players (id INTEGER PRIMARY KEY, name TEXT, score INTEGER)");
// 插入資料
db.run("INSERT INTO players (name, score) VALUES ('Jeffrey', 255)");
db.run("INSERT INTO players (name, score) VALUES ('darkthread', 32767)");
// 查詢資料
const res = db.exec("SELECT * FROM players WHERE score > ?", [100]);
const cols = res[0].columns;
const rows = res[0].values;
const list = rows.map(row => {
const player = {};
cols.forEach((col, i) => {
player[col] = row[i];
});
return player;
});
document.querySelector('pre').textContent = JSON.stringify(list, null, 2);
})();
</script>
</head>
<body>
<pre></pre>
</body>
</html>

至於文章開頭的範例,算是我第一個用 Github Copilot Agent Mode 嘗試 Vibe Coding 做的玩具,我也放上 Github Pages 了,有興趣的同學可以玩看看。

問我 Vibe Coding 的感想?開發程式終究還是場戰鬥,但需要的技巧他X的完全不同啊啊啊~~

The blog post discusses using sql.js to execute SQL queries directly in the browser without a server, leveraging WebAssembly for SQLite. It highlights a demo that enables querying a CSV dataset with SQL on the client side.
Comments
# by 派脆克
這個技術還蠻酷的,讓我問個弱弱問題,這個sqlite是存在單個瀏覽器分頁的記憶體中嗎?如果想要持久化裡面的資料,有什麼比較好的做法?如果沒有持久化資料,那是不是跟把資料存在記憶裡差不多?
# by yoyo
so cool~ 在某些情況還滿實用的 請問能夠save/load SQLite檔案嗎
# by test
持久化只能用Cache API, IndexedDB(太辛苦)
# by Jeffrey
to 派脆克/yoyo,請參考新文 https://blog.darkthread.net/blog/sqlite-wasm-persistence/
# by James
這應該是駭客的最愛吧