用 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的完全不同啊啊啊~~

thumbnail

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

這應該是駭客的最愛吧

Post a comment