当前课程知识点:软件工程 > 第11章 软件系统设计 > 11.8 数据库选择策略 > 讲授视频
大家好
今天我们的题目是
数据库存储的策略选择
那么什么是数据库
维基百科中的解释
A database is an organized
Collection of data
简单地来说
数据库就是对数据的管理
在实际业务中
一般包括对数据的增 删
改 查等操作
更多的也会包括
数据管理中
对用户的访问权限管理
数据的持续化
以及分布式等不同方案的选择
这里我们简单地举一个
数据库的例子
假设有一个用户管理系统
它需要存储如上
这样一个用户信息表
同时它也还要支持
对id 用户名
昵称的查找功能
以及能够对密码和昵称进行修改
还要能够添加新的用户
删除原有的用户
在实际的应用场景中
我们还需要保证
这几个功能
能够在尽量少的时间内
得到响应
以及使用尽量少的存储空间
来使得能够使用一台服务器
就能够实现
这样一个用户管理系统
试想一下
如果我们能够
有这样一个超级数据库
它可以存储任意大小的数据
以及数据之间的关系
同时它还能够提供最快的
增 删 改 查操作
那么实际上
一切数据库的问题
就不再是问题了
然而理想是美好的
现实往往很残酷
我们不能够拥有无穷的存储空间
也没有光速的响应时间
我们有的
仅仅是一台500G的磁盘
4G内存和I3处理器的电脑
那么在实际应用场景中
如何选择合适的数据库
才能够最大化
我们的服务器的性能
得到最优化的输出结果呢
这就是我们今天希望能够
简单介绍的一个问题
仍然回到之前那个简单的例子
这是一个用户管理系统
它至少应该具备
如下几个基本功能
我们简单地对其抽象
事实上就是数据应该怎么存
数据应该怎么查找
如何修改数据
以及如何添加和删除数据
这几个基本的功能
在进行数据库的选择之前
我们需要
对数据库的一些基本性质
有所了解
下面对现有的数据库
进行一些简单的性质分类
首先数据库的数据应该怎么存
既可以分为持续化存储
与内存数据库
顾名思义
持久化存储
指的就是将数据持续化在磁盘上
内存数据库
指的则是数据直接存储在内盘中
数据存储
还能分为单机与分布式
单机也就是一台服务器
分布式指的则是
可能是一个数据库集群
或者是多台服务器
数据如何进行增删改查
实际应用中
可以分为关系查找
和Key—Value查找的形式
这里简单做一个介绍
就像之前
需要保存那张用户信息表
关系查找只单纯地通过用户ID
对用户名 密码 昵称进行查找
Key—Value查找则有所不同
可能一个用户ID
对应的是一个
可以随时改变的文档类型
也就是如下这一张表
一个用户ID可能对应了用户密码
也有可能对应了
用户名 密码 昵称
甚至还有可能是其他属性
这是关系查找
与Key—Value查找的区别
在数据库选择中
操作是否安全
也是一个重要的性质
这其中涉及到了事务
以及一致性
和最终一致性的问题
之后还会简单地介绍
数据库使用过程当中
可用性
是我们需要十分注意的一点
如果数据库故障了
应该如何恢复
大部分的现有数据库
都具有了一个简单的
故障恢复功能
下面我们简单介绍一下
数据库的事务一致性
这两个性质
事务
这往往应用在金融交易当中
比如银行转帐业务
我们想象这样一个场景
A需要银行转帐给B一定的金额
可以简单分为这样几个步骤
A首先查询自己银行帐户的余额
输入转帐的额度
然后银行从A帐户中删除金额
给B帐户增加金额
B帐户再确认金额是否到帐
那么这中间如果某一步出错了
如果银行从A帐户删除金额
这一步没有成功
而直接给B帐户增加了金额
那么银行是否会产生一定的损失
而同时如果两个人使用A帐户
同时进行转帐
是否会出现银行对A帐户
只进行一次删除金额的查询
那么事务就能够保证了
操作序列的完整执行
也就是如上这样一个
完整的多步流程
要么被同时执行
要么都不执行
这在涉及金融的业务中尤为重要
一致性
通常分为实时一致性
与最终一致性
我们可以简单想象这样一个场景
A在微信朋友圈中
发布了一张照片
如果同一时间
他的所有好友都能看到
那么指的就是实时一致性
而他发布了一张照片之后
他的好友
最会在未来的某一个时刻看到
比如1分钟以后
1个小时以后
或者明天
反正他的好友总是会看到的
这指的就是最终一致性
最终一致性
与实时一致性的一个最大区别
在于是否保证
一定要在同时
能够被他的所有好友看到
实时一致性在应用中
往往极度消耗计算资源
在实际的场景中
通常会采用最终一致性
来进行效率上的
一定程度上的妥协
接下来
我们简单地介绍一下
如今最流行的几种数据库
Mysql是当前最流行的
开源关系型数据库
它十分地简单易用
同时拥有大量的第三方插件
社区活跃 文档十分丰富
上手也比较简单
作为关系型数据库
它支持快速的复杂查询操作
同时也有完整的事务机制
和非常高的安全性
mongoDB是当前
最流行的非关系型数据库
其模式自由
可以自由地根据需要
随时修改文档格式
就像我们之前介绍的
Key—value的文件格式
同时其还支持海量数据的查询
与插入
支持完全的索引
作为流行的分布式数据库
它还自动支持
分片等分布式操作
具有良好的故障恢复与备份功能
良好的文档与社区环境
也使得它的学习成本很低
需要注意的是
与Mysql对比
它也有着很大的不同
mongo在使用过程中
需要占用很大的空间
来保存它的索引
同时mongo作为非关系型数据库
也不支持事务操作
只具有最终一致性
因为mongo是一个新兴的
非关系型数据库
其社区尚不很成熟
在较高安全的级别的应用中
也无法得到保证
redis作为近年兴起的
内存数据库的代表
其把数据直接存储在内存之中
使得我们对数据的访问非常快
redis在保证访问速度的同时
还支持持续化的存储
其本身也支持了
非常多的数据结构
比如列表 字典
在实际应用场景中
与Mysql 与mongo
有着非常大的不同
作为内存数据库
数据直接保存在内存中
是十分不可靠的
任何的重要数据
都不应该存储在内存数据库中
因为一旦当机
其内存数据库是不可恢复的
同时redis也并不支持
完整的事务实现
不适合作为
安全性较高的场景应用
回到我们最初的问题
如何对数据库进行选择
对具体的实际问题
我们需要具体分析
在实际应用当中
是否使用现有的几种数据库
就能够完全满足我们的需求了呢
事实上大部分应用场景
是这样的
比起我们只需要选择Mysql
mongo中的一种
就已经能够满足
我们大部分的应用了
然而如果不能够
满足我们的应用的要求
那么我们需要分析出
具体是什么问题
构成了我们应用的阻碍
是访问的需求量过大
安全一致性要求高
或者是实施一致性的需求
这个时候我们可以两方面
来考虑这样一个问题
第一方面
是不是我们的业务过于复杂
我们可以尝试拆分业务
不同的场景采用不同的数据库
例如
涉及财务金融等信息
需要使用事务的性质
那么可以采用Mysql
而大量的用户数据需要保存
需要设计到大量的查询
那么mongo有其优势
需要非常快的反应速度
比如网站首页
需要在最快的时间内得到响应
那么我们可以使用redis
把这些首页放在内存之中
如果业务没有办法拆分
同时问题比较少见
还没有第三方开源的一些
现有的代码可以使用
那么我们完全可以
在开源的代码基础上
进行二次开发
这里以豌豆荚 豆瓣
淘宝等的尝试为最好的一些例子
而在实际应用当中
数据库实现成本
也是我们
非常需要考虑的一个问题
有时候我们往往需要考虑到
程序员具体熟悉哪一个数据库
这样可以降低我们的学习成本
应用中是否需要支持分布式
那么mongo
因为自动支持了分布式
就有其优势
是否现代的业务中
不确定业务模型
比如很多初创企业
并不知道他们以后未来
会发展成什么样子
那么mongo支持自由的模型模式
就能很好地满足了这一需求
接下来我们通过
几个简单的案例分析
来学习掌握一下
这样一个数据库选择的技巧
首先考虑一个
简单的社交网站案例
它要求的功能是用户登录
分享等功能
要求的并发
是每秒同时在线的人数
能够支持100人左右
我们来简单分析一下
它首先需要用户数据
能够得到持续化的存储
因此内存数据库不被我们所考虑
其对用户的安全性最高
不要事务机制
那么mongo是可以使用的
查询并发量也比较小
这里我们以mysql2000的并发
和mongo5000的并发来做估计
会发现这两个都是可以的
然而业务使用模型比较复杂
作为社交网络
它的业务随时可能会有所改变
而这方面
mongo是有优势的
综合以上几点
我们建议使用mongo
来作为数据库
在考虑这样一个新闻网站
它没有用户登录与交互
仅仅只是用于展示新闻的内容
但是
它需要支持很大的用户访问量
我们这里以每秒万人的访问量
来作为一个基准考虑
首先我们来分析一下
它没有用户数据
没有复杂的关系业务
而它的访问量非常的大
mongo和mysql
都可能不太适用于
如此大的信息访问
内容单一
也就是新闻的内容
基本上是不会进行再次修改的
因此我们可以考虑内存数据库
安全性要求也不是那么高
因此内存数据库
是我们完全可以使用的一个选择
综合以上四点
我们建议使用redis的内存数据库
来进行这样一个网站的搭建
最后我们考虑一个
相对复杂的业务场景
这是一个抢票服务
功能是在某个时刻
为大量的用户进行抢票服务
要求能够在10秒内
为5000个用户正确地
返回抢票结果
我们来简单分析一下
这样一个业务
首先用户的数据
需要能够进行持久化存储
因此考虑使用mysql与mongo
还要能够支持事务机制
不能让一张票
被两个人同时抢到
这时候应该考虑使用mysql
还要求能够超快速度地响应时间
需要在短时间内返回结果
这是应该考虑内存数据库
那么我们到底应该怎么用呢
事实上
如这样一个复杂的应用场景
我们应该尝试对其进行拆分
也就是能不能数据持续化存储
用mysql
抢票则使用内存数据库
进行响应等
显然这样直接的拆分可不行的
而需要进行业务的拆分
那么具体应该怎么做呢
针对抢票业务
我们来分离一下业务场景
首先可以很明显地分为两个阶段
非抢票阶段
用户只需要进行登录 注册
和一定程度上的查询就可以了
而抢票阶段
用户抢票的时候
首先需要进行身份的验证
然后发出抢票请求
系统来验证是否还有余票
最后系统返回结果
针对以上的场景分析
我们发现
也只有抢票的过程中
对速度有着极大的需求
因此我们希望这个过程
全都在内存中进行
而在非抢票阶段
用户的登录注册
需要进行持续化的存储
我们完全可以使用mysql
以及mongo来进行
在抢票时
我们可以将所有的用户信息
读入到内存数据库之中
来保证访问速度
最后在验证余票的时候
必须有一个事务机制
来保证不会出现一张票
被两个人同时抢到
这一机制
内存数据库是没有办法实现的
然而我们可以通过
我们自己的业务代码
也就是应用层的代码
来实现这样一个事务机制
从而能够保证(2)的任务
全都在内存进行
保证了反馈的速度
最后谢谢大家的观看
-1.1 软件无处不在
--讲课视频
-1.2 软件的本质特性
--讲授视频
-1.3 软件工程的产生与发展
--讲授视频
-1.4 软件工程的基本概念
--讲授视频
-1.5 软件质量实现
--讲授视频
-1.6 业界人士谈软件工程
-测验题--作业
-讨论题
--讨论题
-作业题
--第一张 作业题
-2.1 编程过程与规范
--讲课视频
-2.2 良好的编程实践
--讲课视频
-2.3 Python集成开发环境
--讲课视频
-2.4 代码静态检查
--讲课视频
-2.5 代码性能分析
--讲课视频
-2.6 结对编程实践
--讲课视频
-2.7 刘贺谈软件工程
--讲课视频
--讨论
-测验题--作业
-作业题
--第二章 作业题
-3.1 单元测试概述
--讲课视频
-3.2 黑盒测试方法
--黑盒测试方法
-3.3 白盒测试方法
--基本概念
--代码覆盖标准
--基本路径测试
-3.4 单元测试工具
--单元测试工具
--html
-测验题--作业
-作业题
--第三章 作业题
--作业题附件
-4.1 软件过程
--讲课视频
-4.2 软件过程模型
--讲课视频
-4.3 敏捷开发过程
--讲课视频
-4.4 微软公司开发过程
--邹欣经理自我介绍
--微软开发过程之一
--微软开发过程之二
-测验题--作业
-5.1 团队组织与管理
--讲课视频
-5.2 项目沟通管理
--讲课视频
-5.3 软件项目计划
--讲课视频
-5.4 软件项目估算
--讲课视频
-测验题--作业
-讨论题
--讨论
-6.1 敏捷开发之Scrum
-- 敏捷开发之Scrum
--html
-6.2 用户故事与估算
--讲课视频
-6.3 团队协作工具Tower
-6.4 配置管理
--讲课视频
-6.5 配置管理工具Git
--讲课视频
-测验题--作业
-作业题--作业
-7.1 需求工程师
--讲课视频
-7.2 需求定义
--讲课视频
-7.3 需求的类型
--讲课视频
--讲课视频(2)
-7.4 需求工程过程
--讲课视频
-7.5 需求的主要来源
--讲课视频
-7.6 需求获取技术
--讲课视频
--讲课视频二
--讲课视频三
-7.7 撰写需求文档
--讲课视频
-测验题--作业
-讨论题
--讨论
-8.1 用例建模概念
--讲课视频
-8.2 用例建模过程
--讲课视频
-8.3 用例建模精讲
--讲课视频
-8.4 建模工具介绍
--讲课视频
-8.5 微信抢票应用案例
--讲课视频
-测验题--作业
-讨论题
--讨论
-9.1 面向对象分析
--讲课视频
-9.2 CRC卡片分拣法
--讲课视频-1
--讲课视频-2
-9.3 面向对象设计
--讲课视频-1
--讲课视频-2
-9.4 类图建模
--讲课视频-1
--讲课视频-2
-第9章 面向对象分析与设计--测验题
-讨论题
--讨论
-10.1 顺序图概念
--讲课视频
-10.2 顺序图建模
--讲课视频
-10.3 顺序图风格
--讲义视频
-10.4 状态建模
--讲课视频
-10.5 状态图
--讲课视频
-10.6 状态图精讲
--讲义视频
-测验题--作业
-讨论题
--讨论
-11.1 软件体系结构概念
--讲授视频
-11.2 软件设计原则
--讲授视频
-11.3 软件体系结构风格(一)
--讲授视频
-11.4 软件体系结构风格(二)
--讲授视频
-11.5 软件体系结构风格(三)
--讲授视频
-11.6 软件设计过程
--讲授视频
-11.7 Web系统架构设计
--讲授视频
-11.8 数据库选择策略
--讲授视频
-测验题--作业
-作业题
--html
--html
--html
-作业题--作业
-12.1 交互设计概述
--讲授视频
-12.2 交互设计目标
--讲授视频
-12.3 GUI设计原则
--讲课视频
-12.4 KLM效率模型
--Video
-12.5 Fitts定律
--讲授视频
-12.6 交互设计过程
--讲授视频
-测验题--作业
-13.1 软件测试概念
--讲课视频
-13.2 软件测试类型
--讲课视频
-13.3 软件功能测试
--讲课视频
-13.4 软件性能测试
--讲课视频
-测验题--作业
-14.1 软件部署与交付
--讲课视频
-14.2 软件演化与维护
--讲课视频
-测验题--作业
-第一部分:基础知识
-第二部分:编程与测试(选做)