幽默:如何在靜態檔案託管伺服器上使用資料庫?

banq發表於2021-05-07

如何在靜態檔案託管伺服器上使用資料庫?首先,將SQLite(用C編寫)編譯為WebAssembly。SQLite可以使用emscripten進行編譯,而無需進行任何修改,並且sql.js庫是wasm程式碼周圍的薄JS包裝器。
sql.js只允許您建立和讀取完全位於記憶體中的資料庫-因此,我實現了一個虛擬檔案系統,當SQLite嘗試從檔案系統讀取時,該虛擬檔案系統使用HTTP Range請求獲取資料庫的塊:sql.js-httpvfs。從SQLite的角度來看,它看起來像是生活在具有空檔案系統的普通計算機上,但可以讀取/wdi.sqlite3檔案的空檔案系統。當然它不能寫入該檔案,但是隻讀資料庫仍然非常有用。
由於透過HTTP獲取資料的開銷非常大,因此我們需要分塊獲取資料,並在請求數量和使用的頻寬之間找到平衡。幸運的是,SQLite已經使用使用者定義的頁面大小(預設為4 KiB)將其資料庫組織在“ pages ”中。我已將此資料庫的頁面大小設定為1 KiB。
這是一個簡單的索引查詢查詢的示例:

select indicator_code, long_definition from wdi_series where indicator_name
    = 'Literacy rate, youth total (% of people ages 15-24)'


執行上面的查詢,然後檢視頁面讀取日誌。SQLite對該查詢進行7頁讀取。
  • 僅讀取三頁即可獲得一些架構資訊(這些資訊已被快取)
  • 兩頁讀取是索引中的索引查詢 on wdi_series (indicator_name)
  • wdi_series表資料上有兩次頁面讀取(第一次透過主鍵查詢行值,第二次從溢位頁面獲取文字資料)

索引以及表讀取都是B樹查詢。
 

好處:DOM作為資料庫
由於我們已經在瀏覽器中執行資料庫,為什麼不使用瀏覽器稱為dom虛擬表作為資料庫?

select count(*) as number_of_demos from dom
  where selector match '.content div.sqlite-httpvfs-demo';
select count(*) as sqlite_mentions from dom
  where selector match '.content p' and textContent like '%SQLite%';


我們甚至可以將元素直接插入DOM中:

insert into dom (parent, tagName, textContent)
    select 'ulouttable1', 'li', short_name
    from wdi_country where currency_unit = 'Euro'


更新DOM中的元素:

update dom set textContent =
  get_flag("2-alpha_code") || ' ' || textContent
from wdi_country
where selector match 'ulouttable1 > li'
  and textContent = wdi_country.short_name


當然,這裡的一切都是開源的。sqlite包裝器的主要實現是在sql.js-httpvfs中。該部落格文章的原始碼是pandoc markdown檔案,而演示是自定義的“圍欄fenced程式碼塊” React元件
點選標題
 

相關文章