7

数据库(Database):按照数据结构来组织、存储和管理数据的仓库 。

简单理解就是一个存储数据的仓库,为了方便数据的存储和管理,它能将数据按照特定的规律存储在磁盘上。并且,通过数据库管理系统,我们可以有效地组织和管理存储在数据库中的数据。

我们来设计一个简单的数据库—— LintCode,用来存放我们 LintcCode 的相关信息。

在 LintCode 数据库中,有两张表——课程表 courses和教师表 teacher

courses 表中存放着课程的信息 ,包括:课程名称 name 、学生总数 student_count、开课时间 created_at 以及讲师 ID teacher_id

teachers 表中存放着教师的信息,包括:讲师姓名 name 、讲师邮箱 email 、讲师年龄 age 以及讲师国籍 country

这时一个简单的数据库已经搭建好了:

定义一个数据库连接类 python 编写一个数据库_数据

下面我们对上述两个表格进行一些简单的介绍,方便大家对后续课程的理解:

数据库:数据库是一些关联表的集合。LintCode 就是我们用来存放课程表 courses 和教师表 teachers 的数据库。
数据表:数据表是数据的矩阵。课程表 courses 和 教师表 teachers 就是数据表,看起来像一个简单的 Excel 表格。
: 一列(数据元素)包含了相同类型的数据。例如教师表 teachers 中的姓名 name 就是一个列,这一列中的教师姓名都是用字符方式存储。
: 一行数据(可以元组,或记录)是一组相关的数据。例如教师表 teachers 每一行都对应一位教师信息

接下来,我们可以通过SQL语句实现一些基础的增删查改功能,这也是建立一个数据库系统的基础:

一、数据以文本形式保存
将所要保存的数据,写入文本文件。这个文本文件就是你的数据库。

为了方便读取,数据必须分成记录,每一条记录的长度规定为等长。

实际应用中,数据库往往采用B树(B-tree)格式储存数据。

二、什么是B树?

要理解B树,必须从二叉查找树(Binary search tree)讲起。

定义一个数据库连接类 python 编写一个数据库_数据库_02

二叉查找树是一种查找效率非常高的数据结构,它有三个特点。

(1)每个节点最多只有两个子树。

(2)左子树都为小于父节点的值,右子树都为大于父节点的值。

(3)在n个节点中找到目标值,一般只需要log(n)次比较。

二叉查找树的结构不适合数据库,因为它的查找效率与层数相关。越处在下层的数据,就需要越多次比较。极端情况下,n个数据需要n次比较才能找到目标值。对于数据库来说,每进入一层,就要从硬盘读取一次数据,这非常致命,因为硬盘的读取时间远远大于数据处理时间,数据库读取硬盘的次数越少越好。

B树是对二叉查找树的改进。它的设计思想是,将相关数据尽量集中在一起,以便一次读取多个数据,减少硬盘操作次数。

定义一个数据库连接类 python 编写一个数据库_数据结构_03

B树的特点也有三个。

(1)一个节点可以容纳多个值。比如上图中,最多的一个节点容纳了4个值。

(2)除非数据已经填满,否则不会增加新的层。也就是说,B树追求”层”越少越好。

(3)子节点中的值,与父节点中的值,有严格的大小对应关系。一般来说,如果父节点有a个值,那么就有a+1个子节点。比如上图中,父节点有两个值(7和16),就对应三个子节点,第一个子节点都是小于7的值,最后一个子节点都是大于16的值,中间的子节点就是7和16之间的值。

这种数据结构,非常有利于减少读取硬盘的次数。假定一个节点可以容纳100个值,那么3层的B树可以容纳100万个数据,如果换成二叉查找树,则需要20层!假定操作系统一次读取一个节点,并且根节点保留在内存中,那么B树在100万个数据中查找目标值,只需要读取两次硬盘。

三、索引
数据库以B树格式储存,只解决了按照”主键”查找数据的问题。如果想查找其他字段,就需要建立索引(index)。

所谓索引,就是以某个字段为关键字的B树文件。假定有一张”雇员表”,包含了员工号(主键)和姓名两个字段。可以对姓名建立索引文件,该文件以B树格式对姓名进行储存,每个姓名后面是其在数据库中的位置(即第几条记录)。查找姓名的时候,先从索引中找到对应第几条记录,然后再从表格中读取。

这种索引查找方法,叫做“索引顺序存取方法”(Indexed Sequential Access Method),缩写为ISAM。它已经有多种实现(比如C-ISAM库和D-ISAM库),只要使用这些代码库,就能自己写一个最简单的数据库。

四、高级功能
部署了最基本的数据存取(包括索引)以后,还可以实现一些高级功能。

(1)SQL语言是数据库通用操作语言,所以需要一个SQL解析器,将SQL命令解析为对应的ISAM操作。

(2)**数据库连接(join)**是指数据库的两张表通过”外键”,建立连接关系。你需要对这种操作进行优化。

(3)**数据库事务(transaction)**是指批量进行一系列数据库操作,只要有一步不成功,整个操作都不成功。所以需要有一个”操作日志”,以便失败时对操作进行回滚。

(4)备份机制:保存数据库的副本。

(5)远程操作:使得用户可以在不同的机器上,通过TCP/IP协议操作数据库。

关于更多的系统架构,就需要更高层级的视野来实现,这里推荐《系统架构设计》这门课,老师把16大系统设计知识点讲得非常细致,戳这里可以免费试听

具体说一下要实现一个简单的系统(不一定局限于数据库),应该以怎样的思路去构建:

第一步, 确定该系统需要设计哪些功能,设计得多牛

• 需要设计哪些功能(也可以自己想)

把所有的功能一一的罗列出来,进行分类,并把核心的功能优先实现

• 需要承受多大的访问量?

第二步,将大系统拆分为小服务

  1. Replay 重放需求: 重新过一遍每个需求,为每个需求添加一个服务
  2. Merge 归并需求: 归并相同的服务

定义一个数据库连接类 python 编写一个数据库_数据库_04

第三步,确定数据如何存储和访问

1.对每个 Service 选择合适的存储结构

2.细化数据表单

3.画图展示数据存储和读取的流程