Pregunta

estoy empezando el desarrollo de una aplicación web con los requisitos de almacenamiento de base de datos fuera de línea. En resúmen, la aplicación debe ser capaz de ejecutar en:

  • Uno de los principales navegadores de escritorio, Chrome prefiere
  • Safari en iOS
  • navegador nativo de Android (basado en WebKit y V8)

Así que la cuestión es que la tecnología para elegir:? Base de datos SQL Web o IndexedDB

En cuanto a la base de datos SQL Web, por un lado, está listo para ser utilizado en cualquiera de los escenarios anteriores. Por otro lado, Mozilla Firefox ha declarado nunca ponerlo en práctica, y según el proyecto de HTML5 trabajo la especificación ha llegado a un punto muerto:

Esta especificación ha llegado a un callejón sin salida: todos los implementadores interesados ??han utilizado el mismo servidor SQL (SQLite), pero necesitamos múltiples implementaciones independientes para proceder a lo largo de un camino de normalización. Hasta otro implementador está interesado en implementar esta especificación, la descripción del lenguaje SQL se ha dejado como una simple referencia a SQLite, lo cual no es aceptable para un estándar. En caso de ser un implementador interesado en implementar un servidor SQL independiente, póngase en contacto con el editor para que pueda escribir una especificación para el dialecto, lo que permite esta especificación se mueva hacia adelante.

IndexedDB es la alternativa defendida por Mozilla, pero sólo llegará en Firefox 4. Microsoft está interesada y Chrome va a apoyar también. No sé nada de los planes de Apple con respecto a IndexedDB.

Me inclino personalmente para elegir la base de datos SQL Web, pero sólo porque yo estoy acostumbrado a SQLite, me gusta el poder y la expresividad de SQL, y entiendo el modelo relacional. IndexedDB, para mí, es una incertidumbre.

Dicho esto, tengo miedo de apostar por el caballo equivocado. ¿Es seguro asumir apoyo a la base de datos SQL Web seguirá existiendo, incluso si IndexedDB se convierte en la norma?

(Una nota sobre CouchDB:? ¿Usted también lo ven como una alternativa)

¿Fue útil?

Solución

Considerando sólo WebSQL soporta los tres requisitos que usted ha enumerado, no debe ser simple su elección? No tienes ni idea de la hoja de ruta de desarrollo para Safari o Android, a fin de utilizar lo que tiene disponible.

Otros consejos

Bueno, como con todas las cosas de computación, el juego es la "abstracción".

Si se puede topar con una capa adecuada que funciona tanto en un almacén de SQL y una tienda de clave / valor, entonces, lo ideal es que están aislados del problema y pueden apoyar la aplicación correspondiente en el navegador en particular. Si sus patrones de modelos de datos y el acceso no encajan con el denominador común más bajo (es decir, una tienda de k / v), a continuación, que más o menos resuelve su problema allí mismo.

Si usted puede utilizar cualquiera de las tiendas, entonces el trabajo en una capa de acceso decente y abordar el problema desde esa dirección.

Mente, sólo porque usted tiene una k / v tienda en la parte de atrás no significa que tenga que modelar sus datos, ya que sólo un modelo k / v. Esencialmente toda una base de datos está en el backend es una tienda k / v. Si usted no tiene una cantidad insana de los datos, se pueden hacer muchas cosas. Con una gran cantidad de datos de los aros puede que tenga que saltar a través de puede costar en el rendimiento que es muy posible que no vea con una menor cantidad de datos. Todo depende.

Son sus necesidades de bases de datos significativamente más allá de las tiendas de clave / valor? Si no es así, he encontrado una serie de paquetes de JavaScript para la abstracción de base de datos basada en el navegador local. Uno de estos paquetes es jStore:

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

Hace poco lo utilizó para añadir almacenamiento clave / valor local. Está bien documentado y el tiempo de integración fue insignificante -. Que soporta una serie de backends de almacenamiento, incluyendo flash de almacenamiento local, a través de su API

CouchDB es una excelente solución - para un problema que no es del todo congruente con la suya. Echa un vistazo a couchone móvil . No por estrictamente 'aplicaciones web', pero puede proporcionar una base de base de datos que podría correr con, si usted tiene cierta flexibilidad con la especificación.

Mi recomendación es ir para IndexDB , porque hay una IndexDB Polyfill disponible.

Todos los navegadores que soporten WebSQL puede apoyar el IndexDB API esta manera. Al revés sería muy difícil de aplicar, por lo que si desea llegar a todos los navegadores, que saben de alguna API DB, IndexDB es la mejor opción hoy en día.


Nota: A pesar de que esta cuestión es antigua que sigue siendo relevante, así que creo que las respuestas a esta pregunta merece una actualización. Y lo siento por la solución de enlace única, por lo que añade sólo enlaces a destinos de larga duración por lo general: W3C y GitHub

Con su requerimiento dado de Safari en iOS, no hay otra alternativa que WebSQL. WebSQL se apoya en otro navegador móvil, como Opera y Blackberry. No creo que van a eliminar el soporte WebSQL incluso si tienen IndexedDB. De alguna manera que son complementarios.

Por otro lado, en la guerra de almacenamiento navegador, IndexedDB ganar para siempre. IE y FF sólo tendrán IndexedDB. hecho irónico es que implementa FF IndexedDB en la parte superior de SQLite.

Lo que me gustaría decir es IndexedDB es más que un simple almacén de claves de valor. Tiene índice y transacción. Estos sólo dos hacen casi todas las características de consulta SQL incluyendo unirse, condicional y la clasificación. No es obvio al principio debido a su API asíncrona.

Rendimiento de IndexedDB es mejor que WebSQL. Es más seguro. Es más flexible para el caso de uso de JavaScript. Por último, es más fácil de usar.

Para ilustrar el caso, voy a utilizar sudo código de mi biblioteca , pero se puede utilizar IndexedDB API directamente:

Tienda El 'pueblo' tiene campo de índice 'nombre' y la lista de campo indexado 'manía'. En JSON,

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

Para recuperar el nombre de 'pueblo' cuyo hobby es 'acampar'.

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

Lo interesante de este código es que no hay serialización en cuestión. Por lo tanto es muy rápido.

El siguiente ejemplo ilustra consulta amistad gráfico. friendship almacén de objetos sólo tiene un listado friend_list campo indexado. Utiliza los objetos del almacén de claves como clave primaria fuera de línea. people almacén de objetos tiene muchos atributos, entre ellos se encuentra el campo location. La consulta es encontrar la lista de amigos que conocen me y other_guy y están situados en 'Singapur'.

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

Una vez más esta consulta de unión es sólo de exploración clave y por lo tanto muy rápido. Mediante el uso scan predeterminado algoritmo de combinación ordenados para encontrar los correspondientes llaves, pero aquí mostrar ingenua en bucle anidado algoritmo. Así tabla de unión es posible, pero hay que unírseles código de algoritmo. Pero los nuevos algoritmos de combinación como en zig-zag son más rápidos que es posible con SQLite porque todas las entradas están ordenados, los cursores pueden avanzar en el pozo y lo más importante unirse a proceso puede explotar el conocimiento externo que no está en la base de datos. Con SQL, operación de unión es opaco.

Aparte de eso IndexedDB se puede utilizar técnicas como el streaming y el mapa / reducir el procesamiento.

Estoy respondiendo a este en 2016 (5 años después de que esta pregunta) y todo lo referente a la desaprobación de WebSQL sigue en pie . IndexedDB por el contrario, cuenta con el apoyo de todos los principales proveedores de navegadores .

Así que para cualquier persona que pueda encontrarse aquí se enfrentaron con la misma decisión que tomar, ir con IndexedDB.

Como implicado por otros aquí, sin embargo, esta decisión no es uno que tiene necesariamente que ser hecho; uno puede simplemente elegir (o marca) una biblioteca que utiliza Cualquiera que sea la base de datos está disponible en una máquina cliente.

Bakedgoods difiere de tales bibliotecas que han sido sugeridas aquí de varias maneras; más pertinente, permite que el tipo (s) de almacenamiento que se van a utilizar para ser especificada explícitamente, a su vez permite al desarrollador para introducir otros factores (tales como las características de rendimiento) en al proceso de toma de decisiones.

Con él, la realización de las operaciones de almacenamiento en cualquiera de los tipos de bases de datos se admite es una cuestión de ...

... especificando las opciones de operación apropiadas y configuraciones equivalentes para ambos tipos de bases de datos:

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

... y la realización de la operación:

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

Su sencilla interfaz y soporte instalación de almacenamiento sin precedentes viene a costa de la falta de apoyo para algunas configuraciones de instalación específicas de almacenamiento. Por ejemplo, no es compatible con la conducción de las operaciones de almacenamiento en tablas WebSQL con las claves principales de varias columnas.

Así que si usted hace un uso intensivo de esos tipos de características, es posible que desee buscar en otra parte.

Ah, y en aras de una total transparencia, Bakedgoods se mantiene por su servidor :).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top