Database design 与NoSQL数据库的多对多关系

Database design 与NoSQL数据库的多对多关系,database-design,nosql,many-to-many,taxonomy,document-oriented-db,Database Design,Nosql,Many To Many,Taxonomy,Document Oriented Db,我想用NoSQL数据库为node.js应用程序实现一个分类结构(地理术语)。我和MySQL有着相似的分类结构,但现在是时候向前迈进,学习一些新的东西了,所以我决定尝试一种不同的方法,在我的测试应用程序中使用NoSQL(面向文档)。分类结构很简单-有五个不同的级别:国家(即英国)→ 地区(英格兰)→ 郡(默西塞德)→ 城市/城镇/村庄(利物浦)→ 城市的一部分(托克特) 显而易见的选择是使用树形结构,但问题在于细节——历史上一些城镇属于其他县。这个想法是用这些术语标记出生在某些城市或城镇的人,然后

我想用NoSQL数据库为node.js应用程序实现一个分类结构(地理术语)。我和MySQL有着相似的分类结构,但现在是时候向前迈进,学习一些新的东西了,所以我决定尝试一种不同的方法,在我的测试应用程序中使用NoSQL(面向文档)。分类结构很简单-有五个不同的级别:国家(即英国)→ 地区(英格兰)→ 郡(默西塞德)→ 城市/城镇/村庄(利物浦)→ 城市的一部分(托克特)

显而易见的选择是使用树形结构,但问题在于细节——历史上一些城镇属于其他县。这个想法是用这些术语标记出生在某些城市或城镇的人,然后用地理标记过滤他们,因此我必须尊重这样一个事实:在一些人出生时,利物浦或曼彻斯特(以及其他地方)是兰开夏郡的一部分。否则,任何用户使用my geo filter获得的结果都将不正确

约翰·多伊1957年出生在兰开夏郡的布莱克本。保罗·布朗1960年出生于利物浦(兰开夏郡,现为默西塞德郡)。5年后,乔治亚多伊(nee Jones)出生在威拉尔(柴郡,现在的默西塞德郡)。他们的儿子林戈1982年出生在利物浦(当时是默西塞德郡)

约翰出生于兰开斯特郡,保罗出生于兰开斯特郡和默西塞德郡,佐治亚州同时来自柴郡和默西塞德郡,林戈出生于默西塞德郡。所以当我按县搜索时,它们应该被相应地分类。但随着一对多的简单结构,遵循国家的现代结构,他们将永远不会被过滤,因为他们应该是

如何使用NoSQL(首先是面向文档的)解决方案来实现集合结构的复杂性?我在谷歌上搜索了一下,在堆栈上做了一些研究,但仍然不知道下一步该怎么做。在我看来,有几种可能的解决方法:

  • 使用类似SQL的数据结构:

    {
        {'name': 'United Kingdom', 'unique_id': 1},
        {'name': 'England', 'unique_id': 2, 'parents': [1]},
        {'name': 'Merseyside', 'unique_id': 3, 'parents': [2]},
        {'name': 'Lancashire', 'unique_id': 4, 'parents': [2]},
        {'name': 'Liverpool', 'unique_id': 5, 'parents': [3, 4]},
    }
    
  • 将树结构与一些引用一起使用:

    {    
        {'name': 'United Kingdom', 'unique_id': 1
            {'name': 'England', 'unique_id': 2]
                {'name': 'Merseyside', 'unique_id': 3]
                    {'name': 'Liverpool', 'unique_id': 5, 'alternate_parents': [4]},
                },
                {'name': 'Lancashire', 'unique_id': 4},
            },
        },
    }
    
  • 使用无引用的树结构(一对多)并手动向文档添加“备用父级”标记:

    {    
        {'name': 'United Kingdom', 'unique_id': 1
            {'name': 'England', 'unique_id': 2]
                {'name': 'Merseyside', 'unique_id': 3]
                    {'name': 'Liverpool', 'unique_id': 5},
                },
                {'name': 'Lancashire', 'unique_id': 4},
            },
        },
    }
    
  • 坚持使用SQL

  • 尝试实现无数据库分类法
  • 请给我关于那件事的建议。我对任何NoSQL都是新手(目前我还没有设计过这样的数据库),所以我有一个真正的设计问题

    我是stack的新手,所以如果我在这篇文章中做错了什么,请随时纠正我:)谢谢

    编辑 我选择了@Jonathan answer作为解决方案。我认为它更适合我的需要(我的数据库中将存储其他文档并用这些术语标记它们),尤其是@Valentin建议的mapReduce功能


    但是,如果你的应用程序不需要文档集合,@Philipp建议的图形数据库(基于关系而非文档)可能是最好的解决方案。

    首先,如果你不熟悉基本原理,就很难在NoSQL和SQL数据库之间进行选择。如果这是您存储的唯一数据,请使用关系型(SQL)。如果有更多的数据(我假设是这样),并且需要更多的交织模式,那么就直接使用NoSQL

    我会在这个问题上采取关系化的方式,以避免它变得太复杂。。。开始几次收集;一个用于国家、地区等。不要被劝阻在NoSQL数据库中执行关系(SQL)类型的模式;大多数情况下,它们是最好的解决方案

    然后,在每个子组中,都有一个名为父组的字段

    例如:

    {
        {'name': 'United Kingdom'},
        {'name': 'United States'}
    }
    
    {
        {'name': 'England', 'parent': 'United Kingdom'},
        {'name': 'California', 'parent': 'United States'}
    }
    
    这样,您的数据集就不会嵌套到无法管理返回数据的地步。然后你可以抓取国家和相应的地区。。。轻松地等着

    祝你好运

    编辑:回答OP的问题:

    (首先,我推荐MongoDB——这是一个很好的解决方案。)

  • 因为当您开始使用MongoDB时,您会意识到它将数据并排存储在硬盘上。如果你编辑了这样一个巨大的记录,它很可能会被推到磁盘的后面,使你的硬盘类似于瑞士奶酪。一旦你到了那个点,你必须做一次修复,以使它再次浓缩。此外,这样在应用程序中更容易分离数据,这样,如果需要处理数据,就不必将其应用于整个对象。我假设您将拥有一个大型数据集,因为世界上有许多不同的位置

  • 不要太担心那种事。如果您计划经常更改名称,则可以将ID用于父项,并将子项与ID匹配。我这样做是因为我假设您不需要更改位置数据库

  • 我将使用嵌套文档来存储多个父对象,而不是数组。这样,它可以更容易地查询和索引。我会采用以下方法:

    {
        {
            'name': 'England,
            'parent': {
                1: 1,
                568: 1
            }
         }
     }
    

  • 这样,你就可以利用你的索引思想,找到db.region.$.568=
    1

    由于你的评论,我假设你说“NoSQL”时是指“MongoDB”。有许多其他数据库技术通常被称为NoSQL,它们完全不同,但这一种似乎就是您所指的

  • 这不是一个好主意,因为要获得整个分类链,您需要执行多个数据库查询,这通常应该避免

  • 三,。一个巨大的文档树也不是一个好主意,因为MongoDB对每个文档的限制是16MB。当您创建巨大的整体文档时,您可能会达到该限制

  • 我认为MongoDB可能不是您用例的最佳解决方案。你考虑使用A了吗?MongoDB针对独立的自包含文档进行了优化。但问题的焦点