作者:yandeng,腾讯 PCG 应用开发工程师 1.数据库基础1.1 MySQL 架构和其它数据库相比,MySQL 有点与众不同,它的架构可以在多种不同场景中应用并发挥良好作用。主要体现在存储引擎的架构上,插件式的存储引擎架构将查询处理和其它的系统任务以及数据的存储提取相分离。这种架构可以根据业务的需求和实际需要选择合适的存储引擎,各层介绍: 1.1.1 连接层最上层是一些客户端和连接服务,包含本地 sock 通信和大多数基于客户端/服务端工具实现的类似于 tcp/ip 的通信。主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程池的概念,为通过认证安全接入的客户端提供线程。同样在该层上可以实现基于 SSL 的安全链接。服务器也会为安全接入的每个客户端验证它所具有的操作权限。 1.1.2 服务层1.1.3 引擎层存储引擎层,存储引擎真正的负责了 MySQL 中数据的存储和提取,服务器通过 API 与存储引擎进行通信。不同的存储引擎具有的功能不同,这样我们可以根据自己的实际需要进行选取。 1.1.4 存储层数据存储层,主要是将数据存储在运行于裸设备的文件系统之上,并完成与存储引擎的交互。 1.2 数据引擎不同的存储引擎都有各自的特点,以适应不同的需求,如表所示。为了做出选择,首先要考虑每一个存储引擎提供了哪些不同的功能。 1.2.1 MyISAM使用这个存储引擎,每个 MyISAM 在磁盘上存储成三个文件。
1.2.2 InnoDBInnoDB 是默认的数据库存储引擎,他的主要特点有:
1.2.3 Memory将数据存在内存,为了提高数据的访问速度,每一个表实际上和一个磁盘文件关联。文件是 frm。
1.3 表与字段设计1.3.1 数据库基本设计规范
1.3.2 数据库字段设计规范
1.3.3 索引设计规范
1.3.4 数据库 SQL 开发规范
1.4 范式与反范式1.4.1 第一范式该范式是为了排除 重复组 的出现,因此要求数据库的每个列的值域都由原子值组成;每个字段的值都只能是单一值。1971 年埃德加·科德提出了第一范式。即表中所有字段都是不可再分的。解决方案:想要消除重复组的话,只要把每笔记录都转化为单一记录即可。 1.4.2 第二范式表中必须存在业务主键,并且非主键依赖于全部业务主键。解决方案:拆分将依赖的字段单独成表。 1.4.3 第三范式表中的非主键列之间不能相互依赖,将不与 PK 形成依赖关系的字段直接提出单独成表即可。 1.5 sql 索引
1.6 join 连表1.6.1 JOIN 按照功能大致分为如下三类:
1.6.2 join 的原理MySQL 使用了嵌套循环(Nested-Loop Join)的实现方式。Nested-Loop Join 需要区分驱动表和被驱动表,先访问驱动表,筛选出结果集,然后将这个结果集作为循环的基础,访问被驱动表过滤出需要的数据。Nested-Loop Join 分下面几种类型:
相关图片来源于网络
这个 buffer 被称为 join buffer,顾名思义,就是用来缓存 join 需要的字段。MySQL 默认 buffer 大小 256K,如果有 n 个 join 操作,会生成 n-1 个 join buffer。 1.6.3 join 的优化
![]()
2.数据进阶2.1 sql 执行过程![]() 如上图所示,当向 MySQL 发送一个请求的时候,MySQL 到底做了什么:
MySQL 的查询优化器使用很多策略来生成一个最优的执行计划。优化策略可以简单的分为两种:
使用 show status like 'Last_query_cost’ 可以查询上次执行的语句的成本,单位为数据页。 ![]() ![]() 2.2 sql 查询计划使用 explain 进行执行计划分析: ![]() ![]() ![]() 2.3 sql 索引优化遵循索引原则适合大部分的常规数据库查询场景,但不是所有的索引都能符合预期,从索引原理本身来分析对索引的创建会更有帮助。
2.3.1 前缀索引当要索引的列字符很多时 索引则会很大且变慢( 可以只索引列开始的部分字符串 节约索引空间 从而提高索引效率 ) 例如:一个数据表的 x_name 值都是类似 23213223.434323.4543.4543.34324 这种值,如果以整个字段值做索引,会使索引文件过大,但是如果设置前 7 位来做索引则不会出现重复索引值的情况了。 ![]() 查询效率会大大提升: ![]() 2.3.2 联合索引顺序
使用选择基数更高(不重复的数据)的字段作为最左索引: ![]() 2.3.3 联合索引左前缀匹配![]()
2.4 慢查询分析2.4.1 先对 sql 语句进行 explain,查看语句存在的问题2.4.2 使用 show profile 查看执行耗时,分析具体耗时原因show profile 的使用指引: ![]() 2.5 改表与 sql 日志2.5.1 改表改表会直接触发表锁,改表过程非常耗时,对于大表修改,无论是字段类型调整还是字段增删,都需要谨慎操作,防止业务表操作被阻塞,大表修改往往有以下几种方式。
常用方法: ![]() 2.5.2 sql 日志![]() ![]() 2.6 分库与分表2.6.1 数据库瓶颈不管是 IO 瓶颈,还是 CPU 瓶颈,最终都会导致数据库的活跃连接数增加,进而逼近甚至达到数据库可承载活跃连接数的阈值。在业务 Service 来看就是,可用数据库连接少甚至无连接可用。接下来就可以想象了吧(并发量、吞吐量、崩溃)。
第二种:网络 IO 瓶颈,请求的数据太多,网络带宽不够 -> 分库。
第二种:单表数据量太大,查询时扫描的行太多,SQL 效率低,CPU 率先出现瓶颈 -> 水平分表。 2.6.2 分库分表
概念:以字段为依据,按照一定策略(hash、range 等),将一个库中的数据拆分到多个库中。结果:每个库的结构都一样;每个库的数据都不一样,没有交集;所有库的并集是全量数据;场景:系统绝对并发量上来了,分表难以根本上解决问题,并且还没有明显的业务归属来垂直分库。分析:库多了,io 和 cpu 的压力自然可以成倍缓解。
概念:以字段为依据,按照一定策略(hash、range 等),将一个表中的数据拆分到多个表中。结果:每个表的结构都一样;每个表的数据都不一样,没有交集;所有表的并集是全量数据。 场景:系统绝对并发量并没有上来,只是单表的数据量太多,影响了 SQL 效率,加重了 CPU 负担,以至于成为瓶颈。 分析:表的数据量少了,单次 SQL 执行效率高,自然减轻了 CPU 的负担。
概念:以表为依据,按照业务归属不同,将不同的表拆分到不同的库中。 结果:每个库的结构都不一样;每个库的数据也不一样,没有交集;所有库的并集是全量数据。 场景:系统绝对并发量上来了,并且可以抽象出单独的业务模块。 分析:到这一步,基本上就可以服务化了。例如,随着业务的发展一些公用的配置表、字典表等越来越多,这时可以将这些表拆到单独的库中,甚至可以服务化。再有,随着业务的发展孵化出了一套业务模式,这时可以将相关的表拆到单独的库中,甚至可以服务化。
概念:以字段为依据,按照字段的活跃性,将表中字段拆到不同的表(主表和扩展表)中。 结果:每个表的结构都不一样;每个表的数据也不一样,一般来说,每个表的字段至少有一列交集,一般是主键,用于关联数据;所有表的并集是全量数据。 2.6.3 分库分表工具目前市面上的分库分表中间件相对较多,其中基于代理方式的有 MySQL Proxy 和 Amoeba, 基于 Hibernate 框架的是 Hibernate Shards,基于 jdbc 的有当当 sharding-jdbc, 基于 mybatis 的类似 maven 插件式的有蘑菇街的蘑菇街 TSharding, 通过重写 spring 的 ibatis template 类的 Cobar Client。 还有一些大公司的开源产品: ![]() 3.分布式数据库3.1 什么是分布式数据库分布式系统数据库系统原理(第三版)中的描述:“我们把分布式数据库定义为一群分布在计算机网络上、逻辑上相互关联的数据库。分布式数据库管理系统(分布式 DBMS)则是支持管理分布式数据库的软件系统,它使得分布对于用户变得透明。有时,分布式数据库系统(Distributed Database System,DDBS)用于表示分布式数据库和分布式 DBMS 这两者。 在以上表述中,“一群分布在网络上、逻辑上相互关联”是其要义。在物理上一群逻辑上相互关联的数据库可以分布式在一个或多个物理节点上。当然,主要还是应用在多个物理节点。这一方面是 X86 服务器性价比的提升有关,另一方面是因为互联网的发展带来了高并发和海量数据处理的需求,原来的单物理服务器节点不足以满足这个需求。 3.2 分布式数据库的理论基础1. CAP 理论首先,分布式数据库的技术理论是基于单节点关系数据库的基本特性的继承,主要涉及事务的 ACID 特性、事务日志的容灾恢复性、数据冗余的高可用性几个要点。 其次,分布式数据的设计要遵循 CAP 定理,即:一个分布式系统不可能同时满足 一致性( Consistency ) 、可用性 ( Availability ) 、分区容 忍 性 ( Partition tolerance ) 这三个基本需求,最 多只能同时满足其中的两项, 分区容错性 是不能放弃的,因此架构师通常是在可用性和一致性之间权衡。这里的权衡不是简单的完全抛弃,而是考虑业务情况作出的牺牲,或者用互联网的一个术语“降级”来描述。 CAP 三个特性描述如下 :一致性:确保分布式群集中的每个节点都返回相同的 、 最近 更新的数据 。一致性是指每个客户端具有相同的数据视图。有多种类型的一致性模型 , CAP 中的一致性是指线性化或顺序一致性,是强一致性。 可用性:每个非失败节点在合理的时间内返回所有读取和写入请求的响应。为了可用,网络分区两侧的每个节点必须能够在合理的时间内做出响应。 分区容忍性:尽管存在网络分区,系统仍可继续运行并 保证 一致性。网络分区已成事实。保证分区容忍度的分布式系统可以在分区修复后从分区进行适当的恢复。 2. BASE 理论 基于 CAP 定理的权衡,演进出了 BASE 理论 ,BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent(最终一致性)三个短语的缩写。BASE 理论的核心思想是:即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。 BA:Basically Available 基本可用,分布式系统在出现故障的时候,允许损失部分可用性,即保证核心可用;S:Soft state 软状态,允许系统存在中间状态,而该中间状态不会影响系统整体可用性;E:Consistency 最终一致性,系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。 BASE 理论本质上是对 CAP 理论的延伸,是对 CAP 中 AP 方案的一个补充。 3.3 分布式数据库的架构演变
|
|
来自: 520jefferson > 《sql》