Подтвердить что ты не робот

HTML5 IndexedDB, Web SQL Database и браузерные войны

Я начинаю разработку веб-приложения с автономными требованиями к хранилищу баз данных. Короче говоря, приложение должно быть в состоянии работать:

  • Один из основных настольных браузеров, предпочитаемый Chrome
  • Safari на iOS
  • Собственный браузер Android (на основе V8 и WebKit)

Итак, вопрос в том, какую технологию выбрать: IndexedDB или Web SQL Database?

Что касается базы данных Web SQL, с одной стороны, она готова к использованию в любом из перечисленных выше сценариев. С другой стороны, Mozilla заявила, что Firefox никогда не реализует ее, и согласно рабочему проекту HTML5 спецификация зашла в тупик:

Эта спецификация зашла в тупик: все заинтересованные разработчики использовали один и тот же SQL-сервер (Sqlite), но нам нужно несколько независимых реализаций для продолжения пути стандартизации. Пока другой разработчик не заинтересован в реализации этой спецификации, описание диалекта SQL оставлено просто ссылкой на Sqlite, что неприемлемо для стандарта. Если вы являетесь разработчиком, заинтересованным в реализации независимого SQL-сервера, обратитесь к редактору, чтобы он мог написать спецификацию для диалекта, что позволило этой спецификации двигаться вперед.

IndexedDB является альтернативой, защищенной Mozilla, но она появится только в Firefox 4. Microsoft заинтересована, и Chrome тоже ее поддержит. Я ничего не знаю о планах Apple относительно IndexedDB.

Я лично склонен выбирать базу данных Web SQL, но только потому, что я привык к SQLite, мне нравится сила и выразительность SQL, и я понимаю реляционную модель. IndexedDB, для меня, является неопределенностью.

Тем не менее, я боюсь делать ставки на неправильной лошади. Можно ли предположить, что поддержка базы данных Web SQL будет продолжать существовать, даже если IndexedDB станет стандартом?

(Заметка о CouchDB: вы также видите это как альтернативу?)

4b9b3361

Ответ 1

Учитывая, что только WebSQL поддерживает все три требования, которые вы указали, не должен ли ваш выбор быть простым? У вас нет понимания дорожной карты разработки для Safari или Android, поэтому используйте то, что у вас есть.

Ответ 2

Ну, как и во всех вычислениях, игра является "абстракцией".

Если вы можете создать адекватный слой, который работает как в хранилище SQL, так и в хранилище ключей/значений, то в идеале вы изолированы от проблемы и можете поддерживать соответствующую реализацию в конкретном браузере. Если ваша модель данных и шаблоны доступа не соответствуют самому низкому общему знаменателю (т.е. Магазину k/v), то это в значительной степени решает вашу проблему прямо там.

Если вы можете использовать либо хранилище, а затем работать на достойном уровне доступа и подходить к проблеме с этого направления.

Разум, только потому, что у вас есть k/v-хранилище на заднем конце, это не значит, что вы должны моделировать свои данные только как модель k/v. По сути, вся БД находится на бэкэнде, это k/v-магазин. Если у вас нет сумасшедшего количества данных, вы можете многое сделать. С большим количеством данных обручи, которые вы, возможно, придется перепрыгивать, могут стоить вам производительности, которых вы, возможно, не видите с меньшим количеством данных. Все зависит.

Ответ 3

Значительно ли ваша база данных находится за пределами хранилищ ключей/значений? Если нет, я нашел несколько пакетов javascript для локальной абстракции базы данных на основе браузера. Одним из таких пакетов является jStore:

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

Недавно я использовал его для добавления локального хранилища ключей/значений. Он хорошо документирован, а время интеграции было незначительным - он поддерживает массив хранилищ, включая флэш-локальное хранилище, через свой API.

CouchDB - отличное решение - для проблемы, которая не совсем согласуется с вашей. Проверьте couchone mobile. Не для строго "веб-приложений", но он может обеспечить базу данных, с которой вы могли бы работать, если у вас есть определенная гибкость в спецификации.

Ответ 4

С учетом вашего требования Safari на iOS нет альтернативы, кроме WebSQL. WebSQL поддерживается в другом мобильном браузере, таком как Opera и Blackberry. Я не думаю, что они удалят поддержку WebSQL, даже если у них есть IndexedDB. Каким-то образом они дополняют друг друга.

С другой стороны, во время войны с хранилищем браузеров IndexedDB выигрывает навсегда. IE и FF будут иметь только IndexedDB. Ироничным фактом является то, что FF реализует IndexedDB поверх Sqlite.

Что я хотел бы сказать, это IndexedDB - это больше, чем просто хранилище ключей. У него есть индекс и транзакция. Эти два только делают почти все функции SQL-запроса, включая объединение, условное и сортировку. Это не очевидно сначала из-за его асинхронного API.

Производительность IndexedDB лучше WebSQL. Это более безопасно. Он более гибкий для использования javascript. Наконец, это проще в использовании.

Чтобы проиллюстрировать это, я буду использовать sudo-код из моей библиотеки, но вы можете напрямую использовать IndexedDB API:

В хранилище "people" указано поле "имя" и список индексированных полей "хобби". В JSON,

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

Получить имя из "людей", чье хобби "кемпинг".

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

Интересно, что этот код не связан с сериализацией. Следовательно, это очень быстро.

Следующий пример иллюстрирует запрос графика дружбы. friendship В хранилище объектов есть только одно указанное индексированное поле friend_list. Он использует ключ хранения объектов людей как первичный первичный ключ. people хранилище объектов имеет много атрибутов, среди которых поле location. Запрос состоит в том, чтобы найти список друзей, которые знают me и other_guy и находятся в 'Сингапуре'.

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

Снова этот запрос соединения - это просто сканирование ключей и, следовательно, очень быстрое. По умолчанию scan используйте алгоритм sorted-merge для поиска совпадающих ключей, но здесь показан наивный алгоритм объединения вложенных циклов. Таким образом, соединение таблицы возможно, но вам нужно кодировать алгоритм объединения. Но более новые алгоритмы, такие как слияние зигзагов, быстрее, чем возможно, с Sqlite, потому что все входы сортируются, курсоры могут продвигаться хорошо, а что более важно, процесс соединения может использовать внешние знания, которых нет в базе данных. С SQL операция соединения непрозрачна.

Помимо этого IndexedDB могут использоваться такие методы, как потоковая передача и преобразование карты/уменьшения.

Ответ 5

Моя рекомендация - перейти на IndexDB, потому что есть IndexDB Polyfill доступно.

Все браузеры, поддерживающие WebSQL, могут поддерживать IndexDB API таким образом. Другим способом было бы очень сложно реализовать, поэтому, если вы хотите достичь всех браузеров, которые знают о некоторых API БД, сегодня лучший выбор - IndexDB.


Примечание. Даже если этот вопрос старый, он все еще имеет значение, поэтому я думаю, что ответы на этот вопрос заслуживают обновления. И извините за решение только для ссылок, поэтому я добавил только ссылки на обычно длительные адресаты: W3C и GitHub

Ответ 6

Я отвечаю на это в 2016 году (через 5 лет после того, как вы задали этот вопрос), и все, что касается обесценивания WebSQL, все еще стоит. IndexedDB, с другой стороны, пользуется поддержкой всех основных поставщиков браузеров.

Таким образом, всем, кто может оказаться здесь, столкнулся с тем же самым решением, зайдите в IndexedDB.

Как подразумевается другими здесь, такое решение не обязательно должно быть сделано; можно просто выбрать (или создать) библиотеку, которая использует любую доступную базу данных на клиентской машине.

BakedGoods отличается от таких библиотек, которые уже предложены здесь несколькими способами; наиболее подходящим образом, он позволяет использовать тип хранения, который должен быть явно определен, в свою очередь, позволяя разработчику вводить другие факторы (такие как характеристики производительности) в процесс принятия решений.

При этом проводя операции хранения в зависимости от того, какой тип базы данных поддерживается, является вопросом...

... с указанием соответствующих параметров операции и эквивалентных конфигураций для обоих типов баз данных:

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

... и проводя операцию:

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

Его простой интерфейс и непревзойденная поддержка хранилища оплачиваются из-за отсутствия поддержки для некоторых конфигураций, связанных с хранилищем. Например, он не поддерживает проведение операций хранения в таблицах WebSQL с использованием нескольких столбцов первичных ключей.

Итак, если вы сильно используете те типы функций, вы можете захотеть посмотреть в другом месте.

О, и для полной прозрачности, BakedGoods поддерживается вашим действительно:).