Question

Je commence le développement d'une application Web avec des exigences de stockage de base de données hors ligne. Longue histoire courte, l'application devrait être en mesure de fonctionner sur:

  • L'un des principaux navigateurs de bureau, Chrome préféré
  • Safari sur iOS
  • navigateur natif d'Android (basé sur WebKit et V8)

La question est donc la technologie à choisir: ou IndexedDB Web base de données SQL

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

  

Cette spécification a abouti à une impasse: tous les intéressés ont utilisé implementors le même backend SQL (SQLite), mais nous avons besoin de plusieurs implémentations indépendantes pour continuer sur une voie de normalisation. Jusqu'à ce qu'un autre est intéressé implementor mise en œuvre de cette spécification, la description du dialecte SQL a été laissé comme une simple référence à SQLite, ce qui est acceptable pour une norme. Si vous êtes un implementor intéressé à mettre en œuvre un backend SQL indépendant, s'il vous plaît contacter l'éditeur pour qu'il puisse écrire une spécification pour le dialecte, permettant ainsi cette spécification pour aller de l'avant.

IndexedDB est l'alternative préconisée par Mozilla, mais il ne se concrétisera que dans Firefox 4. Microsoft est intéressé et Chrome soutiendra aussi. Je ne sais rien des plans d'Apple concernant IndexedDB.

Je suis personnellement enclin à choisir base de données SQL Web, mais juste parce que je suis habitué à SQLite, je aime le pouvoir 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 d'assumer le soutien pour le Web SQL Database continuera d'exister, même si IndexedDB devient la norme?

(Une note sur CouchDB: voyez-vous aussi comme alternative)

Était-ce utile?

La solution

Étant donné que websql prend en charge les trois exigences que vous avez énumérées, ne devrait pas être votre choix simple? Vous avez pas idée de la feuille de route de développement pour Safari ou Android, utilisez donc ce que vous avez disponible.

Autres conseils

Eh bien, comme avec toutes les choses de calcul, le jeu est "abstraction".

Si vous pouvez venir avec une couche adéquate qui fonctionne aussi bien sur un magasin SQL et un magasin clé / valeur, puis, idéalement vous êtes isolés du problème et peut prendre en charge la mise en œuvre appropriée du navigateur particulier. Si vos habitudes de modèle de données et d'accès ne correspondent pas au plus petit dénominateur commun (à savoir k / magasin v), alors que à peu près résout votre problème là.

Si vous pouvez utiliser 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 à l'extrémité arrière ne signifie pas que vous devez modéliser vos données seulement un modèle k / v. Essentiellement tout un DB est sur le back-end est un magasin k / v. Si vous ne disposez pas d'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 à sauter à travers peut vous coûter cher en performances que vous pouvez bien voir pas avec une plus petite quantité de données. Tout dépend.

Vos besoins de base de données qui dépassent largement les magasins clé / valeur? Sinon, je l'ai trouvé un certain nombre de paquets javascript pour l'abstraction de base de données basée sur un navigateur local. Un tel paquet est jStore:

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

J'ai récemment utilisé pour ajouter du stockage clé locale / valeur. Il est bien documenté et le temps d'intégration est négligeable -. Il prend en charge une gamme de backends de stockage, y compris le stockage local flash, grâce à son API

CouchDB est une excellente solution - pour un problème qui est pas tout à fait en harmonie avec le vôtre. Consultez couchone mobile. Pas strictement 'applications Web, mais il peut fournir une base de données que vous pouvez exécuter avec, si vous avez une certaine souplesse à la spécification.

Ma recommandation est de aller pour IndexDB , parce qu'il ya une IndexDB Polyfill disponible.

Tous les navigateurs supportant websql peut prendre en charge l'API IndexDB 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 que cette question est vieux, il est toujours pertinent, donc je pense que les réponses à cette question mérite une mise à jour. Et désolé pour la solution de liaison seule, donc j'ajouté que des liens vers des destinations plus souvent de longue durée: le W3C et GitHub

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 vont retirer le soutien websql même si elles ont IndexedDB. D'une certaine façon, ils sont complémentaires.

D'autre part, la guerre de stockage du navigateur, IndexedDB gagner pour le bien. IE et FF n'auront IndexedDB. Ironique fait est que FF implémente IndexedDB au-dessus de SQLite.

Ce que je voudrais dire est IndexedDB est plus que magasin juste valeur clé. Il a l'index et de transaction. Ces deux seulement font la quasi-totalité de la requête SQL fonction, y compris joindre, conditionnelle et le tri. Il n'est pas évident au premier abord en raison de son API asynchrone.

Performance de IndexedDB est mieux que websql. Il est plus sûr. Il est plus souple pour les cas d'utilisation de javascript. Enfin, il est plus facile à utiliser.

Pour illustrer le cas, je vais utiliser le code de ma bibliothèque , mais vous pouvez utiliser API IndexedDB directement:

Le « peuple » magasin a « nom » champ d'index et la liste des champs indexés « passe-temps ». En JSON,

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

Pour récupérer le nom de « peuple » dont le hobby est « 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);
  });
});

La chose intéressante à propos de ce code est qu'il n'y a pas sérialisation impliqué. Il est donc très rapide.

L'exemple suivant illustre la requête graphique de l'amitié. magasin d'objets friendship a un seul champ indiciel coté friend_list. Il utilise les objets de stockage de clés comme clé primaire hors-ligne. magasin d'objets people a beaucoup d'attributs, parmi eux est champ location. La requête est de trouver la liste d'amis qui connaissent me et other_guy et situés dans « 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 de jointure est juste numérisation clé et donc très rapide. Par l'utilisation par défaut scan algorithme de fusion triées pour trouver les clés correspondant, mais ici show-boucle imbriquée naïve algorithme de jointure. Donc, il est possible de rejoindre la table, mais vous devez le code algorithme de jointure. Mais les nouveaux algorithmes comme la fusion en zigzag sont plus rapides que possible avec SQLite parce que toutes les entrées sont triées, les curseurs peuvent avancer à bien et plus important encore rejoindre processus peut exploiter les connaissances externes qui ne sont pas dans la base de données. Avec SQL, opération de jointure est opaque.

Autre que IndexedDB peut être utilisé des techniques telles que le streaming et map / reduce traitement.

Je répondre à cela en 2016 (5 ans après avoir posé cette question) et tout ce qui concerne la deprecation de websql est toujours debout . IndexedDB d'autre part, bénéficie du soutien de tous les principaux fournisseurs navigateur .

Alors à tous ceux qui peuvent se trouver ici confrontés à la même décision de faire, aller avec IndexedDB.

comme le laisse entendre d'autres ici, cependant, une telle décision n'est pas celui qui doit nécessairement être fait; on peut simplement choisir (ou faire) une bibliothèque qui utilise la base de données selon les données disponibles sur une machine client.

Bakedgoods diffère de ces bibliothèques déjà proposées ici de plusieurs façons; la plus pertinente, il permet le type de mémoire (s) qui doivent être utilisées pour spécifier explicitement, à son tour, permet au développeur d'introduire d'autres facteurs (tels que les caractéristiques de performance) dans le processus de prise de décision.

Avec elle, la conduite des opérations de stockage dans celui des types de base de données est pris en charge est une question de ...

... spécifiant les options de fonctionnement appropriées et configs équivalentes pour les deux types de base 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 réalisation 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 des installations de stockage inégalée se fait au prix d'un manque de soutien pour certaines configurations de stockage installation spécifiques. Par exemple, il ne supporte pas la conduction des opérations de stockage dans les tableaux websql avec les clés primaires à plusieurs colonnes.

Donc, si vous faites un usage intensif de ces types de fonctionnalités, vous voudrez peut-être chercher ailleurs.

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top