Start · Sprachen · JavaScript · Referenz · IDBIndex.unique

IDBIndex.unique

Eigenschaft

Schreibgeschützte Eigenschaft, die als <code>boolean</code> angibt, ob ein IndexedDB-Index eindeutige Schlüssel erzwingt, also keine Duplikate zulässt.

seit JavaScript Baseline: alle modernen Browser (IndexedDB 1.0) Kategorie: webapi

Signatur

IDBIndex.unique

Beschreibung

Die Eigenschaft unique eines IDBIndex-Objekts sagt, ob der Index beim Anlegen mit der Option { unique: true } erstellt wurde. Ist der Wert true, dürfen zwei Datensätze im zugehörigen Object Store für den indizierten Schlüsselpfad nicht denselben Wert haben. Ist er false (Standard), sind doppelte Indexschlüssel erlaubt.

Den Wert legt man einmalig über IDBObjectStore.prototype.createIndex(name, keyPath, { unique }) fest. Das geht nur innerhalb eines upgradeneeded-Handlers, also in einer versionchange-Transaktion. Danach lässt er sich nicht mehr ändern. Soll sich die Eindeutigkeit ändern, musst du den Index mit deleteIndex() löschen und in einer neuen Datenbankversion neu anlegen.

Praktisch hilft unique vor allem beim Prüfen des Schemas zur Laufzeit, bei Migrationen und beim Debuggen. So erkennst du etwa, ob ein E-Mail-Index wirklich eindeutig ist. Ist das der Fall, schlägt ein add() oder put() mit einem doppelten Wert mit einem ConstraintError fehl.

Rückgabewert

Typ
boolean
Beschreibung
true, wenn der Index keine doppelten Schlüssel zulässt, sonst false.

Beispiele

Eindeutigen Index anlegen und prüfen

const request = indexedDB.open('shop', 1);

request.onupgradeneeded = (event) => {
  const db = event.target.result;
  const store = db.createObjectStore('kunden', { keyPath: 'id', autoIncrement: true });
  const emailIndex = store.createIndex('email', 'email', { unique: true });
  const stadtIndex = store.createIndex('stadt', 'stadt'); // unique: false (Standard)

  console.log(emailIndex.unique);
  console.log(stadtIndex.unique);
};
true false

Schema aller Indizes zur Laufzeit ausgeben

const openDb = (name) => new Promise((resolve, reject) => {
  const req = indexedDB.open(name);
  req.onsuccess = () => resolve(req.result);
  req.onerror = () => reject(req.error);
});

const db = await openDb('shop');
const store = db.transaction('kunden', 'readonly').objectStore('kunden');

for (const name of store.indexNames) {
  const index = store.index(name);
  console.log(`${index.name}: keyPath=${index.keyPath}, unique=${index.unique}`);
}
email: keyPath=email, unique=true stadt: keyPath=stadt, unique=false

ConstraintError bei eindeutigem Index abfangen

const addKunde = (db, kunde) => new Promise((resolve, reject) => {
  const tx = db.transaction('kunden', 'readwrite');
  const store = tx.objectStore('kunden');
  const req = store.add(kunde);
  req.onsuccess = () => resolve(req.result);
  req.onerror = (event) => {
    event.preventDefault(); // verhindert Abbruch der Transaktion
    const unique = store.index('email').unique;
    reject(new Error(`${req.error.name} (email unique=${unique})`));
  };
});

try {
  await addKunde(db, { email: 'anna@example.com', stadt: 'Berlin' });
  await addKunde(db, { email: 'anna@example.com', stadt: 'Hamburg' });
} catch (err) {
  console.log(err.message);
}
ConstraintError (email unique=true)

// Wichtig · Fallstricke

  • Nur lesbar: Eine Zuweisung wie index.unique = true hat keine Wirkung und wirft im Strict Mode einen TypeError. Ändern lässt sich die Eindeutigkeit nur, indem du den Index in einem upgradeneeded-Handler löschst und neu anlegst.
  • Bestehende Duplikate: Enthält der Object Store beim Anlegen eines eindeutigen Index schon doppelte Werte, schlägt createIndex() fehl. Die Upgrade-Transaktion wird dann mit einem ConstraintError abgebrochen.
  • Zusammen mit multiEntry: Bei multiEntry: true gilt die Eindeutigkeit für jedes einzelne Array-Element über alle Datensätze hinweg. Doppelte Werte innerhalb desselben Arrays werden nur einmal indiziert.
  • Datensätze, bei denen der Schlüsselpfad fehlt oder keinen gültigen Schlüssel ergibt, kommen gar nicht in den Index und verletzen die Eindeutigkeit deshalb nicht.
  • Kompatibilität: Wird in allen modernen Browsern und in Web Workern unterstützt. In privaten Fenstern mancher Browser ist IndexedDB eingeschränkt.