HTML5 IndexedDB, base de données SQL Web et guerres de navigateur

je commence le développement d'une application web avec des exigences de stockage de base de données hors ligne. Pour faire court, l'application devrait pouvoir fonctionner sur:

  • Un des plus grands navigateurs de bureau, Chrome préféré
  • Safari on iOS
  • navigateur natif Android (basé sur V8 et WebKit)

la question est donc de savoir quelle technologie choisir: IndexedDB ou web SQL Database?

en ce qui concerne la base de données Web SQL, d'une part, il est prêt à être utilisé dans l'un des scénarios ci-dessus. D'autre part, Mozilla a déclaré que Firefox ne le mettra jamais en œuvre, et selon le HTML5 working draft la spécification a atteint une impasse:

cette spécification a atteint une impasse: tous les implémenteurs intéressés ont utilisé le même backend SQLite, mais nous avons besoin de plusieurs implémentations indépendantes pour procéder le long d'un chemin de la normalisation. Jusqu'à ce qu'un autre implementor soit intéressé à mettre en œuvre cette spécification, la description du dialecte SQL a été laissée comme une simple référence à Sqlite, ce qui n'est pas acceptable pour un standard. Si vous êtes un implementor intéressé par la mise en œuvre d'un backend SQL indépendant, veuillez contacter l'éditeur afin qu'il puisse écrire une spécification pour le dialecte, permettant ainsi à cette spécification d'aller de l'avant.

IndexedDB est le alternative prônée par Mozilla, mais elle ne sera disponible qu'en Firefox 4. Microsoft est intéressé et Chrome le supportera aussi. Je ne sais rien des plans D'Apple concernant IndexedDB.

je suis personnellement enclin à choisir la base de données Web SQL, mais juste parce que je suis habitué à SQLite, j'aime la puissance et l'expressivité de SQL, et je comprends le modèle relationnel. IndexedDB, pour moi, est une incertitude.

cela dit, j'ai peur de parier sur le mauvais cheval. Est-il sûr de supposer que le support de la base de données SQL web continuera d'exister, même si IndexedDB devient la norme?

(une note sur CouchDB: la voyez-vous aussi comme une alternative?)

42
demandé sur Makoto 2010-10-19 23:10:41

6 réponses

considérant que seul WebSQL prend en charge les trois exigences que vous avez énumérées, votre choix ne devrait-il pas être simple? Vous n'avez aucun aperçu de la feuille de route de développement pour Safari ou Android, donc utilisez ce que vous avez disponible.

14
répondu codelark 2010-10-19 20:31:44

Eh bien, comme avec tout ce qui est Informatique, le jeu est "abstraction".

si vous pouvez trouver une couche adéquate qui fonctionne à la fois sur un SQL store et un key/value store, alors, idéalement, vous êtes isolé du problème et pouvez soutenir la mise en œuvre appropriée sur le navigateur particulier. Si votre modèle de données et les modèles d'accès ne correspondent pas au plus petit dénominateur commun (c.-à-d. un magasin k/v), alors cela résout assez bien votre problème juste là.

si vous pouvez utiliser l'un ou l'autre magasin, puis travailler sur une couche d'accès décent et aborder le problème de cette direction.

esprit, juste parce que vous avez un magasin k/v sur le dos ne signifie pas que vous devez modéliser vos données comme un modèle k/v. Essentiellement tout un DB est sur le dos est un magasin k / v. Si vous n'avez pas une quantité folle de données, vous pouvez faire beaucoup de choses. Avec une grande quantité de données les cerceaux que vous pourriez avoir à passer peut vous coûter dans la performance que vous peut ne pas voir avec une plus petite quantité de données. Tout dépend de la situation.

23
répondu Will Hartung 2010-10-28 01:57:08

vos besoins de base de données sont-ils bien au-delà des magasins de clés/de valeurs? Si ce n'est pas le cas, j'ai trouvé un certain nombre de paquets javascript pour l'abstraction de base de données locale basée sur le navigateur. Un de ces paquets est jStore:

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

Je l'ai récemment utilisé pour ajouter stockage local clé/valeur. C'est bien documenté et le temps d'intégration était négligeable -- il supporte un tableau de sauvegardes de stockage, y compris flash local de stockage, via son API.

CouchDB est une excellente solution -- pour un problème qui n'est pas tout à fait compatible avec le vôtre. Découvrez couchone mobile . Pas seulement pour les "applications web", mais il peut fournir une base de données que vous pourriez exécuter, si vous avez une certaine flexibilité avec la spécification.

6
répondu fish2000 2010-10-28 00:53:48

avec votre exigence donnée de Safari sur iOS, il n'y a pas d'autre alternative que WebSQL. WebSQL est pris en charge dans D'autres navigateurs mobiles comme Opera et Blackberry. Je ne pense pas qu'ils supprimeront le support WebSQL même S'ils ont IndexedDB. En quelque sorte, ils sont complémentaires.

d'autre part, sur la guerre de stockage de navigateur, IndexedDB gagner pour de bon. IE et FF n'auront que IndexedDB. Le fait ironique est que FF implémente IndexedDB sur Sqlite.

ce que je voudrais dire C'est que IndexedDB est plus qu'un simple stock de valeurs clés. Il a index et transaction. Ces deux seules font presque toutes les fonctionnalités de la requête SQL incluant join, conditional et tri. Elle n'est pas évidente au début à cause de son API asynchrone.

la Performance de IndexedDB est meilleure que WebSQL. C'est plus sécurisé. Il est plus flexible pour javascript use case. Enfin, il est plus facile à utiliser.

pour illustrer l'affaire, J'utiliserai le code sudo de Ma bibliothèque , mais vous pouvez utiliser L'API IndexedDB directement:

le magasin' people 'a un champ index' name 'et un champ indexé'hobby'. Dans JSON,

people = {
  name: 'Foo Bar',
  email: 'foo@bar.com'
  hobby: ['camping', 'swimming']};

pour récupérer le nom des "gens" dont le Passe-temps 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.

le l'exemple suivant illustre la requête de graphique d'amitié. Le magasin d'objets friendship n'a qu'un seul champ indexé friend_list . Il utilise la clé people object store comme clé primaire hors ligne. people object store possède de nombreux attributs, dont le champ location . La requête est de trouver la liste des amis qui savent me et other_guy et situé dans '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 
});

encore une fois cette requête de jointure n'est qu'un balayage de clé et donc très rapide. Par défaut scan utilise l'algorithme de tri-Fusion pour trouver les clés correspondantes, mais ici montre naïve nested-loop join algorithm. Ainsi, l'adhésion à une table est possible, mais vous devez coder l'algorithme d'adhésion. Mais les nouveaux algorithmes comme la fusion zigzag sont plus rapides que possible avec Sqlite parce que toutes les entrées sont triées, les curseurs peuvent bien avancer et surtout le processus de jointure peut exploiter des connaissances externes qui ne sont pas dans la base de données. Avec SQL, l'opération de jointure est opaque.

autres que ceux Indexésbd peut être utilisé des techniques comme le streaming et la carte/réduire le traitement.

5
répondu Kyaw Tun 2012-11-11 04:24:36

ma recommandation est de aller pour IndexDB , parce qu'il ya un IndexDB Polyfill disponible.

tous les navigateurs prenant en charge WebSQL peuvent prendre en charge L'API IndexDB de cette façon. L'inverse serait très difficile à mettre en œuvre, donc si vous voulez atteindre tous les navigateurs qui connaissent une API DB, IndexDB est le meilleur choix aujourd'hui.


Note: même si cette question Est ancienne, elle est toujours pertinente, donc je pense que les réponses à cette question méritent une mise à jour. Et désolé pour la solution de lien seulement, donc j'ai ajouté seulement des liens vers des destinations habituellement de longue durée: W3C et GitHub

5
répondu Tino 2013-08-09 10:36:07

je réponds à cela en 2016 (5 ans après que vous avez posé cette question) et tout ce qui concerne la dépréciation de WebSQL est toujours . IndexedDB d'autre part, bénéficie du soutien de tous les principaux fournisseurs de navigateur .

donc, pour quiconque peut se trouver ici face à la même décision à prendre, allez avec IndexedDB.

comme d'autres l'ont laissé entendre ici, cependant, une telle décision n'est pas une qui doit nécessairement être faite; on peut simplement choisir (ou faire) une bibliothèque qui utilise n'importe quelle base de données disponible sur une machine client.

BakedGoods diffère de ces bibliothèques déjà suggérées ici de plusieurs façons; le plus pertinent, il permet le type de stockage qui doit être utilisé pour être explicitement spécifié, à son tour permettant au développeur d'introduire d'autres facteurs(tels que les caractéristiques de performance) dans le processus de prise de décision.

avec cela, la conduite des opérations de stockage dans n'importe lequel des types de base de données est une question de...

... spécifiant les options d'exploitation appropriées et les configurations équivalentes pour les deux types de bases de données:

//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
};

... et la conduite de l'opération:

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

son interface simple et le soutien d'installation de stockage inégalée vient au coût de manque de soutien pour certaines configurations spécifiques à l'installation de stockage. Par exemple, il ne supporte pas la conduction des opérations de stockage dans les tables WebSQL avec des touches primaires à plusieurs colonnes.

donc si vous faites un usage intensif de ces types de fonctionnalités, vous pouvez vouloir regarder ailleurs.

Oh, et par souci de totale transparence, BakedGoods est maintenu par votre serviteur :) .

4
répondu Kevin 2016-07-08 23:00:09