2010-10-19 12 views
41

Sto avviando lo sviluppo di un'app Web con requisiti di archiviazione del database offline. Per farla breve, l'applicazione dovrebbe essere in grado di funzionare su:HTML5 IndexedDB, Database Web SQL e guerre browser

  • Uno dei principali browser desktop, Chrome ha preferito
  • Safari su iOS
  • del browser nativo di Android (basato sul V8 e WebKit)

Quindi la domanda è quale tecnologia scegliere: IndexedDB o Database SQL Web?

Per quanto riguarda il database SQL Web, da un lato, è pronto per essere utilizzato in uno qualsiasi degli scenari di cui sopra. D'altra parte, Mozilla ha dichiarato Firefox non sarà mai la sua attuazione, e di tronchi con l'HTML5 working draft la specifica ha raggiunto un vicolo cieco:

Questa specifica ha raggiunto un punto morto: tutti gli implementatori interessati hanno usato il backend stesso SQL (SQLite), ma abbiamo bisogno di più implementazioni indipendenti per procedere lungo un percorso di standardizzazione. Fino a quando un altro implementatore non è interessato a implementare questa specifica, la descrizione del dialetto SQL è stata lasciata semplicemente come riferimento a Sqlite, che non è accettabile per uno standard. Se sei un implementatore interessato all'implementazione di un back-end SQL indipendente, contatta l'editor in modo che possa scrivere una specifica per il dialetto, consentendo così a questa specifica di andare avanti.

IndexedDB è l'alternativa raccomandata da Mozilla, ma verrà solo in Firefox 4. Microsoft è interessata e Chrome lo supporterà. Non conosco nulla dei piani di Apple riguardanti IndexedDB.

Personalmente sono incline a scegliere il Database SQL Web, ma solo perché sono abituato a SQLite, mi piace la potenza e l'espressività di SQL e capisco il modello relazionale. IndexedDB, per me, è un'incertezza.

Detto questo, ho paura di scommettere sul cavallo sbagliato. È sicuro che il supporto per il database SQL Web continuerà a esistere, anche se IndexedDB diventa lo standard?

(Una nota su CouchDB:? Si vede anche come alternativa)

risposta

13

Considerando solo WebSQL supporta tutti e tre i requisiti che hai elencato, non dovrebbe essere la vostra scelta semplice? Non hai informazioni dettagliate sulla roadmap di sviluppo per Safari o Android, quindi utilizza ciò che hai a disposizione.

+3

Sì, il problema sta nel rischio che prenderò. Alla fine, WebSQL verrà abbandonato? È una questione di tempo fino a quando non viene abbandonato, o posso tranquillamente supporre che rimarrà supportato anche se forse non nello sviluppo di funzionalità attive? C'è qualche informazione che non sto considerando che mi permetterebbe di fare una scelta più consapevole? Grazie. – ivo

+3

Non ci sono stati realmente piani concreti per il supporto a lungo termine di Web SQL o IndexedDB. Se vuoi veramente mitigare il rischio, puoi sempre bypassare le alternative SQL e utilizzare una libreria di serializzazione JSON per archiviare le cose in HTML5 localStorage o sessionStorage. – codelark

+2

Appena scoperto che webSQL (e localStorage) non è più persistente in iOS 5.0.1. La posizione in cui sono memorizzati i dati webSQL viene ora regolarmente pulita dal sistema operativo. Se utilizzi Phonegap/Cordova, è in corso lo sviluppo di una soluzione alternativa al plugin. https://issues.apache.org/jira/browse/CB-330 – Wytze

6

Il database ha bisogno di molto oltre gli archivi chiave/valore? In caso contrario, ho trovato un numero di pacchetti javascript per l'astrazione del database basata su browser locale. Uno di questi pacchetti è jStore:

http://code.google.com/p/jquery-jstore/

Recentemente ho usato per aggiungere storage chiave/valore locale. È ben documentato e il tempo di integrazione è trascurabile: supporta una serie di back-end di archiviazione, tra cui l'archiviazione locale flash, tramite la sua API.

CouchDB è una soluzione eccellente - per un problema che non è del tutto congruo con il tuo. Controlla couchone mobile. Non per le "applicazioni web" in senso stretto, ma potrebbe fornire una base di dati del database con cui potresti essere eseguito, se hai una certa flessibilità con le specifiche.

23

Bene, come con tutte le cose informatiche, il gioco è "astrazione".

Se è possibile creare un livello adeguato che funzioni sia su un archivio SQL sia su un archivio di chiavi/valori, idealmente si è isolati dal problema e si può supportare l'implementazione appropriata sul browser specifico. Se il modello di dati e i modelli di accesso non si adattano al minimo comune denominatore (ad esempio un negozio di k/v), allora questo risolve praticamente il problema proprio lì.

Se è possibile utilizzare entrambi gli store, lavorare su un livello di accesso decente e affrontare il problema da quella direzione.

Attenzione, solo perché hai un archivio k/v sul back-end non significa che devi modellare i dati come solo un modello k/v. Essenzialmente tutto un DB è sul backend è un archivio k/v. Se non hai una quantità folle di dati, puoi fare molte cose. Con una grande quantità di dati, i cerchi che potresti dover saltare potrebbero costarti in prestazioni che potresti non vedere con una quantità minore di dati. Tutto dipende

5

Con il tuo requisito di Safari su iOS, non ci sono alternative, ma WebSQL. WebSQL è supportato in altri browser mobili come Opera e Blackberry. Non penso che rimuoveranno il supporto WebSQL anche se hanno IndexedDB. In qualche modo sono complementari.

D'altra parte, nella guerra di archiviazione del browser, IndexedDB vince per sempre. IE e FF avranno solo IndexedDB. Il fatto ironico è che FF implementa IndexedDB su Sqlite.

Quello che vorrei dire è IndexedDB è più di un semplice archivio di valori. Ha indice e transazione. Questi due soli fanno quasi tutte le funzionalità della query SQL incluso join, condizionale e ordinamento. All'inizio non è ovvio a causa della sua API asincrona.

Le prestazioni di IndexedDB sono migliori di WebSQL. È più sicuro È più flessibile per il caso d'uso javascript. Infine è più facile da usare.

Per illustrare il caso, userò il codice sudo da my library, ma è possibile utilizzare IndexedDB API direttamente:

Il negozio '' ne ha campo indice 'nome' e la lista campo indicizzato 'il mio hobby'. In JSON,

people = { 
    name: 'Foo Bar', 
    email: '[email protected]' 
    hobby: ['camping', 'swimming']}; 

Per recuperare il nome da "persone" il cui hobby è "campeggio".

var req = db.keys('people', 'hobby', IDBKeyRange.only('camping')); 
req.done(function(campers) { 
    db.keys('people', campers, 'name').done(function(names) { 
    console.log(names); 
    }); 
}); 

La cosa interessante di questo codice è che non è prevista alcuna serializzazione. Quindi è molto veloce.

L'esempio seguente illustra la query del grafico di amicizia. L'archivio oggetti friendship ha un solo campo indicizzato elencato friend_list. Utilizza la chiave dell'archivio oggetti della gente come chiave primaria fuori linea. L'archivio oggetti people ha molti attributi, tra cui il campo location. La query è di trovare l'elenco di amici che conoscono me e other_guy e si trova a 'Singapore'.

var q1 = new ydn.db.Iterator('friendship', 'friend_list', IDBKeyRange.only(me)); 
var q2 = new dn.db.Iterator('friendship', 'friend_list', IDBKeyRange.only(other_guy)); 
// if location is not indexed, a filtered value query is used. 
var q3 = new ydn.db.Iterator('people', new ydn.db.Expression(['"location"', "'Singapore'", '='])); 
// if location is indexed, an index query is used. 
// var q3 = new ydn.db.Iterator('people', 'location', IDBKeyRange.only('Singapore')); 
var current_loop = 2; // start from inner loop 
var join_algo = function(keys, index_keys) { 
    var advancement = []; 
    advancement[keys.length - 1] = null; 
    var has_adv = false; 
    for (var i = 0; i < keys.length; i++) { 
    if (!goog.isDef(keys[i])) { 
     // completed iterator 
     if (i != 0) { 
     advancement[i] = false; // request to restart the iteration 
     advancement[i - 1] = true; // advance outer iterator 
     current_loop = i - 1; 
     } // i == 0 means we are done. 
    has_adv = true; 
    break; 
    } 
    } 
    if (!has_adv) { 
    // continue looping current 
    advancement[current_loop] = true; 
    } 
    return advancement; 
} 
var result = db.scan([q3, q1, q2], join_algo); 
result.done(function(keys, index_keys, values) { 
    console.log(values); // should get desire list of friends 
}); 

Ancora una volta questa query di join è solo la scansione delle chiavi e quindi molto veloce. Per impostazione predefinita, l'scan utilizza l'algoritmo di unione ordinata per trovare le chiavi corrispondenti, ma qui mostra un algoritmo di join nested-loop ingenuo. Quindi è possibile unire le tabelle, ma devi codificare l'algoritmo di join.Ma gli algoritmi più recenti come l'unione a zigzag sono più veloci di quelli possibili con Sqlite perché tutti gli input sono ordinati, i cursori possono avanzare bene e, soprattutto, il processo di join può sfruttare la conoscenza esterna che non è presente nel database. Con SQL, l'operazione di join è opaca.

Oltre a IndexedDB possono essere utilizzate tecniche come lo streaming e l'elaborazione di mappe/riduzioni.

5

Il mio consiglio è di andare per IndexDB, perché è disponibile un IndexDB Polyfill.

Tutti i browser che supportano WebSQL possono supportare lo IndexDB API in questo modo. Il contrario potrebbe essere molto difficile da implementare, quindi se vuoi raggiungere tutti i browser che conoscono alcune API DB, IndexDB è la scelta migliore oggi.


Nota: Anche se questa domanda è obsoleta, è ancora pertinente, quindi penso che le risposte a questa domanda meritino un aggiornamento. E mi dispiace per la soluzione di solo collegamento, quindi ho aggiunto solo collegamenti a destinazioni solitamente di lunga durata: W3C e GitHub

4

Rispondo a questo nel 2016 (5 anni dopo aver posto questa domanda) e tutto ciò che riguarda lo deprecation of WebSQL still stands. IndexedDB d'altra parte, enjoys the support of all of the major browser vendors.

Quindi, per chiunque possa trovarsi qui di fronte alla stessa decisione da prendere, andare con IndexedDB.

Come suggerito da altri qui, tuttavia, tale decisione non è necessariamente da prendere; si può semplicemente scegliere (o creare) una libreria che utilizza qualsiasi database disponibile su un computer client.

BakedGoods differisce da tali librerie già suggerite qui in vari modi; in modo più pertinente, consente al tipo di memorizzazione che deve essere utilizzato di essere specificato esplicitamente, consentendo a sua volta allo sviluppatore di introdurre altri fattori (come le caratteristiche di prestazione) nel processo decisionale.

Con esso, lo svolgimento di operazioni di stoccaggio in qualsiasi dei tipi di database è supportato è una questione di ...

... specificando le opzioni appropriate di funzionamento e configurazioni equivalenti per entrambi i tipi di database:

//If the operation is a set(), and the referenced structures 
//don't exist, they will be created automatically. 

var webSQLOptionsObj = { 
    databaseName: "Example_DB", 
    databaseDisplayName: "Example DB", 
    databaseVersion: "", 
    estimatedDatabaseSize: 1024 * 1024, 
    tableData: { 
     name: "Main", 
     keyColumnName: "lastName", 
     columnDefinitions: "(lastName TEXT PRIMARY KEY, firstName TEXT)" 
    }, 
    tableIndexDataArray: [name: "First_Name_Index", columnNames: "(firstName)"] 
}; 

var indexedDBOptionsObj = { 
    databaseName: "Example_DB", 
    databaseVersion: 1, 
    objectStoreData: { 
     name: "Main", 
     keyPath: lastName, 
     autoIncrement: false 
    }, 
    objectStoreIndexDataArray: [ 
     {name: "First_Name_Index", keyPath: "firstName", unique: false, multiEntry: false} 
    ], 
}; 

var optionsObj = { 
    conductDisjointly: false, 
    webSQL: webSQLOptionsObj, 
    indexedDB: indexedDBOptionsObj 
}; 

... e condurre l'operazione:

bakedGoods.set({ 
    data: [ 
     {value: {lastName: "Obama", firstName: "Barack"}}, 
     {value: {lastName: "Biden", firstName: "Joe"}} 
    ], 
    storageTypes: ["indexedDB", "webSQL"], 
    options: optionsObj, 
    complete: function(byStorageTypeStoredItemRangeDataObj, byStorageTypeErrorObj){} 
}); 

la sua semplice interfaccia e il supporto impianto di stoccaggio senza pari arriva a costo della mancanza di suppor t per alcune configurazioni specifiche della struttura di archiviazione. Ad esempio, non supporta la conduzione delle operazioni di archiviazione nelle tabelle WebSQL con chiavi primarie a più colonne.

Quindi, se si fa un uso intenso di questi tipi di funzionalità, si potrebbe voler guardare altrove.

Oh, e per garantire la massima trasparenza, BakedGoods è gestito da chi è veramente :).