IndexedDB и отношения «многие ко многим» - PullRequest
5 голосов
/ 14 сентября 2011

Как вы все обрабатываете отношения «многие ко многим» в IndexedDB?

Например, скажем, у меня есть объект Blog для хранения сообщения в блоге и объект Tag для тега / метки сообщения в блоге. Один Blog может иметь много Tag с, а один Tag может использоваться многими Blog с.

Я бы создал blog store и tag store (хотя я открыт для предложений) для размещения двух типов объектов:

// ...
var blogStore = db.createObjectStore("blog", {keyPath: "blogId", autoIncrement: true});
blogStore.createIndex("title", "title", {unique: true});
var tagStore = db.createObjectStore("tag", {keyPath: "tagId", autoIncrement: true});
tagStore.createIndex("label", "label", {unique: true});

От руки Я могу придумать два способа связать два:

  1. есть Blog.tags, который будет массивом BlogTag объектов, который содержит blogId и tagId (и также будет в хранилище для поиска) или
  2. имеет Blog.tags, который будет массивом tagId с, который можно использовать для поиска Tag с.

Первый способ кажется более сложным, но это то, как это будет решаться в SQL. Это тот самый багаж SQL, который я должен оставить после себя?

Полагаю, что 3-й способ - это Blog.tags массив из Tag с. Это кажется самым простым, но тогда я не мог запросить Tag s или повторно использовать теги в блогах (или я мог?).

Кто-нибудь еще обрабатывал такую ​​ситуацию с indexedDB? Если так, что ты в итоге делал? Какие были подводные камни?

1 Ответ

7 голосов
/ 18 декабря 2011

Я работаю над реализацией нейронной сети с поддержкой IndexedDB и столкнулся с этим очень проблема.

У нас нет объединений в IndexedDB, поэтому вы просматриваете как минимум два обращения к хранилищу объектов, если только вы не выполняете какое-либо запоминание / кэширование.

Из опыта я обнаружил, что ориентированный на документы стиль лучше всего подходит для объектов IndexedDB (храните все в одном и том же хранилище), но для хранения отношений требуется вторичное хранилище.

Вот что я делаю.

Скажем, вы хотите иметь местный магазин актеров и фильмов - что-то вроде IMDB. Это и большинство любых отношений «многие ко многим» можно смоделировать с помощью IndexedDB с использованием двух таблиц: «Объекты и отношения».

Вот две таблицы. Вы хотели бы поиск ключевых слов * почти на все. Все, что не говорит «уникальный», может быть неуникальным.

Хранилище объектов объектов:

type_id*
whatever*..

Хранилище объектов отношений:

id* (unique, auto-incrementing)
from_type*
to_id*

Пример актера / фильма: две записи в таблице объектов и одна запись в таблице отношений:

var actor1 = {
    id: 'actor_jonah_goldberg',
    display: 'Jonah Goldberg',
};

var actor2 = {
    id: 'actor_michael_cera',
    display: 'Michael Cera'
};

var movie1 = {
    id: 'movie_superbad',
    display: 'Superbad',
    year: 2007
};

var movie2 = {
    id: 'movie_juno',
    display: 'Juno',
    year: 2007
};

//relationship primary key ids are auto-inc

var relationship1 = {
    from_id: 'actor_jonah_goldberg',
    to_id: 'movie_superbad'
} 

var relationship2 = {
    from_id: 'actor_michael_cera',
    to_id: 'movie_superbad'
} 

var relationship3 = {
    from_id: 'actor_michael_cera',
    to_id: 'movie_juno'
} 

Псевдо-код для получения фильмов Майкла Серы:

IndexedDBApp( { 'store': 'relationships', 'index': 'from_id', 'key': 'actor_michael_cera', 'on_success': function( row ) {...} );
// Would return movie_superbad and movie_juno rows on_success

Псевдо-код для получения всех фильмов за данный год:

IndexedDBApp( { 'store': 'objects', 'index': 'year', 'key': 2007, 'on_success': function( row ) {...} );
// Would return movie_superbad and movie_juno rows on_success

Псевдо-код для получения актеров фильма:

IndexedDBApp( { 'store': 'relationships', 'index': 'to_id', 'key': 'movie_superbad', 'on_success': function( row ) {...} );
// Would return actor_jonah_goldberg and actor_michael_cera on_success

Псуедо-код для получения всех актеров:

IndexedDBApp( { 'store': 'relationships', 'index': 'id', 'cursor_begin': 'actor_a', 'cursor_end': 'actor_z', 'on_success': function( row ) {...} );
// Would return actor_jonah_goldberg and actor_michael_cera on_success
...