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