【软件架构设计(40)】数据库规范化与性能优化

文章目录

一、数据库规范化理论

1、规范化范式

规范化是通过逐步消除数据依赖中的不合适部分,使关系模式达到不同范式级别,以解决数据冗余、插入异常、删除异常等问题,让数据库结构更合理、数据更具一致性。

2、范式级别提升的负面影响

范式级别提升虽然能解决数据冗余和异常问题,但也会带来设计复杂度增加、查询性能下降等负面影响。

在设计与维护层面,高范式对设计专业性和维护成本提出更高要求

  1. 从低范式向高范式转换时,需对关系模式进行细致拆分,比如从1NF升级到BCNF,要反复分析并消除复杂数据依赖,这依赖设计者深厚的专业知识与丰富经验,否则易出现判断失误;
  2. 而拆分后的多表结构,会使表间关联大幅增加,后续维护表结构、约束及关联关系时,仅修改一个业务字段就可能涉及多个表的调整,既提升了工作量,也提高了出错风险。

查询环节的复杂度与性能问题同样突出

  1. SQL复杂度高:高范式下数据分散在多个表中,执行查询时需频繁进行多表连接操作,例如获取一条完整业务数据可能要关联3-4个拆分后的表,这不仅增加了查询语句编写的难度,对开发人员的SQL能力要求更高;
  2. 数据量存在大量扫描和匹配操作:在数据量较大的场景中,多表连接需要大量扫描与匹配操作,会显著增加系统I/O与计算消耗,导致查询响应时间变长,难以满足实时性要求高的业务需求。

数据完整性保障的难度也随之加大

  1. 数据分散,事务管理复杂:数据分散存储使得多表更新的事务管理更复杂,比如一次业务操作需同时更新3个表的数据,若事务控制不当,极易出现部分操作成功、部分失败的情况,直接破坏数据一致性;
  2. 外键约束多,易出错:表拆分带来外键约束数量的增多,维护这些外键关系的正确性与一致性变得更困难,一旦外键设置或更新出现疏漏,就可能引发数据引用错误,造成数据不一致问题。

二、反规范化技术

1、反规范化概念

反规范化是对规范化后的数据库结构进行调整,适当增加数据冗余,以提高某些查询操作的性能,它是规范化的逆过程,但不是简单恢复到原始非规范状态。

规范化通过逐步消除数据依赖中的不合适部分,使关系模式达到不同范式级别(如1NF、2NF、3NF、BCNF等),以解决数据冗余、插入异常、删除异常等问题,让数据库结构更合理、数据更具一致性。一般是将大的关系模式拆分成多个小的关系模式。

2、反规范化技术手段

反规范化通过主动引入适度冗余或调整表结构,平衡数据库查询性能与维护成本,常见策略主要包括增加冗余列、重新组表与分割表,每种方式均需在性能提升与管理复杂度间权衡。

增加冗余列是最直接的反规范化手段,具体可分为派生性冗余列与关联冗余列两类。

  1. 派生性冗余列:例如在包含"单价"和"数量"的表中新增"总价"列(总价=单价×数量),查询时无需重复执行乘法运算,能直接提升效率,但需在"单价"或"数量"更新时同步修改"总价",否则会破坏数据一致性;
  2. 关联冗余列:比如在"订单表"中,除"学号"外额外增加"姓名"列(原本存储于"学生表"),可避免订单查询时的表连接操作,但同样需保证"姓名"在两表中同步更新,防止出现数据不一致。

重新组表与分割表则通过调整表的聚合程度优化性能。

  1. 重新组表:是将规范化拆分后的多个小表合并为单一表,例如把"用户基本信息表""用户联系方式表"合并为"完整用户表",减少多表查询时的连接操作,尤其适合高频获取完整用户信息的场景,但合并后会导致数据冗余增加,且插入、删除时需操作更多字段,提升了操作复杂度;
  2. 分割表 :则针对大表进行拆分,
    • 水平分割按行划分数据(如用户表按地区拆分为"长沙用户表""上海用户表"),
    • 垂直分割按列划分(如将"商品表"的常用字段"名称""价格"与不常用字段"生产细节""售后说明"分开存储),两种方式均能减少单次查询扫描的数据量,加快查询速度,但也增加了数据管理难度,例如水平分割后需判断数据归属表,垂直分割后需处理跨表关联查询。

3、反规范化优缺点分析

反规范化在提升查询性能的同时,也会带来数据冗余、维护复杂度增加等问题,需要权衡利弊。

反规范化优点

  1. 连接操作少,检索快、统计快 :反规范化通过增加冗余列等手段,减少了表之间的连接操作。

    在数据库查询中,表连接操作通常较为耗时,减少连接意味着能更快地获取数据,提高检索和统计的速度。

  2. 需要查的表减少,检索容易:将原本分散在多个表中的数据整合到较少的表中,降低了查询时涉及的表数量,使检索过程更简单直接。用户或应用程序无需在多个表之间进行复杂的关联操作,提高了数据检索的便捷性。

反规范化缺点及解决方案

  1. 数据冗余,需要更大存储空间:反规范化通过增加冗余列等方式提高查询性能,必然导致数据重复存储,占用更多存储空间。

  2. 插入、更新、删除操作开销更大 :由于存在数据冗余,当进行插入、更新、删除操作时,需要维护多个冗余数据位置的一致性

  3. 数据不一致,可能产生添加、修改、删除异常 :冗余数据在更新过程中,若不同位置的数据更新不同步,就会导致数据不一致。
    可采用触发器数据同步,即通过定义触发器,在数据发生变化时自动执行相关操作,确保冗余数据同步更新;也可利用应用程序数据同步,在应用程序代码中编写逻辑,控制数据更新,保证数据一致性。

  4. 更新和插入代码更难写:反规范化后数据结构更复杂,存在冗余数据和表间关系变化,编写更新和插入代码时,需要考虑更多因素,如维护冗余数据一致性等,增加了代码编写难度。

三、数据库索引

1、索引基础概念

数据库索引是数据库管理系统(DBMS)为加速查询操作,在表中创建的数据结构,类似书籍目录,能让数据库快速定位数据位置,无需逐行扫描全表 。它是对数据库表中一列或多列的值进行排序的结构,以特定算法优化,包含索引列的值(键值)和指向实际数据记录的指针

工作原理

  1. B树 :一种多叉平衡查找树,节点中存储索引 和指向子节点的指针。查找数据时,从根节点开始,根据索引值与节点中值的比较,决定向下搜索的分支,直到找到目标值或确定其不存在。

  2. B+树 :也是多路平衡查找树,内部节点存索引值 用于引导查找,叶子节点存实际数据记录指针 ,且叶子节点构成有序链表。查找时先在树结构中定位,再到叶子节点获取数据指针。范围查询时,利用叶子节点有序性可快速遍历。

2、索引类型

索引按不同维度可分为多种类型,每种类型适用于不同的应用场景。

按列数分类

索引类型 定义 适用场景 特点
单列索引 基于表中单个字段创建的索引 经常依单一字段查询的场景 如按"姓名"列查询
多列索引(联合索引) 基于多个字段创建的索引 常需多个字段组合查询的情况 列顺序重要,遵循最左前缀原则

按约束分类

索引类型 定义 用途 特点
唯一索引 保证索引列值唯一的索引 用于主键和唯一约束字段 确保数据唯一性
主键索引 特殊的唯一索引 表中主键列自动创建 值必须唯一,一个表只能有一个

其他类型

索引类型 定义 特点 适用场景
聚簇索引 表中行物理顺序与键值逻辑顺序相同的索引 一个表通常只有一个 查询多行效率高
非聚簇索引 行物理顺序与键值逻辑顺序不同的索引 叶级节点不包含数据页,只含索引行 单行检索快
全文索引 用于文本数据搜索的索引 对文本中单词创建清单辅助检索 文本内容搜索

3、索引优缺点

索引在提升查询效率的同时,也会占用存储空间并影响数据维护效率。

优点类型 具体表现 效果说明 适用场景
提升查询效率 极大加快数据检索速度 尤其大数据量时效果显著 频繁查询操作
保证数据唯一性 确保列值唯一 如唯一索引、主键索引 数据完整性要求高的场景
加速表连接 在实现数据参考完整性方面有意义 提高多表关联查询性能 复杂查询和报表生成
优化分组排序 减少分组和排序时间 提高聚合操作效率 统计分析、数据汇总
缺点类型 具体表现 影响说明 注意事项
占用空间 创建索引需占物理空间 数据量越大占用越多 需要额外的存储成本
降低维护效率 数据增删改时,索引需动态维护 影响操作速度 频繁修改数据的表需谨慎使用

4、索引适用场景与创建原则

合理创建索引需要根据查询模式、数据特征和性能需求进行综合考虑。

1. 适合建索引 :经常搜索的列、主键列、外键(经常用于连接)、需范围搜索的列、需排序的列、where子句中常出现的列。
2. 不适合建索引数据量少的表、数据重复且分布均匀的列、定义为text、image和bit数据类型的列、修改性能远大于检索性能的情况。

四、数据库分区、分表、分库

1、数据库分区

将数据库中的大表按一定规则(如按时间、按范围、按列表等)划分成多个较小的分区,逻辑上是一个表,但物理上存储在不同位置。比如将用户表按时间分区,把一年的数据按月份划分成12个分区。

优点类型 具体表现 效果说明 应用示例
提升查询性能 查询时可快速定位到相关分区,减少扫描数据量 避免全表扫描,提高查询效率 查询某月份用户数据,只需访问对应月份分区,无需扫描全表
便于管理维护 可单独对分区进行备份、恢复、优化等操作 提高运维效率,降低维护成本 可仅备份近期活跃数据所在分区,提高备份效率
数据归档方便 可按规则将历史数据转移到低速存储设备 降低存储成本,优化资源利用 将冷数据迁移到成本更低的存储介质
缺点类型 具体表现 影响说明 注意事项
增加管理复杂度 需合理规划分区策略,管理多个分区 提高系统设计和运维难度 需要专业的分区设计和管理经验
跨分区查询复杂 涉及多个分区的查询,需额外处理分区间数据整合 增加查询复杂度,可能影响性能 需要优化跨分区查询策略

2、数据库分表

把一个大表的数据按一定规则(如按业务逻辑、按数据特征)拆分到多个结构相同的小表中。例如将用户表按国内、国外用户拆分成国内用户表和国外用户表。

优点类型 具体表现 效果说明 应用场景
减小单表数据量 降低单个表的数据规模 提高查询、插入、更新等操作效率 大数据量表的性能优化
优化性能 针对不同小表可定制索引等优化策略 满足特定业务需求,提升针对性性能 不同业务模块的个性化优化
缺点类型 具体表现 影响说明 注意事项
数据关联性管理复杂 原表数据拆分后,涉及多表关联查询时逻辑更复杂 增加查询复杂度,可能影响性能 需要重新设计查询逻辑
维护成本增加 需维护多个表的结构、索引等,数据同步等操作难度增大 提高系统维护难度和成本 需要专业的数据库管理技能

3、数据库分库

将一个数据库中的数据拆分到多个不同的数据库中,每个数据库可部署在不同服务器上。比如将电商系统数据库拆分为用户库、商品库、订单库等。

优点类型 具体说明
负载均衡 分散数据库负载,不同数据库可处理不同业务请求,提升整体系统性能
高可用性 一个数据库出现故障,不影响其他数据库正常运行,提高系统容错能力
便于扩展 可根据业务需求单独扩展某个数据库服务器资源
缺点类型 具体说明
跨库事务处理复杂 涉及多个数据库的事务操作,保证数据一致性难度大
管理成本高 需管理多个数据库实例,包括备份、监控、维护等工作

4、分区和分表对比

分区和分表都是数据分散存储的技术,但在逻辑结构和实现方式上存在差异。

共性解读

  • 都针对数据表:分区和分表操作的对象都是数据库中的数据表。无论是将大表进行分区处理,还是拆分成多个小表,都是围绕数据表展开,目的是优化数据表相关操作和存储。
  • 都使用了分布式存储:二者都采用分布式存储思想,把数据分散存储。分区是将表数据分散到不同分区存储,分表是把数据分散到多个表存储,避免数据集中存储带来的性能瓶颈。
  • 都提升了查询效率:通过减少单次查询需扫描的数据量来提升效率。分区可快速定位到相关分区查询;分表减小单表规模,查询时扫描数据量少,从而加快查询速度。
  • 都降低了数据库的频繁I/O压力值:数据分散存储后,I/O操作也分散。分区使不同分区的I/O操作相对独立,减少单个存储区域的I/O负载;分表将数据分散到多个表,降低单个表的I/O压力,避免因频繁I/O导致性能下降。

差异解读

逻辑结构不同:分区在逻辑上仍是一张表,只是物理存储被划分成多个部分。用户操作时像操作一张完整表,数据库管理系统在内部处理分区相关操作。例如按时间分区的订单表,查询时无需关心具体分区,系统自动定位。分表在逻辑上已变为多张表,每张表结构相同但存储不同部分数据。操作时需明确针对哪张表,如按地区分表的用户表,查询国内用户需访问国内用户表。

5、分区常见形式

数据库分区有多种实现方式,每种方式适用于不同的数据特征和查询需求。

范围分区(Range Partitioning)

依据某列(或多列组合)的值的范围来划分分区。如以日期列划分销售记录表,可按年份、月份将不同时间范围的数据分别存储在不同分区。例如图中按ID范围ID<5000、ID<10000等进行分区。

适用场景:数据具有明显时间或数值范围特征,且常需按范围查询的场景。像订单表按订单时间分区,方便按不同时间段统计订单。

哈希分区(Hash Partitioning)

使用哈希函数对分区键进行计算,根据哈希值将数据分散到不同分区。如对用户表的用户ID列使用Key mod 3(取模运算),将用户数据均匀分配到3个分区。

适用场景:希望数据均匀分布,避免数据倾斜(即数据集中在某些分区),且无明显范围查询需求的场景。如大型社交平台的用户数据存储,可通过哈希分区让各分区负载均衡。

列表分区(List Partitioning)

根据分区键的离散值进行分区。预先定义离散值与分区的映射关系,如将城市名称(长沙、上海、北京)分别映射到不同分区。

适用场景:数据具有明确离散分类特征的场景。像电商系统中按地区管理用户数据,可将不同省份用户划分到对应分区。

复合分区(Composite Partitioning)

结合多种分区方式,先按一种方式进行粗粒度分区,再在每个粗分区内按另一种方式细分。如先按年份对销售数据进行范围分区,再在每个年份分区内按月份进行范围分区。

适用场景:数据特征复杂,单一分区方式无法满足需求的场景。例如大型企业财务数据,既要按季度做范围分区,又要在每个季度分区内按部门做列表分区。

6、分区优点详解

数据库分区通过多种机制提升系统性能和可管理性。

优势类型 具体说明
存储更多数据 突破单个存储设备容量限制,将数据分散存储在多个存储单元。例如,数据库表数据量超出单个硬盘容量时,通过分区可存储在多个硬盘上,实现数据量扩展
数据管理方便 按类别存储在不同分区,清理特定数据时可直接操作对应分区。如电商平台按年份分区订单数据,清理某年数据只需删除对应分区,无需全表筛选,大幅简化操作流程
提高数据检索效率 依据分区规则精准定位数据,避免全表扫描,显著加快查询速度。如按地区分区的用户表,查询某地区用户时直接定位到该分区,减少数据检索范围,提升查询性能
提高查询吞吐量 多分区并行查询,充分利用多个磁盘的I/O能力,显著提升数据读取速度。在大型数据仓库中,多分区并行查询可大幅提升复杂查询性能,增加单位时间内查询处理量
便于聚合函数查询 各分区数据相对独立且格式一致,可先在各分区内计算聚合结果,再合并汇总。如统计各地区销售额总和,先分区计算再汇总,简化计算过程,提高聚合查询效率

五、NoSQL数据库

1、NoSQL与关系数据库对比

NoSQL数据库与关系数据库在应用领域、数据容量、数据类型等方面存在显著差异。

对比维度 关系数据库 NoSQL数据库
应用领域 面向通用领域,适用于各类传统业务场景,如企业的财务系统、人力资源管理系统等,对数据的一致性、完整性和事务处理要求较高 针对特定应用领域,如互联网应用中的用户行为分析、实时数据处理等场景,处理海量、快速变化且结构多样的数据
数据容量 在处理有限数据量时表现良好,对于小型企业或业务数据量不大的场景能有效管理,但随着数据量急剧增长,性能和扩展性会面临挑战 擅长处理海量数据,通过分布式存储和计算架构,可轻松应对大数据量的存储和查询需求,如大型电商平台的商品信息、用户订单等
数据类型 主要处理结构化数据,以二维表形式存储,数据具有固定的模式(Schema),表中的列和数据类型预先定义好,便于进行复杂的关联查询和数据验证 可处理非结构化数据,如文本、图片、视频等,也能处理半结构化数据,不严格要求固定的模式,数据存储更灵活,适应多样化的数据格式
并发支持 支持并发操作,但由于其严格的事务机制和锁机制,在高并发场景下可能会出现锁竞争,导致性能下降 具备高并发处理能力,通过分布式架构和优化的存储引擎,能更好地应对大量并发请求,在互联网高并发访问场景中表现出色
事务支持 具有高事务性,遵循ACID特性(原子性、一致性、隔离性、持久性),确保数据在并发操作和故障情况下的完整性和一致性,适合对数据准确性要求极高的场景 事务性较弱,通常不严格遵循ACID特性,在一些场景下采用最终一致性模型,虽然牺牲了部分事务严格性,但换来了更高的性能和扩展性
扩展方式 主要采用向上扩展(Scale-up)方式,即通过增加硬件资源来提升数据库性能和处理能力,但存在硬件成本高、扩展上限有限等问题 多采用向外扩展(Scale-out)方式,通过增加服务器节点数量来扩展存储和处理能力,具有良好的扩展性和成本效益,可根据业务需求灵活增减节点

2、NoSQL分类

NoSQL数据库按数据模型可分为键值型、文档型、列族型和图型四大类。

分类 存储方式 适用场景 特点
键值型数据库 以键值对形式存储数据 简单的数据存储和快速查询场景 结构简单,读写速度快,适合缓存和会话存储
文档型数据库 以文档形式存储数据 存储半结构化数据,如JSON格式的数据 灵活的数据结构,支持嵌套文档,适合内容管理
列族型数据库 以列族形式存储数据 大数据分析和数据仓库场景 高压缩比,适合稀疏数据,支持大规模数据存储
图型数据库 以图结构存储数据 处理复杂的关系数据,如社交网络、推荐系统等 擅长处理复杂关系查询,支持图算法和路径分析
分类 代表产品 主要特点
键值型 Redis、Memcached、DynamoDB 内存存储,高性能,支持持久化
文档型 MongoDB、CouchDB、Elasticsearch 灵活的文档结构,支持全文搜索
列族型 Cassandra、HBase、Bigtable 分布式存储,高可用性,适合大数据
图型 Neo4j、ArangoDB、Amazon Neptune 图查询语言,复杂关系分析

六、联邦数据库

1、联邦数据库系统定义

联邦数据库系统是由多个彼此协作但又相互独立的成员数据库系统组成的集合,通过对成员数据库系统进行不同程度的集成,实现数据的统一管理和协同操作。

联邦数据库系统(FDBS)是由多个彼此协作但又相互独立的成员数据库系统(CDBS)组成的集合。它通过对成员数据库系统进行不同程度的集成,实现数据的统一管理和协同操作。联邦数据库管理系统(FDBMS)则是为整个联邦数据库系统提供控制和协同操作功能的软件。

2、联邦数据库特征

联邦数据库具有分布性、异构性、自治性和透明性四个主要特征。

特征 具体说明
分布性 成员数据库分布在不同物理位置,数据存储具有分散性,可分布在不同服务器甚至不同地域,打破数据集中存储限制
异构性 成员数据库可以是不同类型的数据库,如包含文本文件、MySQL、Oracle等不同数据库管理系统,支持不同的数据模型和存储格式
自治性 各成员数据库在一定程度上保持独立自治,有自己的管理和控制机制,可独立进行数据操作和事务处理,同时又能参与联邦数据库的协同工作
透明性 用户操作联邦数据库时,无需关心数据实际存储位置、数据库类型差异等底层细节,就像操作一个统一的数据库,提高使用便捷性
场景类型 应用示例
企业数据整合 整合财务系统、HR系统、CRM系统等不同数据库
跨地域数据访问 跨国公司需要访问不同地区的业务数据
遗留系统集成 将老旧的数据库系统与新建系统整合
数据仓库建设 从多个业务系统抽取数据进行分析

3、联邦数据库分类

联邦数据库按耦合度可分为紧耦合和松耦合两种类型。

耦合类型 具体说明
紧耦合 成员数据库之间耦合度高,相互协作紧密,数据共享和交互频繁,对联邦数据库管理系统的协调能力要求较高。在这种模式下,成员数据库的自治性相对受限,更多服从联邦系统整体调度
松耦合 成员数据库相对独立,彼此间耦合度低,仅在必要时进行有限的数据交互和协作。成员数据库保留较高自治性,联邦数据库管理系统主要起辅助协调作用

七、数据库性能优化

1、集中式数据库优化

集中式数据库优化从硬件系统、系统软件、数据库设计和应用软件四个层面进行综合优化。

数据库性能优化方法

优化层面 具体方法
硬件系统 通过升级CPU提升运算能力,增加内存加快数据读写,优化I/O设备(如采用高速硬盘、磁盘阵列)减少数据存取时间,改善网络设备和配置降低数据传输延迟,从硬件层面为数据库高效运行提供基础
系统软件 调整系统参数,如设置合理的进程优先级,让数据库相关进程优先获取CPU使用权,合理分配内存资源给数据库,保障其运行流畅
应用软件 使用数据库连接池,复用数据库连接,减少连接创建和销毁开销,提高应用程序与数据库交互效率

数据库设计优化

设计方面 优化方法
表与视图 合理规划表结构,避免冗余和不合理的关联。建立物化视图,将视图结果预先计算并存储,可加快查询速度,减少实时计算开销
索引 对于经常用于查询条件的列建立索引,能大幅提升查询效率;但对于经常进行数据修改(插入、更新、删除)的列,避免建立过多索引,因索引维护会增加修改操作开销
SQL优化 用不相干子查询替代相干子查询,减少查询执行时的关联计算;只检索需要的列,避免返回不必要数据,减少I/O和网络传输开销;用带IN的条件子句等价替换OR子句,优化查询执行计划;经常提交COMMIT,尽早释放锁资源,减少锁等待时间;尽量减少多表查询,降低查询复杂度

2、分布式数据库优化

分布式数据库优化主要关注通信代价的降低和查询效率的提升。

优化方法 具体说明
全局查询树的变换 对查询树进行优化变换,改变查询执行顺序和方式,减少数据传输量和网络通信次数
多副本策略 合理设置数据副本,将副本放置在不同节点,使查询能就近获取数据,减少跨节点数据传输,提高查询效率
查询树的分解 将复杂查询树分解为多个简单子查询树,在不同节点并行执行子查询,最后合并结果,利用分布式计算能力,降低整体查询时间
半连接与直接连接 根据数据分布和查询需求,选择合适的连接方式。半连接可先过滤掉不需要传输的数据,减少网络传输量;直接连接则在某些情况下能更高效地完成数据关联
相关推荐
一个天蝎座 白勺 程序猿2 小时前
Oracle与Kingbase深度兼容体验:从连接配置到性能优化全解析
数据库·oracle·性能优化·kingbase·金仓数据库
lang201509282 小时前
InnoDB调优指南:性能优化全解析
数据库·mysql
他们叫我技术总监2 小时前
帆软Report11多语言开发避坑:法语特殊引号导致SQL报错的解决方案
java·数据库·sql
UNbuff_03 小时前
MySQL所有关键字详细含义说明
数据库·mysql
QQ12958455043 小时前
sqlite是什么
数据库·sqlite
豆豆·丁3 小时前
kettle 执行java脚本生成SQL
java·开发语言·数据库
wow_DG3 小时前
【MySQL✨】MySQL 入门之旅 · 第十篇:数据库备份与恢复
android·数据库·mysql
OG one.Z3 小时前
MySQL基础
数据库·mysql·oracle
陈尕六4 小时前
SQL优化实战经验指南
mysql·性能优化