交流群:462197261站长百科站长论坛热门标签收藏本站北冥有鱼 互联网前沿资源第一站 助力全行业互联网+
点击这里给我发消息
  • 当前位置:
  • MongoDB设计方法以及技巧示例详解

    前言

    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的透彻理解与对数据库想要实现的目标的清晰了解是良好数据库设计的秘诀。

    总结

    到此这篇关于MongoDB设计方法以及技巧的文章就介绍到这了,更多相关MongoDB设计方法及技巧内容请搜索北冥有鱼以前的文章或继续浏览下面的相关文章希望大家以后多多支持北冥有鱼!


    广而告之:
    热门推荐:
    PHP下载大文件失败并限制下载速度的实例代码

    1.问题: PHP在使用readfile函数定义下载文件时候,文件不可以过大,否则会下载失败,文件损坏且不报错; 2.原因: 这个是因为readfile读取文件的时候会把文件放入缓存,导致内存溢出; 3.解决:分段下载,并限制下载速度; <?php //设置文件最长执行时间 set_time_···

    浅析Angular2子模块以及异步加载

    用Angular2开发一个大型的应用,我们通常都需要分模块进行开发。例如将某一个功能的相关页面和功能放在一个模块里面,这样既可以实现系统的松耦合,给开发和后期的维护带来很大的便利。同时,对于子模块,我们还可以使用延时加载,这样可以减少初始加载的文件的大小。在这篇文···

    解决vue接口数据赋值给data没有反应的问题

    问题: 就是我在接口赋值给了data的变量,然后组件的效果没有出来(我的是旋转效果) 代码如下: data() { return { slides: [] } }, mounted() { this.request() }, methods: { request() { this.$http.post('xxxxxxxxxxxx', {}, (res) => { if (is.objec···

    纯js+css实现仿移动端淘宝网站的弹出详情框功能

    点击查看图片 代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar···

    基于jquery的手风琴图片展示效果实现方法

    本文实例讲述了基于jquery的手风琴图片展示效果实现方法。分享给大家供大家参考。具体实现方法如下: 代码运行效果如下图所示: index.html页面代码如下: 复制代码 代码如下: <!DOCTYPE html> <html class=''> <head>     <title>一···

    JavaScript实现GriwView单列全选(自写代码)

    在 GridView 里有一系列的 Checkbox ,要实现对其全选或全不选。开始在网上找了,但是参考的代码会全选 GridView 里所有的 Checkbox ,而我要的是单列全选。如图:  审核和权限是要分开的。  我自己写了 JavaScript 代码,贴出来供大家参考。 复制代码 代码如···

    NET页面导出Excel实例代码

    复制代码 代码如下:public static void CreateExcel(DataSet ds)        {            string filename = DateTime.Now.ToString("yyyyMMddHHmmssff") + ".xls";  ···

    总结一些PHP中好用但又容易忽略的小知识

    本文主要给大家总结了PHP中一些好用的小知识,分享出来供大家参考学习,下面来看看详细的介绍: 1、PHP函数之判断函数是否存在 当我们创建了自定义函数,并且了解了可变函数的用法,为了确保程序调用的函数是存在的,经常会先使用function_exists判断一下函数是否存在。同样的m···

    asp.net求3位不同数字的组合数

    简单的: 复制代码 代码如下:public partial class _Default : System.Web.UI.Page   {      string m1 = "";      protected void Page_Load(object&n···

    Springmvc异常映射2种实现方法

    请求出现 想要跳转到错误页面 就需要对springmvc进行配置 方法1:基于xml的配置 springmvc.xml配置类 <!--配置基于xml的异常映射--> <bean id="simpleMappingExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">···