MongoDB设计方法及技巧

43次阅读

共计 2551 个字符,预计需要花费 7 分钟才能阅读完成。

MongoDB 是一种流行的数据库,可以在不受任何表格 schema 模式的约束下工作。数据以类似 JSON 的格式存储,并且可以包含不同类型的数据结构。例如,在同一集合 collection 中,我们可以拥有以下两个文档 document:

{
    id: '4',
    name: 'Mark',
    age: '21',
    addresses : [{ street: '123 Church St', city: 'Miami', cc: 'USA'},
        {street: '123 Mary Av', city: 'Los Angeles', cc: 'USA'}
    ]
}

{
    id: '15',
    name: 'Robin',
    department: 'New Business',
    example: 'robin@example.com'
}

为了能够充分利用 MongoDB 的优势,您必须了解并遵循一些基本的数据库设计原则。在讲解设计方法之前,我们必须首先了解 MongoDB 存储数据的结构。

一、 数据如何存储在 MongoDB 中

与传统的 RDBMS 关系型数据库不同,MongoDB 并没有表 Table,行 row 和列 column 的概念。它将数据存储在集合 collections,文档 documents 和字段 fields 中。下图说明了与 RDBMS 类比的结构之间的关系:

二、 数据库设计技巧和窍门

2.1. 规范化存储与非规范化存储

因为 MongoDB 使用文档来存储数据,所以理解“规范化存储“”和“非规范化存储”的概念非常重要。

规范化存储 :- 规范化意味着将数据存储到多个集合 collections 中,并在它们之间设计关联关系。数据保存之后,更新数据比较容易。但是在读取数据的时候,规范化存储的缺点就显现出来。如果要从多个集合 collections 查找数据,则必须执行多个查询,从而使读取数据的速度变慢。(比如:将网页标题、作者、内容分别存储到不同的 collections 中)

非规范化存储 :- 这种方式将若干对象数据,以嵌套的方式存储到单个文档中。它在读取数据的时候表现更好,但在写入时会变慢。这种存储数据的方式还将占用更多空间。(比如:将网页标题、作者、内容分别存储到同一个 collection 中)

所以在两种存储数据方式之间进行选择之前,先评估一下你的应用数据库的使用方式。

  • 如果您有一个不需要频繁更新的数据,更新的即时一致性不是很重要,但是在读取时需要良好的性能,那么非规范化可能是明智的选择。(比如:我们博客的博文,作者一旦保存之后,几乎就不在进行频繁的修改,但是面临着读者频繁的读取阅读操作)
  • 如果数据库中的文档数据需要不断的更新,并且您希望在写入时具有良好的性能,那么您可能需要考虑规范化存储。(比如:需要频繁修改数据的业务类系统)

2.2. 一对多关系

与 RDBMS 相比,在 MongoDB 中对“一对多”关系建模需要进行更细粒度的设计。许多初学者陷入将文档数组嵌入父文档中的陷阱。正如我们在上文中介绍的,知道何时进行规范化存储或非规范化存储是非常重要的。因此设计者需要考虑关系的基数是“一个对少数几个”还是“一个对多个”?每种关系将具有不同的建模方法。

例如:下面“一个对少数几个”的建模示例。最好的建模方法是在父文档(persopn)中嵌入几个(address):

> db.person.findOne()
{
  name: 'Mark Kornfield',
  ssn: '1223-234-75554',
  addresses : [{ street: '123 Church St', city: 'Miami', cc: 'USA'},
     {street: '123 Mary Av', city: 'Los Angeles', cc: 'USA'}
  ]
}

在“一个对多个”示例中,我们将考虑设计两个集合,即产品 products 集合和零件 parts 集合。每个零件都有一个“ObjectID”,该“ObjectID”将出现在产品集合的引用中。这样的设计可以让读写性能更高效。

> db.parts.findOne()
{_id : ObjectID('AAAA'),
    partno : '1224-dsdf-2215',
    name : 'bearing',
    price: 2.63

> db.products.findOne()
{
    name : 'car',
    manufacturer : 'Ford',
    catalog_number: 2234,
    parts : [     // array of references to Part documents
        ObjectID('AAAA'),    // reference to the bearing above
        ObjectID('F17C'),    // reference to a different Part
        ObjectID('D2AA'),
        // etc
]

2.3. 设计模式可视化

尽管 MongoDB 是 schemaless“无模式的”,但仍然存在将集合 collections 可视化为图表的方法。能够查看设计图,将对您理解和设计 MongoDB 的方式上产生重大影响。

DbSchema 是可以很好地完成可视化设计工作的一个工具。如下图所示,它将通过读取集合和文档来推导架构。此外,您只需单击就可以修改图中的对象。在 DbSchema 中,您还可以为 MongoDB 创建外键,当然仅在本地创建,只用于设计目的。

2.4. 智能索引

为了保持数据库的良好性能,有必要建立智能索引,这将简化写入和读取操作。知道 MongoDB 的索引优势和局限性非常重要,MongoDB 保留用于排序操作的内存限制为 32MB。如果你不使用索引,则排序时数据库将被迫将所有排序文档 hold 在内存里面,如果达到 32M 的限制,则数据库将返回错误或空集。

结论

对 MongoDB 的透彻理解与对数据库想要实现的目标的清晰了解是良好数据库设计的秘诀。

欢迎关注我的博客,里面有很多精品合集

  • 本文转载注明出处(必须带连接,不能只转文字):字母哥博客。

觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力!。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。

  • 《手摸手教你学 Spring Boot2.0》
  • 《Spring Security-JWT-OAuth2 一本通》
  • 《实战前后端分离 RBAC 权限管理系统》
  • 《实战 SpringCloud 微服务从青铜到王者》
  • 《VUE 深入浅出系列》

正文完
 0