Database design 如何设计一个模式来有效地查询键值数据库中的嵌套项?
我在Erlang中使用Mnesia,但这个问题适用于任何键值数据库,如couchdb等 我试图摆脱RDBMS的思维过程,但我做不到 我想知道如何有效地实现这种模式 假设我有一个用户记录,他有许多子项a记录,这些记录 多个子项B记录,因此:Database design 如何设计一个模式来有效地查询键值数据库中的嵌套项?,database-design,erlang,schema,couchdb,mnesia,Database Design,Erlang,Schema,Couchdb,Mnesia,我在Erlang中使用Mnesia,但这个问题适用于任何键值数据库,如couchdb等 我试图摆脱RDBMS的思维过程,但我做不到 我想知道如何有效地实现这种模式 假设我有一个用户记录,他有许多子项a记录,这些记录 多个子项B记录,因此: User -SubItem A --SubItem B ... 我需要在子项B上运行查询。在子项B可用时执行查询是否有效 这是嵌套的吗?我应该把它正常化,这样会更快吗 我听说有些人使用数据复制,因此数据是 嵌套和分离,这是荒谬的,还是实际有用 一些案例 根本
User
-SubItem A
--SubItem B
...
我需要在子项B上运行查询。在子项B可用时执行查询是否有效
这是嵌套的吗?我应该把它正常化,这样会更快吗
我听说有些人使用数据复制,因此数据是
嵌套和分离,这是荒谬的,还是实际有用
一些案例 根本的问题是,什么时候的表现足够好 如果确实需要详细检查每个子项B,并且B的大小决定了字典的总体大小,那么扫描用户字典的表不会产生过多的开销 如果这还不够好,请对其进行规范化,以便在查询子项B时避免预先读取所有用户和子项A数据。如果表已排序,则在子项B字典中使用复合键,例如(UserId、SubItemAId、SubItemBId),以便执行范围查询
<>如果这完全杀死了你的用户/子项的查询性能,那么考虑数据复制作为最后的手段,因为它更容易出错。 <>在CouCHDB中,为每个子项发射视图条目是微不足道的。这将使您能够非常快速地访问这些项目。根据您在视图条目中的内容,您可能会提供链接回父文档/子项所需的任何信息。我不确定Mnesia,我只是刚刚开始使用CouchDB,但我的理解是,在CouchDB中,由于您生成自己的自定义索引(“视图”),您可以直接在这些子项上建立索引 映射函数示例:
function(doc) {
for(var i in doc.subitems_a) {
var subitem_a = doc.subitems_a[i];
for(var j in doc.subitems_a[item_a].subitems_b) {
var subitem_b = subitem_a.subitems_b[j];
emit(subitem_b, doc)
}
}
}
这实际上是子项B的索引列表,然后您可以根据自己的选择从该列表中剪切和拼接。实际上,我认为这取决于您使用的数据库。在CouchDB中,一件事情会更好地工作,而在Mnesia中,另一件事情会更好。你应该对数据进行分区和切分吗?你应该根据什么标准这样做?有多少数据重复就足够了 正如杰弗里·汉廷(Jeffery Hantin)所说,需要一些实验和分析才能找到正确的解决方案。也就是说,大多数非关系数据库都为您提供了解决问题所需的工具。你的一部分是找出每一个的权衡,以及你可以接受的与其他人的权衡