MongoDB实战读书笔记(二):面向文档的数据
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实战读书笔记(二):面向文档的数据的更多相关文章
- 机器学习实战 - 读书笔记(13) - 利用PCA来简化数据
前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第13章 - 利用PCA来简化数据. 这里介绍,机器学习中的降维技术,可简化样品数据. ...
- MongoDB实战读书笔记(一):JavaScript shell操作MongoDB
1 基本增删改查 基本概念: 数据库:同关系型数据库 集合:类似关系型数据库的表 文档:类似关系型数据库的行 字段:类似关系型数据库的列 操作: insert:新增,若新增数据的主键已经存在,则会抛异 ...
- R语言实战读书笔记(二)创建数据集
2.2.2 矩阵 matrix(vector,nrow,ncol,byrow,dimnames,char_vector_rownames,char_vector_colnames) 其中: byrow ...
- 机器学习实战读书笔记(二)k-近邻算法
knn算法: 1.优点:精度高.对异常值不敏感.无数据输入假定 2.缺点:计算复杂度高.空间复杂度高. 3.适用数据范围:数值型和标称型. 一般流程: 1.收集数据 2.准备数据 3.分析数据 4.训 ...
- Java并发编程实战 读书笔记(二)
关于发布和逸出 并发编程实践中,this引用逃逸("this"escape)是指对象还没有构造完成,它的this引用就被发布出去了.这是危及到线程安全的,因为其他线程有可能通过这个 ...
- iPhone与iPad开发实战读书笔记
iPhone开发一些读书笔记 手机应用分类1.教育工具2.生活工具3.社交应用4.定位工具5.游戏6.报纸和杂志的阅读器7.移动办公应用8.财经工具9.手机购物应用10.风景区相关应用11.旅游相关的 ...
- RethinkDB是什么?—— 面向文档的NOSQL数据库,MVCC+Btree索引,pushes JSON to your apps in realtime采用push思路,优化的ssd存储
RethinkDB是什么? RethinkDB是新一代的面向文档的数据库存储管理系统,原本是MySQL中针对SSD优化的一个存储引擎,后来脱离了MySQL成为了独立的系统. 数据如何存储在磁盘上? 数 ...
- 机器学习实战 - 读书笔记(07) - 利用AdaBoost元算法提高分类性能
前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习笔记,这次是第7章 - 利用AdaBoost元算法提高分类性能. 核心思想 在使用某个特定的算法是, ...
- Spring实战读书笔记
Spring实战读书笔记 Spring-core Spring之旅 - DI 和 AOP 概念 spring 的Bean容器 spring 的 核心模块 Spring的核心策略 POJO 最小侵入式编 ...
随机推荐
- pwn学习日记Day9 基础知识积累
知识杂项 libc是Linux下的ANSI C的函数库. LOOKUP函数 数组形式:公式为= LOOKUP(lookup_value,array) 式中 array-包含文本.数字或逻辑值的单元格区 ...
- NMS(非极大值抑制)实现
1.IOU计算 设两个边界框分别为A,B.A的坐标为Ax1,Ax2,Ay1,Ay2,且Ax1 < Ax2,Ay1 < Ay2.B和A类似. 则IOU为A∩B除以A∪B. 当两个边界框有重叠 ...
- 第二章 c语言概述
一.#include指令和头文件 1.#include C预处理指令,C编译器在编译前对源代码做一些准备工作 2.stdio.h标准输入输出头文件,提供了关于输入输出的信息供编译器使用 头文件包含了建 ...
- jupyter notebook 安装代码提示功能
我的是在anaconda中的root环境下运行以下命令,在其他环境下发现没有效果 1 pip install jupyter_contrib_nbextensions jupyter contrib ...
- Flume-自定义 Interceptor(拦截器)
使用 Flume 采集服务器本地日志,需要按照日志类型的不同,将不同种类的日志发往不同的分析系统. 在实际的开发中,一台服务器产生的日志类型可能有很多种,不同类型的日志可能需要发送到不同的分析系统. ...
- RecyclerView下拉刷新和上拉加载更多实现
RecyclerView下拉刷新和上拉加载更多实现 转 https://www.jianshu.com/p/4ea7c2d95ecf 在Android开发中,RecyclerView算是使用频率非 ...
- kotlin之null值安全性
var a: String =null // 编译错误 var a: String? =null // 编译通过 要允许null值, 需要将变量声明为可为null的字符串类型:String? fun ...
- Qt编写安防视频监控系统10-视频轮询
一.前言 视频轮询在视频监控系统中是一个基础的核心功能,尤其是上了大屏以后,这个功能是必须的,根据预先设定的轮询间隔逐个加载视频到预先设定的通道画面数中,轮询间隔.轮询画面数.轮询采用的码流类型(主码 ...
- kubernets部署sock-shop微服务电商平台(11)
一.准备条件 确保kubernetes可以访问:reg.yunwei.edu镜像库(vim /etc/hosts) 需要准备镜像: [root@cicd sock-shop]# cat com ...
- php文件断点上传
前段时间做视频上传业务,通过网页上传视频到服务器. 视频大小 小则几十M,大则 1G+,以一般的HTTP请求发送数据的方式的话,会遇到的问题:1,文件过大,超出服务端的请求大小限制:2,请求时间过长, ...