系统架构设计师 数据库篇

news/2024/9/22 13:19:27 标签: 系统架构, 数据库, mysql, postgresql, sqlserver, oracle

数据库 📚

🌐 一个系统化的数据集合,它允许用户存储、检索和管理数据。数据库通常由表格组成,这些表格中存储了结构化的数据。每个表格由行(记录)和列(字段)组成,它们分别对应数据项和数据特征。

数据库的主要特点包括:

  • 组织化 📈:数据以表格的形式组织,使得数据之间的关系清晰,便于管理。
  • 可访问性 🔍:用户可以通过查询语言(如SQL)来访问和操作数据。
  • 一致性 🔄:数据库管理系统(DBMS)确保数据的准确性和一致性。
  • 安全性 🔐:数据库提供了用户认证、权限控制等安全机制,以保护数据不被未授权访问。
  • 冗余减少 🗂️:通过数据规范化,数据库减少了数据冗余,提高了数据的一致性。
  • 灵活性 🛠️:数据库保证了数据的持久存储,即使在系统故障的情况下也能恢复数据。
  • 持久性 💾:数据结构可以根据需要进行调整,以适应不断变化的需求。

数据库类型:

关系型数据库 📊

  • 如MySQL、PostgreSQL、Oracle和SQL Server,它们使用表格、行和列来组织数据,并使用SQL作为查询语言。

非关系型数据库(NoSQL)🌐

  • 如MongoDB、Cassandra和Redis,它们不依赖于表格模型,而是使用其他存储数据的方式,如键值对、文档或图形数据库

数据库并发

在多用户共享系统中,许多事务可能同时对同一数据进行操作。
DBMS控制子系统负责协调并发事务的执行,保证数据库的完整性。

事务的基本概念

事务:用户定义的数据库操作序列,要么全做,要么全不做,是一个不可分割的工作单位。

事务的ACID特性

  • 🔴 原子性(Atomicity):要么全做,要么全不做,不能部分完成。
  • 🔁 一致性(Consistency):事务必须保证数据库从一个一致性状态转移到另一个一致性状态。
  • 🏠 隔离性(Isolation):并发执行的事务之间不会互相影响。
  • 💾 持久性(Durability):一旦事务提交,所做的修改会永久保存在数据库中。

数据不一致问题

  • 📝 丢失修改:两个事务修改同一数据,后提交的事务覆盖前一个事务的结果,导致修改丢失。
  • 🚫 脏数据:事务读取到未提交的修改数据,若修改事务回滚,将导致读取脏数据。
  • 🔄 不可重复读:同一事务两次读取数据,另一个事务在两次读取间修改数据,导致数据不一致。

事务隔离级别

SQL Server 中的事务隔离级别

  • 👀 READ UNCOMMITTED(读取未提交)
    • 允许读取未提交的数据,可能导致脏读。
    • 无法保证数据一致性,但可以提高性能。
    • 适用于对性能要求较高、对一致性要求较低的场景。
  • 🔒 READ COMMITTED(读取已提交)
    • 只能读取已提交的更改,避免脏读。
    • 默认隔离级别,适当平衡一致性和性能。
    • 可能发生不可重复读和幻读。
  • 🔄 REPEATABLE READ(可重复读)
    • 事务在读取数据后,锁定读到的数据行,防止其他事务修改。
    • 防止脏读和不可重复读,但可能发生幻读。
    • 适用于需要多次读取相同数据,并且该数据不能被其他事务修改的场景。
  • 🔓 SNAPSHOT(快照)
    • 提供事务开始时数据的一致性视图,防止脏读、不可重复读和幻读。
    • 使用版本控制技术,可以在不加锁的情况下提供一致性读。
    • 提高并发性能,适用于只读操作较多的场景。
  • 🚧 SERIALIZABLE(可串行化)
    • 最高的隔离级别,完全锁定读到的数据,防止脏读、不可重复读和幻读。
    • 所有事务按顺序执行,确保一致性。
    • 对性能影响较大,适用于对数据一致性要求极高的场景。

Oracle 中的事务隔离级别

  • 🔒 READ COMMITTED(读取已提交)
    • 默认的隔离级别。
    • 只能读取已提交的更改,防止脏读。
    • 使用锁机制防止不可重复读和幻读。
  • 🔄 SERIALIZABLE(可串行化)
    • 与 SQL Server 的 SERIALIZABLE 类似。
    • 提供最高的隔离级别,确保事务按顺序执行。
    • 防止脏读、不可重复读和幻读,但可能导致性能降低。

PostgreSQL 中的事务隔离级别

  • 👀 READ UNCOMMITTED(读取未提交)
    • 实际上在 PostgreSQL 中等同于 READ COMMITTED。
    • 不允许脏读。
  • 🔒 READ COMMITTED(读取已提交)
    • 默认隔离级别。
    • 只能读取已提交的更改,防止脏读。
    • 在同一事务中多次读取数据时,可能会看到其他事务提交的修改。
  • 🔄 REPEATABLE READ(可重复读)
    • 提供一致性的视图,防止脏读和不可重复读。
    • 事务在读取数据后,保证后续读取的相同数据保持一致。
    • 使用多版本控制,可能会出现幻读。
  • 🔓 SERIALIZABLE(可串行化)
    • 提供最高的隔离级别,确保事务按顺序执行。
    • 使用乐观并发控制,检测并防止冲突。
    • 防止脏读、不可重复读和幻读,但可能导致事务被回滚。

MySQL 中的事务隔离级别

  • 👀 READ-UNCOMMITTED(读取未提交)
    • 允许读取尚未提交的数据,可能会导致脏读。
  • 🔒 READ-COMMITTED(读取已提交)
    • 只能读取已提交的数据,防止脏读,但可能发生不可重复读或幻读。
  • 🔄 REPEATABLE-READ(可重复读)
    • 多次读取同一数据结果一致,可防止脏读和不可重复读,但可能发生幻读。
  • 🔓 SERIALIZABLE(可串行化)
    • 最高隔离级别,完全服从ACID,防止脏读、不可重复读和幻读。

封锁协议

处理并发控制的主要方法是采用封锁技术,主要有X封锁和S封锁:

  • 🚫 排他型封锁(X 封锁)
    • 事务对数据对象实现X封锁,只有该事务可以读取和修改数据。
  • 🔄 共享型封锁(S封锁)
    • 事务对数据对象实现S封锁,只允许读取数据,不允许修改。

并发控制技术

Oracle

  • 多种封锁技术,包括数据锁(DML锁)和字典锁。
  • 通过回滚段保证不读“脏”数据和可重复读。
  • 提供有效的死锁检测机制。
伪代码示例 (Oracle)
-- 显式锁定表
LOCK TABLE employees IN EXCLUSIVE MODE;

-- 事务中使用FOR UPDATE来隐式锁定选定的行
BEGIN
  -- 开启事务
  SELECT * FROM employees WHERE employee_id = 123 FOR UPDATE;

  -- 执行更新操作
  UPDATE employees SET salary = salary + 1000 WHERE employee_id = 123;

  -- 提交事务
  COMMIT;
END;

SQL Server

  • 使用行级锁、页级锁、表级锁以及意向锁(Intent Locks)。
  • 支持多种事务隔离级别。
  • 自动检测死锁并终止其中一个事务。
伪代码示例 (SQL Server)
-- 使用SELECT WITH (UPDLOCK)来锁定行
BEGIN TRAN
  SELECT * FROM Employees WITH (UPDLOCK)
  WHERE EmployeeID = 1;

  -- 执行更新操作
  UPDATE Employees
  SET Salary = Salary + 1000
  WHERE EmployeeID = 1;

  -- 提交事务
  COMMIT TRAN

PostgreSQL

  • 使用多版本并发控制(MVCC)处理并发,提高性能。
  • 支持多种事务隔离级别,包括共享锁(S锁)和排他锁(X锁)。
伪代码示例 (PostgreSQL)
-- PostgreSQL中使用SELECT FOR UPDATE来锁定行
BEGIN;
  SELECT * FROM employees WHERE employee_id = 123 FOR UPDATE;

  -- 执行更新操作
  UPDATE employees SET salary = salary + 1000 WHERE employee_id = 123;

  -- 提交事务
  COMMIT;

MySQL

  • InnoDB支持MVCC,允许读不受写操作影响。
  • 使用间隙锁和多版本数据避免幻读。
  • 实现行级锁和表级锁,保证事务串行化调度。
伪代码示例 (MySQL)
-- 使用SELECT FOR UPDATE来锁定行
START TRANSACTION;
  SELECT * FROM employees WHERE employee_id = 123 FOR UPDATE;

  -- 执行更新操作
  UPDATE employees SET salary = salary + 1000 WHERE employee_id = 123;

  -- 提交事务
COMMIT;

索引优化策略

  • 📈 选择性索引:为经常作为查询条件且不常更新的属性创建索引。
  • 🚫 限制索引数量:索引过多会影响UPDATE、INSERT和DELETE的性能。
  • 🕒 分析查询频度:分析每个重要查询的使用频度,建立必要索引。
  • 📉 小数据量无需索引:对于数据量小的关系,不必建立索引。
  • 📈 选择性索引:避免在重复值多的列上建立索引。
  • 🔗 复合索引:常涉及多个列的查询,考虑创建复合索引。
  • 🛠️ 索引维护:定期使用REINDEX命令重建索引,减少碎片。
  • 🕵️ 监控索引性能:通过系统表监控索引使用情况,移除低使用率索引。

避免索引失效的操作

  • 🚫 避免使用函数:WHERE子句中使用函数可能使索引失效。
  • 🚫 避免使用不等式:如!=或<>可能导致全表扫描。
  • 📝 使用参数化查询:避免在WHERE子句中直接使用变量。

查询优化

  • 🏗️ 物化视图:建立物化视图或减少多表查询。
  • 🔄 替换子查询:用不相干子查询替代相干子查询。
  • 📑 仅检索必要属性:只检索需要的属性。
  • 🔐 优化条件子句:用IN子句替换OR子句。
  • 🔄 及时提交:经常提交以尽早释放锁。

数据库的优化策略

SQL Server 优化策略

  • 🔍 使用执行计划分析工具
  • 🛠️ 索引优化
  • 📈 调整表结构和数据类型
  • 🕒 减少锁定
  • ⚙️ 缓存和内存管理

Oracle 优化策略

  • 🔍 使用执行计划分析
  • 🛠️ 索引优化
  • 📊 统计信息和优化器
  • 🕒 减少锁定和提高并发
  • 💽 内存和 I/O 优化

PostgreSQL 优化策略

  • 🔍 使用 EXPLAIN 分析查询计划
  • 🛠️ 索引优化
  • 📊 内存和配置优化
  • 🕒 VACUUM 和 ANALYZE
  • 🧩 表分区和数据归档

MySQL 优化策略

  • 🔍 使用 EXPLAIN 分析查询计划
  • 🛠️ 索引优化
  • 📊 使用慢查询日志
  • 📈 调整缓存和内存设置
  • 🕒 分区表和优化表结构
  • ⚙️ 减少锁定和提高并发

备份与恢复技术

备份方式

  • 💾 物理备份
  • 📜 逻辑备份

物理备份类型

  • 🧊 冷备份
  • 🔥 热备份

按数据量

  • 🔒 完全备份
  • 📈 增量备份
  • 🔄 差异备份

日志文件

事务日志:记录数据库的所有操作,将结果保存在独立文件中,称为日志文件。

  • 🔙 undo log(回滚日志):用于事务回滚和MVCC。
  • 🔄 redo log(重做日志):用于故障恢复,确保事务持久性。
  • 🌐 binlog(归档日志):用于数据备份和主从复制。

总结 🧐

数据库系统中,为了保持数据的一致性和完整性,必须对并发事务进行有效的控制。ACID特性是确保事务可靠性的关键,而隔离级别则在并发控制中起到了平衡性能与一致性的作用。正确的索引设计和查询优化可以显著提升数据库的性能,同时,合理的备份与恢复策略是数据安全的重要保障。

记忆口诀 🎓

  • 原子性:所有操作,要么全做,要么不做。
  • 一致性:数据状态,始终如一。
  • 隔离性:事务之间,互不干扰。
  • 持久性:一旦提交,永不丢失。

趣味记忆互联网案例故事 🌐

想象一下,你在一家全球连锁的咖啡馆,点了一杯咖啡,这就像是开始一个事务。原子性就像是你要么拿到整杯咖啡,要么就不拿;一致性就像是无论你在哪家分店,咖啡的味道和品质都是一致的;隔离性就像是每个顾客都有自己的独立空间,不受其他顾客影响;持久性则像是你已经付款的咖啡,即使出了店门,你依然拥有这杯咖啡。而并发控制就像是咖啡馆的服务员,确保每个顾客的订单都能正确无误地完成,即使在高峰时段,也能保持秩序和质量。

参与点评
读者朋友们,如果您在阅读过程中,对文章的质量、易理解性有任何建议,欢迎在评论区指出,我会认真改进。


http://www.niftyadmin.cn/n/5670332.html

相关文章

在 Qt 中实现 `QListWidget` 列表项水平居中显示

文章目录 在 Qt 中实现 QListWidget 列表项水平居中显示引言QListWidget 和 QListWidgetItem水平居中的实现思路核心代码实现主窗口的设置添加列表项并设置文本居中样式表设置 运行效果可能遇到的问题总结参考文献 在 Qt 中实现 QListWidget 列表项水平居中显示 引言 Qt 是一…

glTF格式:WebGL应用的3D资产优化解决方案

摘要 glTF作为一种高效的3D资产格式&#xff0c;为WebGL、OpenGL ES和OpenGL运行时的应用提供了强有力的支持。它不仅简化了3D模型的传输与加载流程&#xff0c;还通过优化资产大小&#xff0c;使得打包、解包更加便捷。本文将深入探讨glTF格式的优势&#xff0c;并提供实用的代…

《C++中的神秘利器——类型萃取(Type Traits)深度解析》

在 C的浩瀚世界中&#xff0c;类型萃取&#xff08;Type Traits&#xff09;犹如一把神奇的钥匙&#xff0c;为开发者打开了高效编程的大门。那么&#xff0c;C中的类型萃取究竟有什么用呢&#xff1f;让我们一同深入探究。 一、类型萃取的基本概念 类型萃取从字面意思理解&a…

江协科技STM32学习- P15 TIM输出比较

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

二叉树(二)深度遍历和广度遍历

一、层序遍历 广度优先搜索&#xff1a;使用队列&#xff0c;先进先出 模板&#xff1a; 1、定义返回的result和用于辅助的队列 2、队列初始化&#xff1a; root非空时进队 3、遍历整个队列&#xff1a;大循环while(!que.empty()) 记录每层的size以及装每层结果的变量&a…

《论分布式存储系统架构设计》写作框架,软考高级系统架构设计师

论文真题 分布式存储系统&#xff08;Distributed Storage System&#xff09;通常将数据分散存储在多台独立的设备上。传统的网络存储系统采用集中的存储服务器存放所有数据&#xff0c;存储服务器成为系统性能的瓶颈&#xff0c;也是可靠性和安全性的焦点&#xff0c;不能满…

Cisco 基础网络汇总

⭕个人主页 可惜已不在 ⭕可以分享给身边有需要的人 ⭕有用的话就留下一个三连吧 目录 前言: 一.网络及网络设备认识 二. 二层网络 三. 生成树、端口 四. 三层网络 五.访问控制 六.NAT 七.DHCP 八.PPP 九.帧中继 十.热备份 十一.综合实验 十二.WLAN 十三.Cisco P…

Vue3与Flask后端Demo

文章目录 准备工作Flask 后端设置Vue3 前端设置跨域问题测试 准备工作 安装开发环境 安装 Python&#xff08;推荐 Python 3.8 或更高版本&#xff09;。安装 Node.js&#xff08;推荐 LTS 版本&#xff09;。安装 PyCharm&#xff08;用于 Flask 开发&#xff09;和 VSCode&am…