Avec votre exigence de Safari sur iOS, il n'y a pas d'autre alternative que WebSQL. WebSQL est supporté par d'autres navigateurs mobiles comme Opera et Blackberry. Je ne pense pas qu'ils vont supprimer le support de WebSQL même s'ils ont IndexedDB. D'une certaine manière, ils sont complémentaires.
D'autre part, dans la guerre du stockage des navigateurs, IndexedDB a gagné pour de bon. IE et FF ne disposeront que d'IndexedDB. Un fait ironique est que FF implémente IndexedDB au-dessus de Sqlite.
Ce que je voudrais dire, c'est que IndexedDB est plus qu'un simple magasin de clés et de valeurs. Elle possède des index et des transactions. Ces deux éléments à eux seuls fournissent presque toutes les fonctionnalités des requêtes SQL, y compris la jointure, la conditionnalité et le tri. Ce n'est pas évident au début à cause de son API asynchrone.
Les performances d'IndexedDB sont meilleures que celles de WebSQL. Il est plus sûr. Il est plus flexible pour les cas d'utilisation de javascript. Enfin, il est plus facile à utiliser.
Pour illustrer le cas, je vais utiliser un pseudo code tiré de ma bibliothèque mais vous pouvez utiliser directement l'API IndexedDB :
Le magasin "people" possède un champ d'indexation "name" et un champ d'indexation de liste "hobby". En JSON,
people = {
name: 'Foo Bar',
email: 'foo@bar.com'
hobby: ['camping', 'swimming']
};
Récupérer le nom des "personnes" dont le hobby est le "camping".
var req = db.keys('people', 'hobby', IDBKeyRange.only('camping'));
req.done(function(campers) {
db.keys('people', campers, 'name').done(function(names) {
console.log(names);
});
});
Ce qui est intéressant dans ce code, c'est qu'il n'y a pas de sérialisation. Il est donc très rapide.
L'exemple suivant illustre une requête de graphique d'amitié. friendship
le magasin d'objets n'a qu'un seul champ indexé répertorié friend_list
. Il utilise la clé du magasin d'objets des personnes comme clé primaire hors ligne. people
Le magasin d'objets possède de nombreux attributs, parmi lesquels location
champ. La requête est de trouver une liste d'amis qui connaissent me
y other_guy
et situé à "Singapour".
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
});
Encore une fois, cette requête jointe n'est qu'un balayage de clés et est donc très rapide. Par défaut scan
utilisent un algorithme de fusion triée pour trouver les clés correspondantes, mais ici, il s'agit d'un algorithme de jointure naïf en boucle imbriquée. La jonction de tables est donc possible, mais vous devez coder l'algorithme de jonction. Mais les algorithmes plus récents comme la fusion en zigzag sont plus rapides qu'avec Sqlite car toutes les entrées sont triées, les curseurs peuvent également avancer et, plus important encore, le processus de jointure peut exploiter des connaissances externes qui ne se trouvent pas dans la base de données. Avec SQL, l'opération de jointure est opaque.
En outre, IndexedDB peut être utilisé pour des techniques comme le streaming et le traitement map/reduce.