IndexedDB ermöglicht es Ihnen Daten innerhalb des Browsers eines Benutzers permanent abzulegen. Weil es Sie Webanwendungen mit funktionsreichen Abfragemöglichkeiten erstellen lässt, können diese Anwendungen sowohl online als auch offline funktionieren. IndexedDB ist geeignet für Anwendungen, die eine große Menge an Daten speichern (z.B. ein Katalog von DVDs in einer Videothek) und Anwendungen, die keine durchgehende Internetverbindung benötigen um zu funktionieren (z.B. E-Mail-Clients, To-Do-Listen oder Notizen).
Über dieses Dokument
Diese Einführung bespricht wesentliche Konzepte und Fachbegriffe in IndexedDB. Sie liefert Ihnen einen Gesamtüberblick und führt Sie in die Schlüsselkonzepte ein. Um mehr über die Begrifflichkeiten von IndexedDB zu erfahren, lesen Sie den Abschnitt Definitionen.
Eine Anleitung zur Verwendung der API finden Sie im Artikel Using IndexedDB. Eine Referenzdokumentierung der IndexedDB-API finden Sie im Artikel IndexedDB und dessen Unterseiten, welche die Objekttypen dokumentiert, die von IndexedDB verwendet werden, ebenso wie die Methoden von synchronen wie asynchronen APIs.
Überblick über IndexedDB
Mit IndexedDB lassen sich indizierte Objekte mit „Schlüsseln“ ablegen und abrufen. Alle Änderungen an der Datenbank geschehen innerhalb von Transaktionen. Wie die meisten Webspeicher-Lösungen folgt IndexedDB einer Same-Origin-Policy. Während also auf Daten, die innerhalb einer Domain gespeichert wurden, zugegriffen werden kann, kann nicht domainübergreifend auf Daten zugegriffen werden.
Die API umfasst sowohl eine asynchrone API als auch eine synchrone API. Die asynchrone API kann für die meisten Fälle verwendet werden, auch für WebWorkers, während die synchrone API nur für den Gebrauch durch WebWorkers gedacht ist. Momentan wird die synchrone API von keinem der großen Browser unterstützt. Aber selbst wenn synchrone APIs unterstützt wären, würden Sie eher die asynchrone API verwenden, wenn Sie mit IndexedDB arbeiten.
IndexedDB ist eine Alternative zur WebSQL-Datenbank, welche vom W3C am 18. November 2010 als veraltet erklärt wurde. Während sowohl IndexedDB als auch WebSQL Lösungen zur Speicherung von Daten bieten, bieten sie nicht dieselben Funktionalitäten. WebSQL-Datenbank ist ein relationales Datenbankanfragesystem, IndexedDB hingegen ist ein indiziertes Tabellensystem.
Wichtige Konzepte
Wenn Sie die Arbeit mit anderen Datenbanksystemen gewohnt sind kann die Arbeit mit IndexedDB am Anfang ungewohnt erscheinen. Behalten Sie deshalb folgende wichtige Konzepte im Hinterkopf:
-
IndexedDB-Datenbanken speichern Schlüssel-Wert-Paare. Die Werte können komplexe strukturierte Objekte sein, und Schlüssel können Eigenschaften dieser Objekte sein. Für eine schnelle Suche oder eine sortierte Aufzählung können Indizes erstellt werden, die irgendeine Eigenschaft der Objekte nutzen.
-
IndexedDB baut auf einem Transaktions-Datenbankmodell auf. Alles, was Sie in IndexedDB tun, geschieht immer im Kontext einer Transaktion. Die IndexedDB-API bietet viele Objekte, die Indizes, Tabellen, Positionsmarken usw. repräsentieren, aber jedes einzelne dieser Objekte ist an eine bestimmte Transaktion gebunden. Deshalb können Sie außerhalb einer Transaktion keine Befehle ausführen oder Positionsmarken öffnen.
Transaktionen haben eine wohldefinierte Lebenszeit, deswegen führt der Versuch eine Transaktion zu verwenden, nachdem sie beendet ist, zu Exceptions. Außerdem führen Transaktionen ein Auto-Commit durch und können nicht von Hand committed werden.
Dieses Transaktionsmodell ist besonders nützlich im Hinblick auf was passieren könnte, wenn ein Benutzer zwei Instanzen einer Webapp gleichzeitig in verschiedenen Tabs öffnen würde. Ohne Transaktions-Operationen könnten die Änderungen der beiden Instanzen miteinander in Konflikt geraten. Wenn Sie mit Transaktionen in Datenbanken nicht vertraut sind, lesen Sie den Wikipedia-Artikel über Transaktionen. Eine weitere Beschreibung finden Sie außerdem im Abschnitt Definitionen bei Transaktion.
-
Die IndexedDB API ist meistens asynchron. Die API übergibt Daten nicht, indem sie Werte zurückgibt; stattdessen muss eine Callback-Funktion übergeben werden. Daten werden nicht in der Datenbank abgelegt oder aus ihr mittels synchronen Methoden abgerufen. Stattdessen muss eine Datenbankoperation angefordert werden. DOM-Ereignisse informieren darüber, wenn die Operation beendet ist, und aus der Art des Ereignisses lässt sich erkennen, ob die Operation erfolgreich war oder fehlschlug. Das klingt zunächst etwas kompliziert, aber hier wurden einige vernünfte Maßnahmen umgesetzt. Diese Funktionsweise ist außerdem nicht so anders als die, mit der XMLHttpRequest arbeitet.
-
IndexedDB verwendet Anfragen, überall. Anfragen sind Objekte, die Erfolgs- oder Fehlschlag-DOM-Ereignisse erhalten, welche zuvor erwähnt wurden. Anfragen können die Eigenschaften
onsuccess
undonerror
besitzen. Die FunktionenaddEventListener()
undremoveEventListener()
können auf ihnen ausgeführt werden. Sie haben außerdem die EigenschaftenreadyState
,result
, underrorCode
, die den Status der Anfrage mitteilen. Die Eigenschaftresult
ist besonders zauberhaft, da sie viele verschiedene Dinge darstellen kann, abhängig davon, wie die Anfrage erzeugt wurde (z.B. eine Instanz vonIDBCursor
, oder der Schlüssel zu einem Wert, den Sie gerade der Datenbank hinzugefügt haben). -
IndexedDB verwendet DOM-Ereignisse um Sie darüber zu informieren, wenn Ergebnisse verfügbar sind. DOM-Ereignisse haben immer die Eigenschaft
type
(in IndexedDB ist sie in den meisten Fällen auf „success
“ oder „error
“ gesetzt). DOM-Ereignisse haben außerdem eine Eigenschafttarget
, die Ihnen verrät in welche Richtung das Ereignis unterwegs ist. In den meisten Fällen ist dastarget
eines Ereignisses dasIDBRequest
Objekt, das als Ergebnis einiger Datenbankoperationen erzeugt wurde. Success events don't bubble up and they can't be canceled. Error events, on the other hand, do bubble, and can be cancelled. Das ist recht wichtig, da Fehlerereignisse jede Transaktion, in der sie auftauchen, zu einem Abort führen, es sei denn diese wird annulliert (cancel). -
IndexedDB ist objektorientiert. IndexedDB ist keine relationale Datenbank, die Tabellen mit Sammlungen von Zeilen und Spalten hat. Dieser wichtige und grundlegende Unterschied beeinflusst die Art und Weise, wie Sie Ihre Anwendungen gestalten und bauen.
In einem traditionellen relationalen Datenspeicher würden Sie Tabellen haben, in denen Sammlungen an Zeilen von Daten und Spalten von named types von Daten gespeichert wären. IndexedDB auf der anderen Seite erfordert es, dass Sie einen Objektspeicher für einen Datentyp erzeugen und einfach JavaScript-Objekte in diesem Speicher ablegen. Jeder Objektspeicher kann eine Sammlung an Indizes beinhalten, die es einfach machen zwischen ihnen zu suchen und zu iterieren. Wenn Sie nicht mit objektorientiertem Managementsystemen von Datenbanken vertraut sind, lesen Sie den Wikipedia-Artikel über Objektdatenbanken. -
IndexedDB verwendet keine Structured Query Language (SQL). Es verwendet Anfragen, die einen Positionsmarker erzeugen, den Sie verwenden um durch die Ergebnismenge zu iterieren. Wenn Sie nicht mit NoSQL-Systemen vertraut sind, lesen Sie den Wikipedia-Artikel zu NoSQL.
-
IndexedDB hält an einer Same-Origin-Policy fest. Eine Herkunft (origin) besteht aus der Domain, dem Anwendungsschichtenprotokoll und dem Port einer URL des Dokuments, auf dem das Skript ausgeführt wird. Jede Herkunft hat ihre eigene entsprechende Untermenge an Datenbanken. Jede Datenbank hat einen Namen, das sie innerhalb einer Herkunft identifiziert.
Die von IndexedDB auferlegte Sicherheitsbegrenzung hindert Anwendungen daran, auf Daten einer anderen Herkunft zuzugreifen. Während eine Anwendung oder eine Seite, die unter https://www.example.com/app/ liegt, Daten aus https://www.example.com/dir/ abrufen kann, weil sie die gleiche Herkunft haben, kann sie nicht Daten aus https://www.example.com:8080/dir/ (anderer Port) oder https://www.example.com/dir/ (anderes Protokoll) abrufen, weil sie verschiedene Herkünfte haben.
Definitionen
Dieser Abschitt definiert und erklärt Begriffe, die in der IndexedDB-API verwendet werden.
Datenbank
- Datenbank
-
Ein Aufbewahrungsort für Informationen, typischerweise bestehend aus einem oder mehreren Objektspeichern. Jede Datenbank muss folgende Angaben enthalten:
- Name. Er identifiziert die Datenbank innerhalb einer konkreten Herkunft und verändert sich nicht innerhalb seiner Lebenszeit. Der Name kann aus einem beliebigen String-Wert bestehen (einschließlich dem leeren String).
-
Aktuelle Version. Wenn eine Datenbank zum ersten Mal erstellt wird, nimmt ihre Version den integer-Wert 1 an, wenn nichts anderes angegeben wird. Jede Datenbank kann zu einem Zeitpunkt nur eine Version haben.
- Objektspeicher
-
Das Instrument, mit welchem Daten in einer Datenbank gespeichert werden. Der Objektspeicher hält Eintragungen aus Schlüssel-Wert-Paaren permanent. Eintragungen innerhalb eines Objektspeichers werden entsprechend der Schlüssel in aufsteigender Reihenfolge sortiert.
Jeder Objektspeicher muss einen Namen haben, der innerhalb seiner Datenbank einzigartig ist. Der Objektspeicher kann optional einen Schlüsselerzeuger und einen Schlüsselpfad besitzen. Wenn der Objektspeicher einen Schlüsselpfad hat, verwendet er in-line keys; ansonsten out-of-line keys.
Eine Referenzdokumentation zu Objektspeichern finden Sie unter IDBObjectStore oder IDBObjectStoreSync.
- Version
-
Wenn eine Datenbank zum ersten Mal erstellt wird, ist ihre Versionsnummer die integer-Zahl 1. Jede Datenbank hat zu jedem Zeitpunkt genau eine Versionsnummer; eine Datenbank kann nicht in verschiedenen Versionen gleichzeitig existieren. Die Versionsnummer kann nur geändert werden, indem die Datenbank mit einer größeren Versionsnummer geöffnet wird als mit der aktuellen. Das wird die Transaktion
versionchange
starten und einupgradeneeded
Ereignis auslösen. Die einzige Stelle, an der das Schema der Datenbank geupdatet werden kann, ist innerhalb des Handlers dieses Ereignisses.
-
Anmerkung: Diese Definition beschreibt die aktuellsten Spezifikationen, welche nur in Browsern auf dem neuesten Stand implementiert sind. In alten Browsern ist die mittlerweile veraltete und entfernte Methode
IDBDatabase.setVersion()
implementiert. - Datenbankverbindung
- Eine Operation, die beim Öffnen einer Datenbank erstellt wird. Eine vorgegebene Datenbank kann mehrere Verbindungen gleichzeitig haben.
- Transaktion
-
Eine nicht teilbare und dauerhafte Menge an Datenzugriffs- und Datenmodifikationsoperationen auf einer bestimmten Datenbank. Durch Transaktionen können Sie auf die Daten einer Datenbank zugreifen. Tatsächlich muss jeder Lese- oder Schreibvorgang von Daten in einer Transaktion stattfinden.
Eine Datenbankverbindung kann mit mehreren aktiven Transaktionen gleichzeitig verknüpft sein, so lange schreibende Transaktionen keine überlappenden scopes haben. The scope of transactions, which is defined at creation, determines which object stores the transaction can interact with and remains constant for the lifetime of the transaction. So, for example, if a database connection already has a writing transaction with a scope that just covers theflyingMonkey
object store, you can start a second transaction with a scope of theunicornCentaur
andunicornPegasus
object stores. As for reading transactions, you can have several of them—even overlapping ones.Transactions are expected to be short-lived, so the browser can terminate a transaction that takes too long, in order to free up storage resources that the long-running transaction has locked. You can abort the transaction, which rolls back the changes made to the database in the transaction. And you don't even have to wait for the transaction to start or be active to abort it.
The three modes of transactions are:
readwrite
,readonly
, andversionchange
. The only way to create and delete object stores and indexes is by using aversionchange
transaction. To learn more about transaction types, see the reference article for IndexedDB.Because everything happens within a transaction, it is a very important concept in IndexedDB. To learn more about transactions, especially on how they relate to versioning, see IDBTransaction, which also has reference documentation. For the documentation on the synchronous API, see IDBTransactionSync.
- Anfrage
- Die Operation, mit der Lese- und Schreibvorgänge auf einer Datenbank ausgeführt werden. Jede Anfrage repräsentiert eine Lese- oder Schreiboperation.
- Index
-
Ein Spezialobjektspeicher zum Nachschlagen von Einträgen eines anderen Objektspeichers, bezeichnet als referenzierter Objektspeicher. Der Index ist ein persistenter Schlüssel-Wert-Speicher, wobei der Wert seiner Einträge dem Schlüssel eines Eintrages im referenzierten Objektspeicher entspricht. Die Einträge in einem Index werden automatisch eingepflegt, sobald Einträge im referenzierten Objekt eingefügt, aktualisiert oder entfernt werden. Jeder Eintrag in einem Index kann auf nur einen Eintrag in seinem referenzierten Objektspeicher zeigen, aber mehrere Indizes können auf denselben Objektspeicher verweisen. Wenn der Objektspeicher sich ändert, werden alle Indizes, die auf ihn verweisen, automatisch aktualisiert.
Alternativ können Einträge eines Objektspeichers mithilfe eines Schlüssels nachgeschlagen werden.
Um mehr über die Verwendung von Indizes zu erfahren, lesen Sie Using IndexedDB. Die Referenzdokumentation zu Indizes finden Sie unter IDBKeyRange.
Schlüssel und Wert
- Schlüssel
-
Ein Datenwert über welchen abgelegte Werte aus dem Objektspeicher sortiert und ausgelesen werden können. Der Objektspeicher kann den Schlüssel aus einer dieser drei Quellen erlangen: Einem Schlüsselgenerator, einem Schlüsselpfad und einem explizit angegebem Wert. Der Schlüssel muss aus einem Datentyp bestehen, der eine Nummer hat, die größer ist als die des Schlüssel vor ihm. Jeder Eintrag in einem Objektspeicher muss einen innerhalb des gleichen Objektspeichers einzigartigen Schlüssel haben, deshalb können nicht mehrere Einträge mit demselben Schlüssel in einem vorgegebenem Objektspeicher vorliegen.
Ein Schlüssel kann einen der folgenden Typen haben: string, date, float und array. Bei Arrays kann der Schlüssel zwischen einem leeren Wert und unendlich liegen. Arrays können wiederum Arrays beinhalten. Es gibt keine Vorschrift nur Schlüssel der Typen string oder integer zu verwenden .Alternativ können Sie Einträge eines Objektspeichers auch mithilfe eines Index nachschlagen.
- Schlüsselgenerator
- Ein Mechanismus um neue Schlüssel in einer angeordneten Reihenfolge zu erzeugen. Wenn ein Objektspeicher über keinen Schlüsselgenerator verfügt, muss die Anwendung Schlüssel für zu speichernde Einträge zur Verfügung stellen. Generatoren werden nicht zwischen Speichern geteilt. Dies ist mehr ein Detail von Browserimplementierungen, da in der Webentwicklung nicht wirklich Schlüsselgeneratoren erzeugt oder auf sie zugegriffen wird.
- in-line key
- A key that is stored as part of the stored value. It is found using a key path. An in-line key can be generated using a generator. After the key has been generated, it can then be stored in the value using the key path or it can also be used as a key.
- out-of-line key
- A key that is stored separately from the value being stored.
- key path
- Defines where the browser should extract the key from a value in the object store or index. A valid key path can include one of the following: an empty string, a JavaScript identifier, or multiple JavaScript identifiers separated by periods. It cannot include spaces.
- value
-
Each record has a value, which could include anything that can be expressed in JavaScript, including: boolean, number, string, date, object, array, regexp, undefined, and null.
When an object or array is stored, the properties and values in that object or array can also be anything that is a valid value.
Blobs and files can be stored, cf. specification .
Range and scope
- scope
- The set of object stores and indexes to which a transaction applies. The scopes of read-only transactions can overlap and execute at the same time. On the other hand, the scopes of writing transactions cannot overlap. You can still start several transactions with the same scope at the same time, but they just queue up and execute one after another.
- cursor
- A mechanism for iterating over multiple records with a key range. The cursor has a source that indicates which index or object store it is iterating. It has a position within the range, and moves in a direction that is increasing or decreasing in the order of record keys. For the reference documentation on cursors, see IDBCursor or IDBCursorSync.
- key range
-
A continuous interval over some data type used for keys. Records can be retrieved from object stores and indexes using keys or a range of keys. You can limit or filter the range using lower and upper bounds. For example, you can iterate over all values of a key between x and y.
For the reference documentation on key range, see IDBKeyRange.
Limitations
IndexedDB is designed to cover most cases that need client-side storage. However, it is not designed for a few cases like the following:
- Internationalized sorting. Not all languages sort strings in the same way, so internationalized sorting is not supported. While the database can't store data in a specific internationalized order, you can sort the data that you've read out of the database yourself.
- Synchronizing. The API is not designed to take care of synchronizing with a server-side database. You have to write code that synchronizes a client-side indexedDB database with a server-side database.
- Full text searching. The API does not have an equivalent of the
LIKE
operator in SQL.
In addition, be aware that browsers can wipe out the database, such as in the following conditions:
- The user requests a wipe out.
Many browsers have settings that let users wipe all data stored for a given website, including cookies, bookmarks, stored passwords, and IndexedDB data. - The browser is in private browsing mode.
Some browsers, have "private browsing" (Firefox) or "incognito" (Chrome) modes. At the end of the session, the browser wipes out the database. - The disk or quota limit has been reached.
- The data is corrupt.
- An incompatible change is made to the feature.
The exact circumstances and browser capabilities change over time, but the general philosophy of the browser vendors is to make the best effort to keep the data when possible.
Warning: At the moment due to bugs or on purpose it's impossible to open an IndexedDB database from a Web App. This needs more investigation and then be documented.
Next step
OK, so, now with these big concepts under our belts, we can get to more concrete stuff. For a tutorial on how to use the API, see Using IndexedDB.
See also
Specification
Reference
Tutorials
- Using IndexedDB
- A simple TODO list using HTML5 IndexedDB. Hinweis: This example uses an old version of the spec and does not work on up-to-date browsers - it still uses the removed
setVersion()
method.
Related article