Review
- DBMS & CRUD
- How to store
- 正确性(了解,心里有概念涉及)
- 可用性(了解,心里有概念涉及)
MongoDB Raft protocol
Read Preference
Write Preference
读多数落实 or 性能可能读新的。
本讲:数据库设计(掌握,即如何使用数据库构建App?Overview
Step1.存什么
Step2.怎么存
Step3.如何优化(Index如何设置/如何访问:Read Concern/Write Concern)以Blog(App)为例子
一般互联网应用的设计过程
Step1. UI ,做UI 假功能给用户使用
UI:
UI旁边的那个图是最常访问的页面。
以上图为例子,数据库要怎么存
一个app一个DB
如何将信息归类到DB呢?文档数据库设计初衷:Doc<->Object;Collection<->Class;(这个千万别忘了)
DB设计的规定动作:look for Conceptional Model
先找概念(class/Object),找关系,再讨论怎么存
####先找概念(class/Object)
以此例子 - author
- blog
- comment
找关系
The following 存储方式叫Schema:数据模式。
数据模式是数据库设计的核心
- Author:{name, date of Birth,Ranking….}
- Blog{author:OID}
- Comment{author:OID,blog:OID}
用户间关系如何存储?(为了符合我那个UI设计,即主页上右侧要显示我followee的文章)
一种是存followee(我关注的人)/一种是存follower。可以从UI走一遍看我要获取这些信息访问数据的代价。
所以,上面这种schma是不可取的。
另一种schema
Author {name,
date of birth,
[followee],[follower],
[blog{title,date,contne},[comment{title,content,author}] ]}
这种访问代价:Author:1+|Followee|;(First Page)//
但如果访问了第二个页面,不知道该页面的id,只知道followeeID,要找到那篇文章,找到以后,获得comments.
这种schema每一个doc的1很大,但总是finite的。
这种有什么问题吗?
当我要添加新的文章或comment的时候的访问代价?
第一个schema只要插入一个新的document. 另一种schema需要我在author这个巨大的文档上修改。
修改相当于将文档拿出来,改之后重写一遍。
如何降低综合代价?(平衡第一/二种schema)
如何重新设计?
第一种schema:
- 不只存follower/followee的一种,而是将两种都加进去(重复存储了作者间的关系,只需要改两次)
- 如何获取我followee的blog:在author里新增blog:OID/commet:OID
这种改动的核心在于,通过增加冗余(additional info:additional的理解在于,减少这些信息也不会破坏性能的完整性)来获取性能trade off。
问题:同样信息不同地方重复,更改的代价也上升了。
我们可能需要增加一个collection
FirstPage{author:[blog{title,content}]}这个页面被调用的次数 毕竟太多了。
发表文章的频率肯定远低于firstpage打开的频率。
然后,我们还可以将简短的comment放到blog里:
Blog:{title,date,author:OID,[comment:OID]}
最终schema
First Page/Author/Blog
设计process
- 直观
- come up with conceptional model
- 映射conceptional model
- 调整,综合trade-off
首先得到conceptional model,再得到raw design,再看应用UI是如何设计的,考虑访问数据库的性能,优化。
优化:
Class 的合并与嵌入// 记录Objects间的关系的方式是可以调节的//通过添加冗余信息获取性能trade-off。
设计模式
冗余设计看成物理设计。
对象之间的关系
1:M
嵌入式存法:one-to-few被嵌入的不能太多,所以叫one-to-few.这也是comments数量不能太多的。
on the other hand, blog 很多,blog comments也很多,即第一类schema的嵌入代价太高了。
One-to-many
blog里存[comment:OID]
Many-to-one
comment单独,存blogOID
Two-way referencing
两边都要改
如何选择?通过哪种对象访问哪种对象
通过blog访问comments,one-to-many.
范式化与逆范式化
定义
信息不冗余。
冗余
我们却会在数据库里有意识的加入逆范式化,只为了提高其性能。
关键在于如何增加与利用冗余
Many-to-One Denormalization
DB design的经验总结
MongoDB manual 如何利用其做DB design.