IndexedDB 和多对多关系

发布于 2024-12-04 07:41:06 字数 1089 浏览 5 评论 0原文

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

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

我会创建一个 blog storetag 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 ,它是一个包含 blogIdtagIdBlogTag 对象数组(并且也可以在商店中检索)或
  2. Blog.tags 是一个 tagId 数组,可用于查找 Tag

第一种方法看起来比较冗长,但是这是在 SQL 中解决这个问题的方法。这只是我应该留下的 SQL 包袱吗?

我想第三种方法是让 Blog.tags 成为 Tag 的数组。这看起来很简单,但我无法查询 Tag 或跨博客重复使用标签(或者我可以吗?)。

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

How are you all handling many-to-many relationships in IndexedDB?

For example, say I have a Blog object to hold a blog post and a Tag object for a tag/label of the blog post. One Blog can have many Tags and one Tag can be used by many Blogs.

I would create a blog store and tag store (though I'm open to suggestions) to house the two types of objects:

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

Off hand I can think of two ways to link the two:

  1. have a Blog.tags which would be an array of BlogTag objects which holds blogId and tagId (and would also be in the store for retrieval) or
  2. have a Blog.tags which would be an array of tagIds that could be used to look up the Tags.

The first way seems longer-winded but is how this would be tackled in SQL. Is that just SQL-baggage that I should leave behind?

I suppose a 3rd way would be to have Blog.tags be an array of Tags. This seems simplest but then I couldn't query for Tags or reuse tags across blogs (or could I?).

Has anyone else handled such a situation with indexedDB? If so, what did you end up doing? What were some pitfalls?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

国粹 2024-12-11 07:41:06

我正在开发 IndexedDB 支持的 JS 神经网络实现 并面临着这个问题
问题。

我们在 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'
} 

用于获取 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

Psuedo -用于获取电影演员的代码:

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

I'm working on an IndexedDB-backed JS neural network implementation and faced this very
problem.

We don't have joins in IndexedDB so you're looking at at least two object store hits unless you're doing some sort of memoization/caching.

From experience I've found that a document-oriented style is best with IndexedDB objects (store everything in the same store), but a secondary store is needed to house relations.

Here's what I'm doing.

Say you want to have a local store of actors and movies -- something like IMDB. This and most any many-to-many relationship can be modeled with IndexedDB using two tables: Objects and Relationships.

Here are the two tables. You'd want key lookups* on almost everything. Anything that doesn't say unique can be non-unique.

Objects object store:

type_id*
whatever*..

Relationships object store:

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

An actor/movie example would be two records in the Objects table and one in the relationship table:

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

Psuedo-code for getting Michael Cera's movies:

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

Psuedo-code for getting all movies from a given year:

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

Psuedo-code for getting a movie's actors:

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

Psuedo-code for getting all actors:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文