1 schema设计原则

1.1 关系型数据库的三大设计范式

  • 第一范式(1NF)无重复的列
  • 第二范式(2NF)属性完全依赖于主键 [ 消除部分子函数依赖 ]
  • 第三范式(3NF)属性不依赖于其它非主属性 [ 消除传递依赖 ]

参考:https://blog.csdn.net/zhangminemail/article/details/56834253

1.2 选择Mongodb需要考虑

  • 读写比例、查询语句是否复杂、是否需要聚合函数、数据量
  • 数据基本单位是什么
    • RDBMS:表
    • 键值数据库:键指向的值
    • Mongodb:BSON文档
  • 是否需要强事务支持
  • 如何记录生成好的唯一ID或者主键,如:RDMS支持联合主键

1.3 schema基础

(1)文档设计

// 商品
{
_id: ObjectId("4c4b1476238d3b4dd5003981"), // 唯一ID
slug:"wheelbarrow-9092", // 唯一slug
sku:"9092",
name:"Extra Large wheelbarrow",
description:"Heav y duty wheelbarrow...",
details:{ // 嵌套文档
weight:47,
wight_units:"lbs",
model_num: 4039283402,
manufacturer:"Acme",
color:"green"
},
total_reviews:4,
average_review:4.5,
pricing:{
retail:589700,
sale:489700
},
price_history:[{
retail:529700,
sale:429700,
start:new Date(2010,4,1),
end:new Date(2010,4,8)
},{
retail:529700,
sale:529700,
start:new Date(2010,4,9),
end:new Date(2010,4,16)
}],
primary_category: ObjectId("6a5b1476238d3b4dd5000048"), // 一对多
category_ids:[ // 多对多
ObjectId("6a5b1476238d3b4dd5000048"),
ObjectId("6a5b1476238d3b4dd5000049")
],
main_cat_id: ObjectId("6a5b1476238d3b4dd5000048"),
tags:["tools","gardening","soil"]
}

(2)唯一slug

// http://domain.com/products/4c4b1476238d3b4dd5003981

// 展示相对友好一些
// http://domain.com/products/wheelbarrow-9092 db.products.createIndex({slug:1},{unique:true});

(3)内嵌文档

一般用于需要动态修改的内容

如:details为商品详情,每个商品包含的信息不一样。如果是U盘,还需要标识内存大小;如果是桌子,需要标识高度等。

(4)一对多

一个商品只对应一个主要类别,一个类别下有多个商品

(5)多对多

一个商品对应多个关联类别,一个类别有多个商品

(6)关系结构

类别文档可以复用,所以我们需要把它提取出来,而不是像商品信息那样直接嵌套在商品中。

// 类别文档  Home -> Outdoors -> Gardening Tools
{
_id: ObjectId("6a5b1476238d3b4dd5000048"), // Outdoors的子类别
slug:"gardening-tools",
name:"Gardening Tools",
description:"Gardening gadgets glore!",
parent_id: ObjectId("55804822812cb336b78728f9"),
// 冗余数据,用于快速查找
ancestors:[{
name:"Home", // 商品类别
_id:ObjectId("55804822812cb336b78728fa"),
slug:"home"
},{
name:"Outdoors", // Home的子类别
_id:ObjectId("55804822812cb336b78728f9"),
slug:"outdoors"
}]
}

(7)查询

// 查询该类别的所有商品
db.products.find({category_ids:ObjectId("6a5b1476238d3b4dd5000048")}) // 查询商品的所有类别信息
db.categories.find({_id:{$in:product['category_ids']}}) db.products.findOne({'slug':'wheelbarrow-9092'})

1.4 用户和订单:一个用户多个订单

(1)订单

// 订单
{
_id:ObjectId("6a5b1476238d3b4dd5000118"),
user_id:ObjectId("4c4b1476238d3b4dd5003981"), // 用户ID
state:"CART",
line_items:[{
_id:ObjectId("4c4b1476238d3b4dd5003981"),
sku:"9092",
name:"Extra Large Wheelbarrow",
quantity:1,
pricing:{
retail:5897,
sale:4897
}
},{
_id:ObjectId("4c4b1476238d3b4dd5003982"),
sku:"10027",
name:"Rubberized Work Glove, Black",
quantity:2,
pricing:{
retail:1499,
sale:1299
}
}],
shipping_address:{
street:"588 5th",
city:"Brooklyn",
state:"NY",
zip:11215
},
sub_total:6196
}

(2)用户

{
_id:ObjectId("4c4b1476238f3b4dd5000042"),
username:"test",
email:"test@test.com",
first_name:"Kyle",
last_name:"Banker",
hashed_password:"bd1cfa194c3a603e7186780824b04419",
addresses:[{
name:"home",
street:"588 5th",
city:"Brooklyn",
state:"NY",
zip:11215
},{
name:"word",
street:"1 E. 23th",
city:"New York",
state:"NY",
zip:10010
}],
payment_methods:[{
name:"VISA",
payment_token:"43f6ba6b8106fc7"
}]
}

(3)查询操作

// 查询用户的所有订单
db.orders.find({user_id:user['_id']}) // 查询订单的用户信息
db.users.findOne({_id:orders['user_id']})

1.5 评价

{
_id: ObjectId("4c4b1476238d3b4dd5000041"),
product_id: ObjectId("4c4b1476238d3b4dd5003981"),
date: new Date(2010,5,7),
title:'Amazing',
text:'Amzing.I love it.',
rating:4,
user_id: ObjectId("4c4b1476238f3b4dd5000042"),
username: "dgreethumb",
helpful_votes:3,
voter_ids:[ // 评论者的用户ID,阻止多次投票
ObjectId("4c4b1476238f3b4dd5000133"),
ObjectId("4c4b1476238f3b4dd5000003"),
ObjectId("4c4b1476238f3b4dd5001032")
]
}

2 核心概念:数据库、集合、文档

2.1 数据库

(1)数据库是集合和索引的命名空间和物理分组

(2)管理数据库

// 使用garden数据库
> use garden // 删除当前数据库
> db.dropDatabase() // 数据库当前状态
> db.stats()
{
"db": "garden",
"collections": NumberInt("4"),
"views": NumberInt("0"),
"objects": NumberInt("477985"),
"avgObjSize": 178.613015052774,
"dataSize": 85374342, // 数据库实际BSON大小
"storageSize": 30539776,// 额外的为集合增长预留的空间
"numExtents": NumberInt("0"),
"indexes": NumberInt("9"),
"indexSize": 10194944, // 索引总大小
"ok": 1
}

2.2 集合

(1)集合是结构或概念上相似的文档的容器。

(2)管理集合

// 显式创建集合
db.createCollection("users");
// 显式创建集合并指定分配空间的大小(字节)
db.createCollection("users",{size:20000}); // 集合名不能超过128个字符 // 重命名集合
db.products.renameCollection("store_products");

(3)固定集合

  • 指定集合的大小和集合的容量,类似一个队列,满了之后新的数据进来,最久的数据出去
// Max size:16384kB 数量:100
> db.createCollection("users.actions",{capped:true,size:16384,max:100})

(4)TTL集合

  • MongoDb允许在特定的时间后废弃文档数据。
// 一分钟失效,依赖索引机制
> db.reviews.createIndex({time_field:1},{expireAfterSeconds:3600})

(5)系统集合

> db.system.users.find()

> db.system.version.find()

2.3 文档

(1)类型

  • 字符串:UTF-8编码,不能由$开始,不包含圆点、不能包含null字节
  • 数字:double、int、long
  • 时间:从Unix纪元计时开始时间值使用64b整数的毫秒表示
  • 虚拟类型:
// 配合应用程序的converter进行转换
// 参考:https://www.cnblogs.com/linzhanfly/p/9578738.html
{
time_with_zone:{
time:new Date(),
zone:"EST"
}
}

(2)限制

  • BSON文档大小限制为16MB

  • 文档嵌套深度最大为100

  • 插入操作上限为16MB,即如果插入100W条数据需要分割为多个大量插入的文档组。

MongoDB实战读书笔记(二):面向文档的数据的更多相关文章

  1. 机器学习实战 - 读书笔记(13) - 利用PCA来简化数据

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第13章 - 利用PCA来简化数据. 这里介绍,机器学习中的降维技术,可简化样品数据. ...

  2. MongoDB实战读书笔记(一):JavaScript shell操作MongoDB

    1 基本增删改查 基本概念: 数据库:同关系型数据库 集合:类似关系型数据库的表 文档:类似关系型数据库的行 字段:类似关系型数据库的列 操作: insert:新增,若新增数据的主键已经存在,则会抛异 ...

  3. R语言实战读书笔记(二)创建数据集

    2.2.2 矩阵 matrix(vector,nrow,ncol,byrow,dimnames,char_vector_rownames,char_vector_colnames) 其中: byrow ...

  4. 机器学习实战读书笔记(二)k-近邻算法

    knn算法: 1.优点:精度高.对异常值不敏感.无数据输入假定 2.缺点:计算复杂度高.空间复杂度高. 3.适用数据范围:数值型和标称型. 一般流程: 1.收集数据 2.准备数据 3.分析数据 4.训 ...

  5. Java并发编程实战 读书笔记(二)

    关于发布和逸出 并发编程实践中,this引用逃逸("this"escape)是指对象还没有构造完成,它的this引用就被发布出去了.这是危及到线程安全的,因为其他线程有可能通过这个 ...

  6. iPhone与iPad开发实战读书笔记

    iPhone开发一些读书笔记 手机应用分类1.教育工具2.生活工具3.社交应用4.定位工具5.游戏6.报纸和杂志的阅读器7.移动办公应用8.财经工具9.手机购物应用10.风景区相关应用11.旅游相关的 ...

  7. RethinkDB是什么?—— 面向文档的NOSQL数据库,MVCC+Btree索引,pushes JSON to your apps in realtime采用push思路,优化的ssd存储

    RethinkDB是什么? RethinkDB是新一代的面向文档的数据库存储管理系统,原本是MySQL中针对SSD优化的一个存储引擎,后来脱离了MySQL成为了独立的系统. 数据如何存储在磁盘上? 数 ...

  8. 机器学习实战 - 读书笔记(07) - 利用AdaBoost元算法提高分类性能

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习笔记,这次是第7章 - 利用AdaBoost元算法提高分类性能. 核心思想 在使用某个特定的算法是, ...

  9. Spring实战读书笔记

    Spring实战读书笔记 Spring-core Spring之旅 - DI 和 AOP 概念 spring 的Bean容器 spring 的 核心模块 Spring的核心策略 POJO 最小侵入式编 ...

随机推荐

  1. CentOS7.4中配置jdk环境

    参考:https://www.linuxidc.com/Linux/2016-09/135556.htm 1.下载jdk 首先创建安装包放置位置 mkdir -p /usr/local/java 然后 ...

  2. Maven:element '******' cannot have character [children]

    此错误是由于XML文件的解析不正确造成的,因为在一个/某些标签之间存在奇怪和隐藏的字符. 这些字符可能来自网络上的复制粘贴.要解决此问题,请删除标签>标记定义之间的所有空格和换行符,然后将它们放 ...

  3. TypeError: Data location must be "memory" for return parameter in function, but none was given.

      在用truffle编译智能合约时,报错 TypeError: Data location must be "memory" for return parameter in fu ...

  4. Oracle常用操作表结构的语句

    首先,一起来认识几个单词. alter (改变) rename(重命名) column(柱子,用来表示列) modify(修改) comment on (评论) truncate (删减,截断) 1. ...

  5. 生成要发送到社区的内核补丁时如何指定发布的版本号(v2,v3...)?

    1. 生成一个补丁 git format-patch --subject-prefix=v2 -1 那么生成的patch文件就会有如下类似的信息: Subject: [v2] your descrip ...

  6. CImage中m_hBitmap!=0弹框报错

    见图.查资料说是图片打印出现问题. 我的代码流程主要是:读图到CImage中,然后转移到数组中,将原对象销毁,对图像内容处理后,保存. 原来没问题,在加了参数循环后报错. 考虑到是循环中一些因素初始化 ...

  7. github上有对应官方的各种模型

    https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo ...

  8. [Scikit-learn] 1.9 Naive Bayes

    Ref: http://scikit-learn.org/stable/modules/naive_bayes.html 1.9.1. Gaussian Naive Bayes 原理可参考:统计学习笔 ...

  9. swift 第二课 基础知识-2

    setter 和getter 的使用--> 适合计算使用 struct Point { var x = 0.0, y=0.0 } struct Size { var width = 0.0, h ...

  10. “但行好事 莫问前程 只问耕耘 不问收获 成功不必在我 而功力必不唐捐” 科技袁人·年终盛典——5G是科技时代非常重要的基础设施

    中国的科技实力:用数据对比展示当前中国整体科技实力在国际中的发展水平和未来的发展趋势. 主要分为基础研究和应用研究.其中基础研究通过论文数据进行对比展示,应用研究通过发明专利数据. 又分别结合当今中国 ...