IndexedDB中带有标签模型的文档

时间:2012-02-19 18:02:39

标签: nosql database-schema indexeddb

我有歌曲和标签。标签可以是“记录位置”或“最后记录日期”类型。

在关系模型中,我会有一个包含song_id和tag_id信息的连接模型。但是在像indexeddb这样的文档库DB中,我会将标签及其信息直接存储在文档中。我想知道如果我没有很多独特的标签,那么从长远来看这不会导致DB bload吗?

如果另一首歌需要其中一个已经在另一首歌上使用的标签,我会有一个重复的标签。

我当然可以在这里使用连接商店,但这也包括2个表的手动提取。

我对该模型有几个问题:

  1. 我应该有歌曲和标签存储吗?
  2. 如何批量更新标签,附加到每首歌曲?
  3. 我可能需要哪些指数才能做到这一点?
  4. 我的主要方面是搜索标签值(并按类型过滤)。

2 个答案:

答案 0 :(得分:1)

使用IDB和其他NoSQL存储的关键是不会陷入连接ID,只是试图让每个对象存储本身都有用。 (并且使用索引很好!)请记住,这就是SQL-ish数据库的工作原理,但它允许您在需要时进行专门的连接,而不是在一般情况下。

批量更新更具挑战性,但更多的是针对最常见的情况进行优化(显示查找歌曲/标签),而不是针对更稀有的事情进行优化(批量更改标签名称)

您正在考虑的最基本架构是将歌曲存储为:

{ name: "Name of Song"
  id: <song id>
  tags: ["tag1", "tag2", "tag3"] }

标签可以简单地用他们的名字来识别:

{ name: "tagname"
  description: "Some tag description or whatever" }

首先创建你的歌曲对象商店:

var songs = db.createObjectStore("songs", "id");

然后创建一个multiEntry索引:

songs.createIndex("tags", "tags", {multiEntry: true});

然后创建一个标签objectStore:

var tags = db.createObjectStore("tags", "name");

现在你可以自己做联接,如果你真的需要,但有时它只是一些开关的东西。

var trans = db.transaction(["songs", "tags"]);

var songTags = [];
trans.objectStore("songs").get("songid").onsuccess = function(e) {
    var song = e.target.result;
    for (var i = 0; i < song.tags.length; i++) {
        trans.objectStore("tags").get(song.tags[i]).onsuccess = function(e) {
            var tag = e.target.result;
            songTags.push(tag);
        }
    }
}
trans.oncomplete = function(e) {
     showSongTags(songTags);
}

感谢歌曲上的'标签'索引,反之亦然。请注意,我们直接使用标记名称,而不是使用某些中间数字tag_id。

var trans = db.transaction(["songs", "tags"]);

var songs = [];
trans.objectStore("songs").index("tags").openCursor("tag1").onsuccess = function(e) {
    var cursor = e.target.result;
    if (!cursor) return;

    cursor.continue();
    songs.push(cursor.value);
}
trans.oncomplete = function(e) {
     showSongs(songs);
}

答案 1 :(得分:0)

当他们不得不在像MySQL这样的关系数据库和像MongoDB这样的文档导向数据库之间做出选择时,你基本上面临着人们面临的同样问题。复制数据 - 更不用说密钥本身 - 占用空间,它肯定更像是“第三种形式”,可以存储一个副本并使用外键代替。

那就是说,我在我的IndexedDB工作中已经完成了这两个方面。相信你做的事情 - 关于存储效率 - 需要与你实际访问数据的方式进行权衡。当你想在IndexedDB中实现类似外键的模式时,它必然需要2个以上的对象存储,比如存储为底层文件系统上的两个独立文件。这意味着对于每个查询,您需要外键数据(此处为标签),您必须至少有两个对象存储点击,可能是两个事务,我假设,额外的io开销和这些相关联。

我会采用面向文档的方法,尝试使用关键速记等技巧(例如“n”代替“名称”)使存储命中率降低。