IndexedDB和多对多关系 [英] IndexedDB and many-to-many Relationships

查看:96
本文介绍了IndexedDB和多对多关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您是如何在IndexedDB中处理多对多关系的?

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



我会创建一个博客商店标记商店(虽然我愿意接受建议)来容纳两种类型的对象:

  // ... 
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 s的数组,可用于查找标记 s。

第一种方法似乎较长时间但它是如何在SQL中解决的。这仅仅是我应该留下的SQL行李吗?



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

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

解决方案

我正在处理 IndexedDB支持的JS神经网络实现,并面临这个非常b $ b问题。



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



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

这就是我正在做的事情。



假设你想拥有一个演员和电影的本地商店 - 某事像IMDB。这个和大多数任何多对多关系都可以使用IndexedDB使用两个表建模:对象和关系。



这是两个表。几乎所有的东西都需要重点查找。任何不说唯一的东西都可以是非唯一的。



对象对象存储:

  type_id * 
whatever * ..

关系对象存储:

  id *(唯一,自动递增)
from_type *
to_id *
code>

演员/电影的例子是Object表中的两条记录和关系表中的一条:

  var actor1 = {
id:'actor_jonah_goldberg',
显示:'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
};

//关系主键ID是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){...}); 
//将返回movie_superbad和movie_juno行on_success

用于获取所有电影的伪代码给定年份:
$ b $ pre $ IndexedDBApp({'store':'objects','index':'year','key' :2007,'on_success':function(row){...});
//将返回movie_superbad和movie_juno行on_success

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


$ b $ pre $ IndexedDBApp({'store':'relationships','index':'to_id','key':'movie_superbad ','on_success':function(row){...});
//将返回actor_jonah_goldberg和actor_michael_cera on_success

获取所有演员的Psuedo代码:

  IndexedDBApp({'store':'relationships','index':'id','cursor_begin':'actor_a', 'cursor_end':'actor_z','on_success':function(row){...}); 
//将返回actor_jonah_goldberg和actor_michael_cera on_success


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?

解决方案

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

这篇关于IndexedDB和多对多关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆