Nosql IndexedDB中带有标记模型的文档

Nosql IndexedDB中带有标记模型的文档,nosql,database-schema,indexeddb,Nosql,Database Schema,Indexeddb,我有歌曲和标签。标签的类型可以是“录制位置”或“上次录制日期” 在关系模型中,我会有一个包含song_id和tag_id信息的连接模型。但是在像indexeddb这样的文档库数据库中,我会将标记及其信息直接存储在文档中。我想知道,如果我没有很多独特的标签,从长远来看,这是否不会导致DB bload 如果另一首歌需要一个标签,而这个标签已经在另一首歌中使用,我会有一个重复的标签 当然,我也可以在这里使用连接存储,但这还包括对2个表的手动获取 我对模型有几个问题: 我应该有一个歌曲和标签商店吗 如何

我有歌曲和标签。标签的类型可以是“录制位置”或“上次录制日期”

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

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

当然,我也可以在这里使用连接存储,但这还包括对2个表的手动获取

我对模型有几个问题:

  • 我应该有一个歌曲和标签商店吗
  • 如何批量更新附加到每首歌曲的标签
  • 我可能需要什么样的索引来加快速度

  • 我的主要功能是通过标记值(并按类型过滤)进行搜索。

    当人们不得不在关系数据库(如MySQL)和面向文档的数据库(如MongoDB)之间进行选择时,基本上面临着相同的问题。复制数据——更不用说密钥本身了——会占用空间,存储一个副本并使用外键显然更像是“第三种形式”

    也就是说,我在IndexedDB的工作中经历了这两方面。相信您所做的同样的事情——关于存储效率——需要与您实际访问数据的方式进行权衡。当您想要在IndexedDB中实现类似外键的模式时,它必然需要2个以上的对象存储,例如在底层文件系统上存储为两个单独的文件。这意味着对于每个需要外键数据(这里是标记)的查询,您必须至少有两个对象存储命中,可能有两个事务,并且,我假设,额外的io开销以及与之相关的其他开销


    我会采用面向文档的方法,并尝试使用诸如键速记之类的技巧(例如,“n”而不是“name”)来降低对存储的影响.

    当人们不得不在MySQL这样的关系数据库和MongoDB这样的面向文档的数据库之间进行选择时,你基本上面临着同样的问题。复制数据——更不用说密钥本身了——会占用空间,而且存储一个副本并使用外键肯定更像是“第三种形式”

    也就是说,我在IndexedDB的工作中经历了这两个方面。相信你做的同样的事情——关于存储效率——需要与你实际访问数据的方式进行权衡。当你想在IndexedDB中实现类似外键的模式时,它必然需要2个以上的对象存储,比如存储为两个单独的f这意味着对于每个需要外键数据(这里是标记)的查询,您必须至少有两个对象存储命中,可能有两个事务,并且,我假设,额外的io开销以及与这些相关的开销


    我会采用面向文档的方法,并尝试使用诸如键速记(例如“n”而不是“name”)之类的技巧来降低对存储的影响。

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

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

    您看到的最基本的模式是将歌曲存储为以下内容:

    { name: "Name of Song"
      id: <song id>
      tags: ["tag1", "tag2", "tag3"] }
    
    首先创建歌曲对象存储:

    var songs = db.createObjectStore("songs", "id");
    
    var tags = db.createObjectStore("tags", "name");
    
    然后创建一个多条目索引:

    songs.createIndex("tags", "tags", {multiEntry: true});
    
    然后创建标记objectStore:

    var songs = db.createObjectStore("songs", "id");
    
    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);
    }
    

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

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

    您看到的最基本的模式是将歌曲存储为以下内容:

    { name: "Name of Song"
      id: <song id>
      tags: ["tag1", "tag2", "tag3"] }
    
    首先创建歌曲对象存储:

    var songs = db.createObjectStore("songs", "id");
    
    var tags = db.createObjectStore("tags", "name");
    
    然后创建一个多条目索引:

    songs.createIndex("tags", "tags", {multiEntry: true});
    
    然后创建标记objectStore:

    var songs = db.createObjectStore("songs", "id");
    
    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);
    }