5

你们都如何处理 IndexedDB 中的多对多关系?

例如,假设我有一个Blog用于保存博客文章的Tag对象和一个用于博客文章标签/标签的对象。一个Blog可以有多个Tags,一个Tag可以被多个Blogs使用。

我会创建一个blog storeand 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对象数组,其中包含blogIdtagId(并且也将在存储中进行检索)或
  2. 有一个可以用来查找 sBlog.tags的数组。tagIdTag

第一种方法似乎冗长,但这是如何在 SQL 中解决的。那只是我应该留下的SQL包吗?

我想第三种方法是有Blog.tags一个s数组Tag。这似乎最简单,但我无法查询Tags 或跨博客重用标签(或者我可以吗?)。

有没有其他人用 indexedDB 处理过这种情况?如果是这样,你最终做了什么?有哪些陷阱?

4

1 回答 1

7

我正在研究一个IndexedDB 支持的 JS 神经网络实现,并遇到了这个问题。

我们在 IndexedDB 中没有连接,因此您至少要查看两个对象存储命中,除非您正在进行某种记忆/缓存。

根据经验,我发现面向文档的样式最适合 IndexedDB 对象(将所有内容存储在同一个存储中),但需要辅助存储来容纳关系。

这就是我正在做的事情。

假设您想拥有一家本地的演员和电影商店——比如 IMDB。这种和大多数任何多对多关系都可以使用 IndexedDB 使用两个表进行建模:对象和关系。

这是两张表。您需要对几乎所有内容进行键查找*。任何不能说独特的东西都可以是非独特的。

对象对象存储:

type_id*
whatever*..

关系对象存储:

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

演员/电影示例将是 Objects 表中的两条记录和关系表中的一条记录:

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'
} 

获取 Michael Cera 电影的伪代码:

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
于 2011-12-18T06:28:24.527 回答