1.10 数据库概述
数据库是“按照数据结构来组织、存储和管理数据的仓库”,是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。
数据库中的数据以一定格式存储在一起,并且能与多个用户共享,数据之间有尽可能小的冗余度。数据库可被视为电子化的文件柜——存储电子文件的场所,用户可以对文件中的数据进行新增、查询、更新、删除等操作。
数据库与应用程序彼此独立,在制作应用程序时,数据库的性能上限在某种程度上代表了应用程序的性能上限,因此对于数据库来说,基准测试、SQL与索引的优化、主从复制,以及分表等工作都是重中之重。
• 基准测试可以测试出MySQL服务器的指标极限,在应用程序制作完成之后,越接近基准测试,说明程序在代码上的可优化空间越少。
• SQL与索引的优化将大幅地提高MySQL的查询速度。
• 主从复制主要用来解决MySQL的单台性能瓶颈问题,通过多台服务器可以平摊写入或读取的压力,让MySQL服务器的整体服务性能提升数倍。
• 分表既可以解决MySQL大表查询速度过慢的问题(单靠索引无法解决),也可以单独存储历史性数据和冗余性数据,不会因历史性、冗余性的数据影响查询速度。
1.10.1 数据库分类
数据库主要分为关系数据库和非关系数据库两种。关系数据库指采用了关系模型来组织数据的数据库,其以行和列的形式存储数据,以便于用户理解。关系数据库中的行和列被称为表,一组表组成了数据库。用户通过查询来检索数据库中的数据。关系模型可以简单理解为二维表格模型,一个关系数据库就是由二维表格及其之间的关系组成的一个数据组织。目前,最常用的关系数据库有Oracle、MySQL、DB2和SQL Server。
最早的Oracle版本是1979年夏季发布的。最流行的Oracle版本为Oracle 11g,是2007年11月发布的。
SQL Server最初由Microsoft、Sybase和Ashton-Tate三家公司共同开发,于1988年推出第一个OS/2版本。
MySQL是1996年发布的,开始只面向一小拨人,相当于内部发布。1996年10月,MySQL 3.11.1发布(MySQL没有2.x版本),最开始只提供Solaris下的二进制版本。一个月后,Linux版本出现了。在接下来的两年里,MySQL被依次移植到各个平台。由于MySQL是免费的,并且可以在Linux系统上运行,所以热度逐渐超过了Oracle和SQL Server。
非关系数据库又称为NoSQL数据库,随着互联网Web 2.0网站的兴起,传统的关系数据库在处理Web 2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站时已经显得力不从心,出现了很多难以克服的问题,而非关系的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合和多重数据种类带来的挑战,尤其是大数据应用难题。因为非关系数据库的性能远高于关系数据库,所以通常将非关系数据库作为目前应用程序的缓存,让系统的响应速度更快一些,目前非关系数据库最常用的分别是Redis和MongoDB。
• Redis是2009年正式发布的,主要以键值对作为存储结构对数据进行存储。
• MongoDB最初于2007年开发,主要以JSON作为存储结构对数据进行存储。
由于Redis更新换代较为迅速,集群版更加稳定,不仅免费,而且有使用简单、并发可观等优点,所以一直占据着NoSQL数据库的市场。
在应用程序规模不断扩大的今天,网络应用程序、接口、性能指标、试用场景等日新月异,过去的数据库已无法满足大数据、人工智能等方面的需要,因此NoSQL衍生出了四种新类型,如表1-2所示。
表1-2
值得注意的是,虽然在项目中经常使用部分NoSQL数据库作为缓存,但是NoSQL数据库并不代表缓存,所以不要混淆NoSQL数据库和缓存的概念,后续章节会详细介绍缓存。除上述市场上常见的数据库及其存储方式外,其他特殊的存储方式如表1-3所示。
表1-3
除Hadoop生态圈、Spark生态圈、数据挖掘系列、数据仓储系列、大规模并行数据库系列、数据集成系列等所涉及的存储外,大部分应用程序使用的数据库和存储方式都介绍到了。用表1-1与表1-2的存储方式可以满足绝大部分新闻网站、官网、游戏、电商、社交、数据平台(HTTP API)、医疗管理系统(HIS)、股票分析系统、理财系统、财务系统、管理系统等应用场景的需要。
时序性数据库是一种较为特殊的数据库,它使用了类SQL语句。例如,InfluxDB中使用的InfluxSQL与SQL语句几乎没有差别,其存储格式仍为二维表、非文档结构或键值对结构,所以并没有把InfluxDB放到表1-2中。但是几乎不可能对InfluxDB数据库做多表联查、一对一、一对多等相关查询操作,因为时序性数据库的并发极大,实时响应速度极快,该数据库把一切性能都放在了新增、查询、实时响应等场景上。当数据出现错误时,应尽可能按照Time时间段删除数据。
另外,SQLite虽然同样作为新关系数据库存在,但是过于微型,还原、备份等能力远不如MySQL、Oracle等常规关系数据库,所以通常不作为关系数据库使用。由于SQLite存储空间与本身体积都较小,所以SQLite活跃在移动端,通常作为移动端的缓存而存在,有时也会作为应用程序的缓存而存在。
Elasticsearch在官方文档中属于分布式RESTful响应的搜索引擎(Distributed RESTful Search Engine),但Elasticsearch的存储格式又是文档式的,所以Elasticsearch既可归属于文档数据库,又可归属于搜索引擎。
上述内容属于概念类知识,在学习过程中不要过多纠结归属类型,只要擅长在不同场景的架构中使用不同的存储方式达到理想的业务与性能目标即可。目前市场上最常用的仍然是MySQL、Oracle、Redis、MongoDB、Elasticsearch和FastDFS等一系列“老功臣”。
1. 关系数据库与非关系数据库的区别
关系数据库与非关系数据库的区别如下:
数据存储的方式不同
关系数据天然就是二维表,因此适合存储在数据表的行和列中。数据表不仅可以彼此关联协作存储,也很容易提取数据。与其相反,非关系数据是大块组合在一起的,因而不适合存储在数据表的行和列中。
数据存储的地址不同
关系数据库通常直接存储进二进制文件中。非关系数据库根据自身配置不同,有的只存储在内存中,有的暂存在缓存中。当非关系数据库存储在内存中时,可以达到响应速度更快的目的,但是也更容易丢失数据,一旦重启非关系数据库,则相当于丢失了所有内容。当非关系数据库暂存在缓存中时,它会定期把数据存储到二进制文件中,即便重启非关系数据库,也可保证部分数据不会丢失。
对事务性的支持不同
如果数据操作需要高事务性,那么关系数据库(SQL数据库)是最佳选择。SQL数据库支持对事务原子性细粒度的控制,并且易于回滚事务。虽然非关系数据库也可以使用事务操作,但在稳定性方面无法和关系数据库相比。非关系数据库真正的价值是在操作的扩展性和大数据处理方面。
总而言之,在计算机性能选择上,有得必有失,在增加了响应速度和并发的情况下,非关系数据库和搜索引擎通常牺牲了一部分的数据安全性。
许多高级的Oracle DBA开玩笑称Oracle为“只要磁盘没有物理损坏,任何Oracle存储的数据都可以从磁盘中重新拿回来,甚至有些轻微的物理损坏仍然可以拿到其中一部分数据。”虽然只是一句玩笑话,但这确实是Oracle在一次次互联网浪潮的冲击之下仍然屹立不倒的原因之一,而这也恰恰是大部分非关系数据库无法与之相比的地方之一。
2. 关系数据库等级
大部分在校学生和工作2~3年的程序员经常会提出这样一个问题,即“在工作中对关系数据库需要掌握到什么程度?”
这是一个比较常见的问题,但是因为岗位不同,使用的关系数据库不同,所以对关系数据库需要掌握的程度也不同。笔者按照“游戏等级”的方式,以MySQL为例,划分了不同等级下对MySQL掌握的熟练度,如表1-4所示。
表1-4
续表
3. 常用的MySQL工具
(1)常用的性能基准测试工具有sysbench和mysqlslap。
(2)对应用程序进行性能测试的常用工具是JMeter。
(3)对MySQL和服务器CPU等信息进行性能监控架构可选择Grafana + InfluxDB +Telegraf架构或Prometheus + Grafana架构。
(4)集群可选择MyCAT。
(5)相关统计可选择percona-toolkit。
(6)慢SQL查询可选择mysqldumpslow。
(7)分布式事务可选择Fescar(Seata)。
(8)事务处理测试可选择HammerDB。
(9)快速备份与恢复可选择mysqlhotcopy。
(10)常规备份与恢复可选择mysqldump。
(11)二进制日志(binlog)解析工具可选择Maxwell。
1.10.2 数据库测试的具体内容
(1)初始程序架构时,在设计数据结构与表结构之后,应对设计的表结构与数据结构进行基准性能测试,得到该套结构的基准信息。
(2)在对数据库进行主从复制、MyCAT集群等优化之后,需要进行适当压力的性能测试,以保证集群化后,MySQL单节点性能没有被降低过多。
(3)在编码结束之后应对每条可能执行的SQL语句执行计划解读,确保执行语句中不存在全表索引之类的操作。如果包含全表索引,则需增加索引或优化SQL语句。
(4)应当对数据库做业务存储量测试,即测试当存储的数据量不同时,应用程序的返回时间为多少。此测试通常以应用程序作为入口。
(5)需要对数据库做疲劳测试,在应用程序运行过程中,是否因运行时间过长而出现数据库内存泄漏的情况。
(6)应当对数据库做灾备测试,即当主从复制或相关集群架构部署结束时,需测试断网、断电情况下是否会进行正常的灾备处理与响应服务。
(7)应当对数据库做安全测试,即账号、密码、权限、防火墙、弱密码、脱敏等相关内容是否设计得体,除防止别有用心的人渗透外,是否可以防止当前用户误操作导致数据丢失等情况。