IndexedDB 和关系

发布于 2024-11-18 20:11:35 字数 570 浏览 8 评论 0原文

我可以在 IndexedDB 中的对象存储之间创建关系吗?

例如,我有两个对象存储:artistalbum艺术家专辑具有一对多关系。 album.artistId 将专辑与 artist.id 相关联。

我在这里沿着 Hibernate 的思路思考。我想对艺术家进行查询,并将属于该艺术家的专辑作为 album 对象上名为 artists 的数组返回。

artist.albums = [];

跟进(4.5 年后,2017 年)

下面有一些很好的答案,很好地回答了这个问题。我想补充一点,我最初尝试使用 IndexedDB 作为关系存储,并在其之上构建一个类似 ORM 的解决方案,但它并不适合。 IndexedDB 是一个 NoSQL 数据库,自从我开始以这种方式对待它以来,它变得更有意义,我的项目也更容易管理。我希望这对于那些不断遇到这个问题的人来说可以为原来的问题增加一些价值。

Can I create relationships between my object stores in IndexedDB?

For example, I have two object stores: artist and album. An artist has a one-to-many relationship with an album. album.artistId relates the album to artist.id.

I'm thinking along the lines of Hibernate here. I would like to do a query for artists and have the albums belonging to that artist returned as an array called artists on the album object.

artist.albums = [];

Follow Up (4.5 years later, 2017)

There are some great answers below that answer the question very well. I'd like to add that I was originally trying to use IndexedDB as a relational store and build an ORM-like solution on top of it, which it is not suited for. IndexedDB is a NoSQL database and since I've started treating it that way it's made more sense and my projects easier to manage. I hope this adds some value to the original question for those who continually come across it.

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

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

发布评论

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

评论(4

鹤舞 2024-11-25 20:11:35

在IndexedDB中,关系只是对其他存储的引用。在本例中,artist 商店的 ID 是 album 商店中的索引字段 artistId。这样就可以使用key range查询来快速查询。

使用 ydn.db.Storage 数据库包装器,

var schema = [stores: [
  {name: 'artist'},
  {name: 'album', 
    indexes: [
      {name: 'artistId'}
    ]
  }
];  
db = new ydn.db.Storage('dbname', schema)

假设,我们对艺术家、援助感兴趣。

db.get('artist', aid).success(function(artist ) {     
  db.query('album', 'artistId').only(aid).success(function(albums) {
    // display artist and albums
  })    
});

In IndexedDB, relationship is just reference to other store. In this case, artist store's id is indexed field, artistId, in album store. In this way, you can quickly query using key range query.

Using ydn.db.Storage database wrapper,

var schema = [stores: [
  {name: 'artist'},
  {name: 'album', 
    indexes: [
      {name: 'artistId'}
    ]
  }
];  
db = new ydn.db.Storage('dbname', schema)

suppose, we are interst in artist, aid.

db.get('artist', aid).success(function(artist ) {     
  db.query('album', 'artistId').only(aid).success(function(albums) {
    // display artist and albums
  })    
});
写下不归期 2024-11-25 20:11:35

indexedDB 提供了创建、读取、更新和删除(CRUD)对象“记录”的低级方法。但标准并没有定义关系操作的具体方法。目标是保持标准简单,并允许开发人员以他们认为合适的任何方式实现更高级别的功能。然而,您所要求的仍然可以通过您的少量开发来实现。

为了帮助解决这个问题,Parashuram Narasimhan 为 indexedDB 编写了一个 Jquery 实现,它将为您完成这项工作。

Jquery indexedDB 示例 1

Jquery indexedDB 示例 2

考虑以下普遍的可能性:

$.indexeddb("MyDatabase")
  .objectStore("Artist")
  .openCursor()
  .each(function(){
    //Got Artist
    //Enumerate for Albums
    $.indexeddb("MyDatabase")
      .objectStore("Artist")
      .openCursor()
      .each(function(){
        //Check for matching artist.Id
        //if this albums's artist matches artist
        //then do something
        }
      ;
    }
  ;

答案有点晚了,但我希望它有助于润滑齿轮。

The indexedDB provides low level methods to create, read, update, and delete (CRUD) "records" of objects. But the standard does not define specific methods for relational operations. The goal was to keep the standard simple and allow developers to implement the higher-level functions in any way they saw fit. However, what you're asking for is still attainable through a small amount of development on your part.

To help things out, Parashuram Narasimhan wrote a Jquery implementation for indexedDB that will finish the job for you.

Jquery indexedDB Example 1

Jquery indexedDB Example 2

Consider the following generalized possibility:

$.indexeddb("MyDatabase")
  .objectStore("Artist")
  .openCursor()
  .each(function(){
    //Got Artist
    //Enumerate for Albums
    $.indexeddb("MyDatabase")
      .objectStore("Artist")
      .openCursor()
      .each(function(){
        //Check for matching artist.Id
        //if this albums's artist matches artist
        //then do something
        }
      ;
    }
  ;

A little late for an answer, but I hope it helps grease the gears a bit.

不回头走下去 2024-11-25 20:11:35

您还可以尝试使用 LINQ2IndexedDB - 另一个对 IndexedDB 使用 LINQ 样式查询的库 - http://linq2indexeddb.codeplex.com

You could also try using LINQ2IndexedDB - another library that uses LINQ style queries for IndexedDB - http://linq2indexeddb.codeplex.com

黎歌 2024-11-25 20:11:35

我看到有两种方法可以解决这个问题。

第一种是采用第三范式风格——用一个对象存储来存储数据对象,另一个用于存储它们之间的关系。 IndexedDB 不支持 JOIN 的概念,因此您无论如何都必须进行两次数据库命中,并且通过这种方法,两个存储都可以拥有单独的索引(可以说,这是关键)。

退后一步,根据您的需要,您可能可以使用简单的键/值方法来存储整个 JS 对象。我没有测量任何东西,但到目前为止我的直觉是,如果您不处理中等数量的数据,则不需要处理标准化的复杂性。

退一步说,如果您不真正建立索引,那么您可能并不真正需要 IndexedDB。如果您只是寻找本地存储,请尝试 localStorage。它与现代浏览器非常兼容,而且 API 也更简单。

var obj = { data_object_1: { 'incoming': [ 1, 2, 3 ], 'outgoing': [ 5, 6, 7 ] } };
localStorage.setItem( 'foobar', JSON.stringify( obj ) );
console.log( JSON.parse( getItem( 'foobar' ) ) );

I see two ways to approach this problem.

The first would be to go third normal form-style -- have one object store to store data objects, and another to store the relationships between them. IndexedDB doesn't support the concept of JOIN so you'll have to do two database hits anyways, and with that approach the two stores can each can have separate indexes (which are key, so to speak).

Stepping back a bit, depending on your need you might be able to just store your whole JS object using a simple key/value approach. I haven't measured anything, but my instinct so far is that if you're not dealing with medium amounts of data you don't need to deal with the complexities of normalization.

Stepping back even further, if you don't really indexes than you might not really need IndexedDB. If you're just looking for local store, try localStorage. It's very compatible with modern browsers and the API is way simpler.

var obj = { data_object_1: { 'incoming': [ 1, 2, 3 ], 'outgoing': [ 5, 6, 7 ] } };
localStorage.setItem( 'foobar', JSON.stringify( obj ) );
console.log( JSON.parse( getItem( 'foobar' ) ) );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文