`
风雪涟漪
  • 浏览: 508662 次
  • 性别: Icon_minigender_1
  • 来自: 大连->北京
博客专栏
952ab666-b589-3ca9-8be6-3772bb8d36d4
搜索引擎基础(Search...
浏览量:9069
Ae468720-c1b2-3218-bad0-65e2f3d5477e
SEO策略
浏览量:18482
社区版块
存档分类
最新评论

MongoDB Schema Design 数据库设计

阅读更多


介绍

使用MongoDB设计数据库,就不要按照关系型数据库的思维来做,如范式化数据。因为MongoDB不支持服务端的join查询。一般来说,在对于顶端的对象都要用单独的collection进行存储。

当然不需要望每个对象都要创建一个collection。可替代的策略是使用嵌入对象(embed object)。

例子,在下面的图,有两个collection。

分别是student和courses。

student document嵌入了address对象并和score document。并且有个引用到courses。

相比较关系模型,一般会把score单独存储到一张表中并且有个外键关联到student。

Embed vs. Reference(内嵌VS引用)

MongoDB模型设计关键问题在于是单独创建collection,还是作为内嵌对象?

在关系型数据库中,每个子元素都要单独创建一张表。 在MongoDB中,这并不推荐。

内嵌对象性能要更为高效。 数据分配在了硬盘上; 客户端和服务器通信的消耗基本不存在。

因此 "为什么我不需要内嵌对象?"

为什么引用非常慢?让我们考虑这个student的例子。如果我们有个student对象并执行

print( student.address.city );

这个操作用内嵌对象的话会非常快速并且如果student在RAM中,这个内嵌对象同样也在RAM中。

print( student.scores[0].for_course.name );

如果是第一次访问course。shell或者驱动必须执行下列查询。

// 伪代码!
student.scores[0].for_course = db.courses.findOne({_id:_course_id_to_find_});

每个引用遍历都对于数据库是一个查询。 这个collection在_id上有个索引。 

这个查询还是非常快的。然而, 即使所有的数据在RAM中,从应用服务器到数据库之间的通信也会有延迟。

一般来说,期望在RAM中1ms命中缓存。如果我们循环1000个student,查询每个student应用就会很慢了。

超过1分钟。 然而, 如果我们紧紧需要查询一个单独的元素,时间就是1ms 并且页面读取是完全可以接受的。

(注意如果在db缓存中, 返回1000student实际时间要小于1分钟)

下面是一些使用内嵌对象和引用的规则:

  • 上层的对象。一般都是独立的collection。
  • 对象详细的线性元素一般用于内嵌。
  • 如果对象和对象的关系是包含关系,应该用内嵌。
  • 多对多关系用引用。
  • Collection存入的对象较少比较适合做独立的collection。
  • 这样整个collection可以快速缓存应用服务器的内存中。
  • 内嵌对象更难关联它上层的对象。还不能使用DBRef用在内嵌对象上。
  • 要获取内嵌对象系统级别的视图更为困难。例子, 如果score不是内嵌,
  • 就更容易查询所有学生中中,100个高分数。
  • 如果内嵌对象很大(许多M), 你可能会遇到单个document容量的限制。
  • 如果性能是个问题,那么就用内嵌。

示例

让我们看看一些示例

  • Customer / Order / Order Line-Item
    • orders 应该是一个collection。 customers 是一个 collection.
    •  line-items 应该是order的一个内嵌数组对象。
  • Blogging system.
    • posts 应该是一个  collection. post author 可以是一个 独立的 collection, 
    • 或者如果仅仅是一个email地址,可以作为posts的字段。comments 应该是posts中的内嵌对象。

索引的选择

第二个比较重要的是索引的选择. 作为通用规则,如果在关系型数据库需要添加索引,那么MongoDB也一样。

  • _id 字段自动索引。
  • 查询的字段应该索引。
  • 排序字段需要索引。

 MongoDB profiling facility 提供了你应该添加索引的信息。

注意的是,添加索引会降低写入速度,对于读取频率高的collection可以创建多点的索引。

写频率较高的话,索引开销就很昂贵。


分享到:
评论

相关推荐

    基于net的超市管理系统源代码(完整前后端+sqlserver+说明文档+LW).zip

    功能说明: 环境说明: 开发软件:VS 2017 (版本2017以上即可,不能低于2017) 数据库:SqlServer2008r2(数据库版本无限制,都可以导入) 开发模式:mvc。。。

    LABVIEW程序实例-公式节点.zip

    labview程序代码参考学习使用,希望对你有所帮助。

    大米商城开源版damishop(适合外贸)

    大米外贸商城系统 简称damishop 完全开源版,只需做一种语言一键开启全球133中语言自动翻译功能,价格实现自动汇率转换,集成微信支付宝 paypal以及国外主流支付方式,自带文章博客系统。 软件架构 基于MVC+语言包模式,增加控制台,API导入产品方便对接其他系统(带json示例数据)。 使用要求 PHP7.4+ MYSQL5.6+ REDIS(可选) 安装方法 composer install 打开安装向导安装 http://您的域名/install 特色 1、缓存层增加时间与批量like删除 2、API产品导入方便对接其他系统 3、增加控制台命令行,命令行生成语言翻译包 4、后台一键开启自动翻译模式,支持全球133中语言,由于google代理翻译需要收费,这个功能需要付费。 5、可选购物车与ajax修改购物车产品 6、一键结算checkout 7、增加网站前台自定义路由 方便seo 更新日志 v3.9.7 集成鱼码支付接口,方便个人站长即使收款到账使用 v3.9.3 更新内容 1:增加ueditor与旧编辑器切换 2:增加可视化布局插

    LABVIEW程序实例-通过全局变量接收数据.zip

    labview程序代码参考学习使用,希望对你有所帮助。

    LABVIEW程序实例-日历控件.zip

    labview程序代码参考学习使用,希望对你有所帮助。

    毕设和企业适用springboot人工智能客服系统类及旅游规划平台源码+论文+视频.zip

    毕设和企业适用springboot人工智能客服系统类及旅游规划平台源码+论文+视频

Global site tag (gtag.js) - Google Analytics