2011-09-13 19 views
5

Come gestite tutti i rapporti molti-a-molti in IndexedDB?IndexedDB e relazioni molti-a-molti

Ad esempio, supponiamo di avere un oggetto Blog per contenere un post di blog e un oggetto Tag per un tag/etichetta del post del blog. Uno Blog può avere molti Tag s e uno Tag può essere utilizzato da molti Blog s.

vorrei creare un blog store e tag store (anche se io sono aperto a suggerimenti) per ospitare i due tipi di oggetti:

// ... 
var blogStore = db.createObjectStore("blog", {keyPath: "blogId", autoIncrement: true}); 
blogStore.createIndex("title", "title", {unique: true}); 
var tagStore = db.createObjectStore("tag", {keyPath: "tagId", autoIncrement: true}); 
tagStore.createIndex("label", "label", {unique: true}); 

Fuori mano mi vengono in mente due modi per collegare i due:

  1. hanno un Blog.tags che sarebbe un array di BlogTag oggetti che detiene blogId e tagId (e sarebbe anche nel deposito per il recupero) o
  2. ha un Blog.tags che sarebbe un array di tagId s che potrebbe essere utilizzato per cercare il Tag s.

Il primo modo sembra più prolisso ma è come questo sarebbe affrontato in SQL. È solo un bagaglio di SQL che dovrei lasciare?

Suppongo che un terzo modo sarebbe avere Blog.tags un array di Tag s. Questo sembra il più semplice, ma non potrei richiedere il Tag s o riutilizzare i tag sui blog (o potrei?).

Qualcun altro ha gestito una situazione del genere con indexedDB? Se sì, cosa hai finito? Quali erano alcune insidie?

risposta

7

Sto lavorando a un IndexedDB-backed JS neural network implementation e ho affrontato questo problema molto .

Non abbiamo join in IndexedDB, quindi stai esaminando almeno due hit di archivio oggetti a meno che non stai facendo una sorta di memorizzazione/memorizzazione nella cache.

Per esperienza ho trovato che uno stile orientato ai documenti è il migliore con gli oggetti IndexedDB (memorizza tutto nello stesso negozio), ma è necessario un archivio secondario per ospitare le relazioni.

Ecco cosa sto facendo.

Dite che volete avere un negozio locale di attori e film - qualcosa come IMDB. Questa e la maggior parte delle relazioni molti-a-molti possono essere modellate con IndexedDB utilizzando due tabelle: Oggetti e relazioni.

Ecco le due tabelle. Vorresti cercare la chiave * su quasi tutto. Tutto ciò che non dice univoco può essere non unico.

oggetti oggetto negozio:

type_id* 
whatever*.. 

Rapporti negozio oggetto:

id* (unique, auto-incrementing) 
from_type* 
to_id* 

Un esempio attore/film sarebbe due record nella tabella Oggetti e uno nella tabella di relazione:

var actor1 = { 
    id: 'actor_jonah_goldberg', 
    display: 'Jonah Goldberg', 
}; 

var actor2 = { 
    id: 'actor_michael_cera', 
    display: 'Michael Cera' 
}; 

var movie1 = { 
    id: 'movie_superbad', 
    display: 'Superbad', 
    year: 2007 
}; 

var movie2 = { 
    id: 'movie_juno', 
    display: 'Juno', 
    year: 2007 
}; 

//relationship primary key ids are auto-inc 

var relationship1 = { 
    from_id: 'actor_jonah_goldberg', 
    to_id: 'movie_superbad' 
} 

var relationship2 = { 
    from_id: 'actor_michael_cera', 
    to_id: 'movie_superbad' 
} 

var relationship3 = { 
    from_id: 'actor_michael_cera', 
    to_id: 'movie_juno' 
} 

Psuedo-code per ottenere i film di Michael Cera:

IndexedDBApp({ 'store': 'relationships', 'index': 'from_id', 'key': 'actor_michael_cera', 'on_success': function(row) {...}); 
// Would return movie_superbad and movie_juno rows on_success 

pseudo-codice per ottenere tutti i filmati da un determinato anno:

IndexedDBApp({ 'store': 'objects', 'index': 'year', 'key': 2007, 'on_success': function(row) {...}); 
// Would return movie_superbad and movie_juno rows on_success 

pseudo-codice per ottenere gli attori di un film:

IndexedDBApp({ 'store': 'relationships', 'index': 'to_id', 'key': 'movie_superbad', 'on_success': function(row) {...}); 
// Would return actor_jonah_goldberg and actor_michael_cera on_success 

pseudo-codice per ottenere tutti gli attori:

IndexedDBApp({ 'store': 'relationships', 'index': 'id', 'cursor_begin': 'actor_a', 'cursor_end': 'actor_z', 'on_success': function(row) {...}); 
// Would return actor_jonah_goldberg and actor_michael_cera on_success 
Problemi correlati