С вашим заданным требованием Safari на iOS, нет альтернативы, кроме WebSQL.WebSQL поддерживается в других мобильных браузерах, таких как Opera и Blackberry.Я не думаю, что они уберут поддержку WebSQL, даже если у них есть IndexedDB.Как-то они дополняют друг друга.
С другой стороны, в войне хранилищ браузера, IndexedDB выиграл навсегда.IE и FF будут иметь только IndexedDB.Забавно, что FF реализует IndexedDB поверх Sqlite.
Я хотел бы сказать, что IndexedDB - это больше, чем просто хранилище значений ключей.У него есть индекс и транзакция.Эти только два делают практически все функции SQL-запросов, включая объединение, условное и сортировку.Сначала это не очевидно из-за его асинхронного API.
Производительность IndexedDB лучше, чем WebSQL.Это более безопасно.Это более гибкий вариант использования JavaScript.Наконец, его проще использовать.
Чтобы проиллюстрировать этот случай, я буду использовать код sudo из моей библиотеки , но вы можете напрямую использовать IndexedDB API:
The 'Магазин людей имеет индексное поле «имя» и индексированное поле списка «хобби».В 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
использует алгоритм сортировки слиянием для поиска подходящих ключей, но здесь показан наивный алгоритм объединения вложенных циклов.Таким образом, объединение таблиц возможно, но вы должны кодировать алгоритм объединения.Но более новые алгоритмы, такие как зигзагообразное слияние, быстрее, чем это возможно в Sqlite, потому что все входные данные отсортированы, курсоры могут продвигаться вперед и, что более важно, процесс объединения может использовать внешние знания, которых нет в базе данных.В SQL операция соединения непрозрачна.
Помимо IndexedDB, могут использоваться такие методы, как потоковая передача и обработка отображения / сокращения.