HTML5 indexedDB, веб-база данных SQL и войны браузера
Вопрос
Я начинаю разработку веб-приложения с требованиями к хранилищу базы данных офлайн. Короче говоря, приложение должно быть в состоянии работать:
- Один из основных настольных браузеров, Chrome предпочтительнее
- Safari на iOS.
- В родном браузере Android (на основе V8 и WebKit)
Таким образом, вопрос в том, какая технология выбора: indexeddb или web sql базы данных?
Относительно базы данных Web SQL, с одной стороны, она готова к использованию в любом из вышеперечисленных сценариев. С другой стороны, Mozilla заявил Firefox, никогда не реализует его, а включает в себя HTML5 Рабочий проект Спецификация достигла тупика:
Эта спецификация достигла тупика: все заинтересованные элементы использовали один и тот же бэкэнд SQL (SQLite), но нам нужны несколько независимых реализаций, которые будут выполняться по пути стандартизации. До тех пор, пока другой реализатор не заинтересован в реализации этого спецификации, описание диалекта SQL было оставлено просто ссылкой на SQLite, что не приемлемо для стандарта. Если вы заинтересованы в реализации независимой BackeND SQL, пожалуйста, свяжитесь с редактором, чтобы он мог написать спецификацию для диалекта, что позволяет этой спецификации двигаться вперед.
IndexedDB - это альтернатива, выступающая в зависимости от Mozilla, но она придет только в Firefox 4. Microsoft заинтересована, и Chrome также поддержит это. Я ничего не знаю о планах Apple в отношении IndexedDB.
Я лично склонен выбирать базу данных Web SQL, но только потому, что я привык к SQLite, мне нравится сила и выразительность SQL, и я понимаю реляционную модель. Indexeddb, для меня, это неопределенность.
Тем не менее, я боюсь ставок на неправильную лошадь. Безопасно ли принять поддержку базы данных Web SQL, даже если indexedDB становится стандартом?
(Примечание на CouchDB: Вы также видите его как альтернативы?)
Решение
Учитывая только WebSQL поддерживает все три требования, которые вы перечислены, не должен ли ваш выбор быть простым? Вы не имеете представления о дорожной карте развития Safari или Android, поэтому используйте то, что у вас есть.
Другие советы
Ну, как со всеми вещами вычисления, игра - «абстракция».
Если вы сможете придумать адекватный слой, который работает над магазином SQL, так и в магазине клавиш / значений, то в идеале вы извлекаетесь из задачи и могут поддерживать соответствующую реализацию в конкретном браузере. Если ваша модель данных и шаблоны доступа не подходят с самым низким общим знаменателем (т.е. магазином AK / V), то это в значительной степени решает вашу проблему прямо там.
Если вы можете использовать любой магазин, то работайте на достойном уровне доступа и подходите к проблеме с этого направления.
Ум, только потому, что у вас есть магазин AK / V на заднем конце не означает, что вы должны моделировать ваши данные как только модель AK / V. По сути, все БД находится на бэкере, - это магазин AK / V. Если у вас нет безумных данных, вы можете делать много вещей. Благодаря большому количеству данных обручи, которым вы могли бы перейти через, могут стоить вам, что вы вполне можете не видеть с меньшим количеством данных. Все зависит.
Ваши данные базы данных существенно за пределами ключевых / стоимости магазинов? Если нет, я нашел ряд пакетов JavaScript для локальной абстракции базы данных на основе браузера. Один такой пакет - jstore:
http://code.google.com/p/jquery-jstore/
Недавно я использовал его, чтобы добавить хранение локального ключа / значения. Он хорошо документирован, и время интеграции было незначительным - он поддерживает массив бэкэндов памяти, включая Flash Local Storage, через его API.
CouchDB - отличное решение - для проблемы, которая не совсем конгруэнтна с вашим. Проверить Couchone Mobile. Отказ Не для строго «веб-приложений», но он может предоставить основу базы данных, с которым вы можете работать, если у вас есть некоторая гибкость со спецификацией.
Моя рекомендация заключается в Перейти на indexdb., потому что есть IndexDB Polyfill. имеется в наличии.
Все браузеры, поддерживающие WebSQL, могут поддерживать Indexdb API Сюда. Другой путь будет очень сложно реализовать, поэтому, если вы хотите добраться до всех браузеров, которые знают о некоторых API DB, IndexDB является лучшим выбором сегодня.
Примечание. Даже этот вопрос старый, все равно уместно, поэтому я думаю, что ответы на этот вопрос заслуживают обновления. И извините за решение только на связи, поэтому я добавил только ссылки на обычно длительные пункты назначения: w3c и github
С вашим данным требованием Safari на iOS нет альтернативы, а WebSQL. WebSQL поддерживается в другом мобильном браузере, как Opera и BlackBerry. Я не думаю, что они будут удалять поддержку WebSQL, даже если у них есть indexedDB. Как-то они дополняют.
С другой стороны, на браузере хранилище войны, IndexedDB выиграть навсегда. IE и FF будут иметь только indexedDB. Иронический факт состоит в том, что FF реализует IndexedDB сверху SQLite.
То, что я хотел бы сказать, является indexedDB - это больше, чем просто магазин ключевых значений. Он имеет индекс и транзакцию. Эти только два делают практически все функции SQL-запроса, включая соединение, условное и сортировку. Сначала это не очевидно из-за его асинхронного API.
Производительность IndexedDB лучше, чем WebSQL. Это более безопасно. Это более гибкий для корпуса использования JavaScript. Наконец, это более легче использовать.
Чтобы проиллюстрировать корпус, я буду использовать код Sudo из моя библиотека, но вы можете использовать API indexedDB напрямую:
Магазин «Люди» имеет индексное поле «Имя» и списка индексированного поля «Хобби». В JSON,
people = {
name: 'Foo Bar',
email: 'foo@bar.com'
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
Используйте сортировочный алгоритм слияния, чтобы найти соответствующие клавиши, но здесь отображаются Naive Nested-Loop Algorith. Таким образом, присоединение таблицы возможно, но вы должны кодировать алгоритм присоединения. Но новые алгоритмы, такие как зигзаг слияния, являются быстрее, чем можно с SQLite, потому что все входы сортируются, курсоры могут продвигаться в колодце и более важно, процесс присоединения может использовать внешние знания, которые не в базе данных. С SQL операция присоединения непрозрачна.
Кроме того, IndexedDB могут быть использованы методы, такие как потоковое и карту / уменьшение обработки.
Я отвечаю на это в 2016 году (через 5 лет после того, как вы задали этот вопрос) и все относительно Амортизация WebSQL все еще стоит. Отказ Indexeddb с другой стороны, Наслаждается поддержкой всех основных поставщиков браузера.
Итак для всех, кто может оказаться здесь, столкнувшись с тем же решением, иди с IndexedDB.
Тем не менее, подразумевается другими здесь, такое решение не обязательно должно быть сделано; Можно просто выбрать (или сделать) библиотеку, которая использует, в какой базе данных доступна база данных на клиентской машине.
Выпечка отличается от таких библиотек, уже предложенных здесь несколько способов; Наиболее уместно, он позволяет использовать тип (ы) хранилища, которые должны быть использованы, чтобы быть явно указанным, в свою очередь, позволяя разработчику вводить другие факторы (такие как характеристики производительности) в процессе принятия решений.
С нем поддерживается проведение операций хранения в зависимости от таких типов баз данных - это вопрос ...
... Указание соответствующих вариантов работы и эквивалентных конфиг для обеих типов баз данных:
//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 с первичными клавишами Multi-Column.
Поэтому, если вы придерживаетесь тяжелых применений этих типов функций, вы можете искать в другом месте.
Ох, и ради полной прозрачности выпекрехозы поддерживаются твоей по-настоящему :).