我正在使用Mnesia和Erlang,但这个问题适用于像couchdb这样的任何键值数据库。

我正试图摆脱RDBMS思维过程,但我不能 围绕如何有效地实现这种模式。

假设我有一个用户记录,并且他有许多SubItemA记录,它有 许多SubItem B记录,所以:

User
-SubItem A
--SubItem B
...

我需要在SubItem B上运行查询。这样做是否有效 这个嵌套?我应该将它标准化以便更快吗?

我听说有些人使用数据复制,所以数据都是 嵌套和分开,这是荒谬的或者这实际上是有用的 一些案例?

有帮助吗?

解决方案

基本问题是,表现何时足够好

如果您确实需要详细检查每个SubItem B并且B的大小主导字典的整体大小,则表扫描用户字典不会产生过多的开销。

如果这还不够好,请将其标准化,以便在查询SubItem B时可以避免在所有User和SubItem A数据中读取数据。使用复合键,例如(UserId,SubItemAId,SubItemBId)如果表是有序的,则SubItem B字典可以进行范围查询。

如果这完全杀死了您的User / SubItem A查询性能,那么将数据重复视为最后的手段,因为它更容易出错。

其他提示

在CouchDb中,为每个SubItem发出视图条目是微不足道的。这样可以非常快速地访问这些项目。根据您在视图条目中的内容,您可以提供链接回父文档/子项所需的任何信息。

我不确定Mnesia,我只是开始使用CouchDB,但我的理解是在CouchDB中,因为你生成自己的自定义索引(“views”),你可以直接建立一个索引在这些子项目上。

示例地图功能:

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)
        }
    }
}

这实际上是SubItem B的索引列表,然后您可以根据您的选择剪切和拼接该列表。

实际上,这取决于您所使用的数据库。在CouchDB中,有一件事情会更好,而在Mnesia,其他东西会更好。你应该分区和分片数据吗?你应该以什么标准这样做?多少数据重复就足够了?

正如Jeffery Hantin所说,它需要进行一些实验和分析才能找到正确的解决方案。这就是说,大多数非关系型数据库都为您提供了解决问题所需的工具。你的部分是弄清楚每个人的权衡取舍,你可以接受与其他人的权衡。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top