mozilla
您的搜尋結果

    IndexedDB基礎慨念

    IndexedDB用來儲存資料到使用者的瀏覽器,所以我們的網頁應用程式不論在線上或線下都可以運作。IndexedDB對需要儲存大量資料上(如儲存DVD出租型錄)的應用和不用一直存取網路的應用(如郵件客戶端瀏覽、代辦事項、記事本等)來說十分好用。

    關於本文

    本文介紹IndexedDB重要概念和專有名詞,旨在提供IndexedDB全貌和關鍵概念,如要了解更多IndexedDB專有名詞,請參照定義部分。

    想了解如何使用相關API,請參照使用IndexedDB;相關參考資料請參照IndexedDB一文,該文介紹了IndexedDB使用物件型態以及同步和非同步API。

    IndexedDB概要

    IndexedDB讓我們透過資料鍵(key)儲存、取回物件。所有對資料庫的變更都發生在交易操作;如同大部分網頁儲存方案,IndexedDB遵守同源政策,也就是說我們只能存取同網域下的資料。

    API有分非同步同步,非同步API適用於大部分情況,包括Web Worker,而同步API應該只用在Web Worker內。目前主流瀏覽器尚不支援同步API,不過即使同步API存在,大部分的情況還是以非同步API使用為主。

    W3C在2011/11/18宣布WebSQL已棄用,請用IndexedDB作為替代方案。IndexedDB和WebSQL雖然都是儲存方案,但功能並不相同,IndexedDB是索引資料表資料庫,而WebSQL是關聯式資料庫系統。

    概念總覽

    請將你在其他類型資料庫上的預期從IndexedDB上拋開,然後謹記以下重要概念:

    • IndexedDB資料庫儲存資料鍵對資料值的成對資料(key-value pairs)。資料值可以是複雜的結構化物件,資料鍵可以是這些物件的屬性,然後我們可以依物件屬性建立索引,進行資料搜尋以及排序。

    • IndexedDB建基於交易性質資料庫模型(transactional database model)。任何在IndexedDB上進行的操作都是屬於交易(transaction),IndexedDB API提供了索引、資料表等等許多物件,然而之些物件都鎖定到某一個特定交易,所以我們不行在交易範疇外執行指令等操作。

      交易具有生命週期,所以交易結束後又操作交易會引起例外錯誤,而且交易是自動執行生效的,無法手動執行生效。

      想想看如果一個使用者在兩個頁面開啟同一個網路應用程式時,若是沒有交易機制,這兩個頁面對資料庫的存取操作將會產生衝突,因此交易機制是一個相當有用的機制。如果不清楚何謂交易,請參照底下交易定義部分和維基百科交易相關文章

    • IndexedDB大部分API都是非同步類別。IndexedDB API不會回傳資料,相反地,我們需要傳入回呼函數(Callback function)。我們並非直接、同步地儲存和取得資料,我們是請求資料庫作業,當作業結束時DOM事件再通知我們作業結束,然後我們再透過事件類別判斷作業成功或失敗;或許以上作法一開始聽起來有點複雜,不過之所以會如此做是有其背後道理的,而且這種作法和XMLHttpRequest相去不遠。

    • IndexedDB透過DOM事件通知作業結果。DOM事件具有一個type屬性(在IndexedDB中,這個屬性幾乎不是”success”就是”error”),DOM事件還有一個target屬性告訴我們事件進行目標,絕大多數情況下,事件的target皆為操作資料庫結果產生的IDBRequest物件。成功事件不會往上傳播而且無法取消,失敗事件會往上傳播但可取消,請謹記這點,因為正在進行的交易會因為失敗事件而中止,除非取消失敗事件。

    • IndexedDB隨處都在使用請求(Request)。接收前述成功或失敗DOM事件的物件就是請求,請求有onsuccess和onerror屬性以及addEventListener和removeEventListener方法,他們還有readyState, result與errorCode屬性告訴我們請求狀態,尤其result屬性相當奇妙,它可以代表各式不同意義,就看我們是如何建立請求,比如說,一個IDBCurson物件或剛存入資料庫的資料的資料鍵。

    • IndexedDB乃是物件導向的。IndexedDB非關聯式資料庫,沒有資料表,這一點深深影響著應用程式如何設計。

      傳統關聯式資料庫中存著由資料列和屬性欄所構成的資料表,另一方面,IndexedDB存的是某一個資料型態的物件存檔(Object store),IndexedDB就只是保存存檔的Javascript物件;每一個物件存檔能具備一連串索引用以搜尋和排列資料,如果沒有聽過物件導向資料管理系統庫,可以去維基百科物件資料庫看看。

    • IndexedDB沒有結構化查詢語言(Structured Query Language, SQL)。IndexedDB查詢索引以取得指標(Cursor),然後我們再用指標一一存取查詢結果,如果沒有聽過NoSQL系統,請去維基百科NoSQL看看。

    • IndexedDB遵守同源政策(Same-origin policy)。URL的網域、應用層協定和埠號構成來源,每一個來源皆有其獨特關聯的資料庫,每一個資料庫都有名稱辨識其所在來源。

      同源政策限制了IndexedDB存取其他來源下的資料,例如來自http://www.example.com/app/的應用能夠存取http://www.example.com/dir/下的資料,因為他們其實來自同一個來源,但無法存取http://www.example.com:8080/dir/(埠號不同)或https://www.example.com/dir/(協定不同)的資料,因為來源不同。

    定義

    以下是IndexedDB API專有名詞定義與解說。

    Database

    資料庫
    資訊集中存放之處,由一或數個物件存檔(Object store)組成,每一個資料庫必須具有:
    • 名稱。用以辨識資料庫所屬來源,在生命週期間固定不變,可以任意字串(甚至空白字串)。
    • 目前版本。當資料庫創建後,如未指定,它的版本是整數1。每一個資料庫同一時間只能有一個版本。

    物件存檔(object store)

    資料存放於資料庫的機制;物件存檔持有紀錄,也就是資料鍵和資料值的成對紀錄。記錄在物件存檔中依資料鍵(keys)大小由小到大排列。

    每一個物件存檔都具備獨特名稱,物件存檔能夠選擇性地持有key generatorkey path;若有key path便會採用in-line keys,否則便採用out-of-line keys

    更多物件存檔細節,請參照IDBObjectStoreIDBObjectStoreSync

    版本(version)
    當資料庫創建後,如未指定,它的版本是整數1;每一個資料庫同一時間只能有一個版本,唯一變更版本的方法是開啟比目前更大的版本,變更版本將啟動versionchange交易並且觸發upgradeneeded事件,upgradeneeded事件處理器也是唯一可以變更資料庫結構之處。
    注意: 本處解說涵蓋近期大部分規範,舊版瀏覽器支援現在已經廢棄的IDBDatabase.setVersion()方法。
     
    database connection
    An operation created by opening a database. A given database can have multiple connections at the same time.
    交易(transaction)

    在特定資料庫上進行資料存取和資料修改的一連串作業,這便是我們和資料庫的互動,事實上,任何讀取或變更資料庫資料都會發生在交易之中。

    只要寫入交易間沒有重疊範疇(scopes),一個資料庫連結可以同時擁有多個進行中交易。交易範疇在交易創建當下決定,交易範疇定義了與交易互動的物件存檔以及將交易期間不可變更部分,例如說,有一個資料庫連結正在進行寫入交易,這項寫入交易涵蓋flyingMonkey物件存檔,我們可以進行第二項有關unicornCentaur與unicornPegasus物件存檔的交易。至於讀取交易則不受交易範疇重疊限制。

    交易的生命應該不可過長,所以瀏覽器可以終止交易時間過長的交易,好讓長時間被鎖定的資料得以解除鎖定;交易可以中止,中止後交易所造成的變更都會被復原;交易的中止不必要等到交易開始或進行中。

    交易有三種模式: readwrite, readonlyversionchange,只能透過versionchange交易創建、刪除物件存檔與索引。

    由於交易是相當重要的觀念,尤其是交易和版本間的關係,請參照IDBTransaction以了解更多交易相
    關細節,另外關於同步API,請參照IDBTransactionSync

    請求(request)
    每一個讀寫作業都是一個請求。
    索引(index)

    一個用來查詢其他物件存檔內紀錄的特殊物件存檔,被查詢的物件存檔我們稱為參照物件存檔(referenced object store)。索引是資料鍵和值的成對紀錄,其中值就是參照物件存檔內的記錄的資料鍵;當參照物件存檔有紀錄新增、變更或刪除時索引內的紀錄也會相應自動產生,索引內的紀錄只能指向參照物件存檔內的一筆紀錄,但可以有多筆索引紀錄參照同一個物件存檔。物件存檔變更同時,所有的相關索引也會自動相應更新。

    除此之外,我們也可以透過資料鍵(key)來查詢物件存檔中的紀錄。

    了解如何使用索引請參照使用IndexedDB,要知道更多索引細節請參照IDBKeyRangeIDBIndex

    資料鍵(Key)和資料值(Value)

    資料鍵(key)

    資料存放在物件存檔中。物件存檔有三種方式產生資料鍵: 資料鍵產生器(key generator)、資料鍵路徑(key path)以及指定值。資料鍵的資料型態(data type)必須要是能夠進行大小排序;物件存檔中的每一筆紀錄都要有一支獨特的對應資料鍵,不能和同一個物件存檔中其他紀錄的資料鍵相同。

    資料鍵可以是: string, date, float和array(陣列);對於array,資料鍵範圍可以是空值到無限,還可以在array中包含另一個array,至於以字串或整數作資料鍵則無特殊規定。

    除此之外,我們也可以透過索引(index)來查詢物件存檔中的紀錄。

    資料鍵產生器(key generator)
    被存成為儲存值一部分的資料鍵,當使用資料鍵路徑(key path)時產生。In-line資料鍵能用資料鍵產生器產生,產生後,In-line資料鍵可以依資料鍵路徑存入資料值,也可以用作為資料鍵。
    in-line key
    被存成為儲存值一部分的資料鍵,當使用資料鍵路徑(key path)時產生。In-line資料鍵能用資料鍵產生器產生,產生後,In-line資料鍵可以依資料鍵路徑存入資料值,也可以用作為資料鍵。
    out-of-line key
    沒有存成資料值一部分的資料鍵。
    資料鍵路徑(key path)
    定義瀏覽器應該如何從物件存檔資料值或索引中提取資料鍵。以下為有效的資料鍵路徑: 一個空字串、一個Javascript辨識名稱(JavaScript identifier)或數個由”.”(ASCII字元第46字碼)分隔的Javascript辨識名稱。路徑不可含有空白字元。
    資料值(value)

    每筆紀錄都有資料值,資料值可以是任意Javascript所能表達的項目,包括boolean, number, string, date, object, array, regexp, undefined以及 null。

    儲存物件或陣列裡的屬性和值也可以是任意Javascript所能表達的項目。

    可以儲存Blobs和檔案,請參照W3C規範

    範圍和範疇

    範疇
    交易影響到的物件和索引。讀取交易間的範疇可以互相重疊、同時進行,然後寫入交易範疇則不可,如果同時開啟多項交易範疇相同的寫入交易的話,那麼這些交易會排入佇列(queue),一個接著一個完成後執行。
    指標(Cursor)
    在一定資料鍵範圍以內往覆(iterate)資料的機制。指標指向了一個物件存檔或索引,它會在一定範圍內,由小到大或由大到小循著紀錄的資料鍵移動,詳細資訊請參照IDBCursorIDBCursorSync
    資料鍵範圍

    某種資料型態的一段連續區間,這個區間將作為資料鍵的上下限,我們透過資料鍵或資料鍵範圍取出物件存檔和索引值;藉由上下限我們可以做到存取資料鍵介於x和y之間的資料,詳細請參考IDBKeyRange

    限制

    IndexedDB設計上足以滿足大部分客戶端儲存需求,不過,以下情況並不適用IndexedDB:

    • 多國語言排序。各國語言字串的排序不一定都一樣,所以IndexedDB無法處理多國語言字串排序。不過雖然IndexedDB無法處理多國語言字串排序,我們可以改為先讀出資料後再自行排序。
    • 同步化。IndexedDB API設計上並沒有考慮到和伺服器端資料庫同步化,所以客戶端和伺服器端資料庫同步需要我們自行處理。
    • 全文搜尋。IndexedDB沒有等同於SQL的LIKE的API。

    除此之外,請小心瀏覽器可能會清空資料庫,例如:

    • 使用者要求清空資料庫。許多瀏覽器讓使用者可以清空網站的cookies、書籤、密碼和IndexedDB資料庫。
    • 私密瀏覽。Firefox和Chrome等瀏覽器提供私密瀏覽模式,當瀏覽結束後,資料庫會被清空。
    • 超出硬碟空間或資料庫空間上限。
    • 資料毀損。
    • 當未來有不相容於現在的修改。

    瀏覽器確切的狀況和功能範疇未來會變更,但基本上瀏覽器還是會盡可能保存資料。

    Warning: 目前因為問題和刻意安排,Web App無法開啟IndexedDB資料庫,需要更多這方面的分析和探討。

    下一步

    現在我們已經了解IndexedDB的整體概念,接下來請到“使用IndexedDB”看看如何實際使用IndexedDB。

    延伸閱讀

    標準規範

    參照

    相關教學

    相關文章

    Document Tags and Contributors

    Contributors to this page: foxbrush, thomaschen
    最近更新: thomaschen,