主题定位:
- 基础理论:结构化数据的存储、事务
- 基础数据结构:平衡二叉树、红黑树
- 云数据库:云数据库产品、与云数据库相连的服务。
建议搭配
4_RDB数据库.smm、4_Nosql数据库.smm和4_树形数据结构.smm一同学习
# 数据库基础概念
# 数据库类型
- RDB(关系型数据库):也就是 MySQL、PostgreSQL 这种表格型数据库。
前辈语录:
由于查询一定有规则,所以我们往往需要的不是一个 scheme-less 的数据库(这是手段不是目的),而是要一个能储存不规则数据的 RDB。
# 事务四特性 ACID
数据库中的 ACID 是保证事务(Transaction)可靠执行的四个核心特性:
-
A — Atomicity(原子性):事务要么全部成功,要么全部失败回滚。
不会只执行一部分。
类比:转账要么钱同时扣和加,要么都不发生。
-
C — Consistency(一致性):事务执行前后,数据库都必须处于合法状态,不违反约束(如主键、外键、余额不能为负等)。
数据始终符合规则。
-
I — Isolation(隔离性):多个事务并发执行时彼此互不干扰,中间状态不会被其他事务看到。
每个事务像 "单独运行"。
-
D — Durability(持久性):事务一旦提交,数据就会永久保存,即使断电或崩溃也不会丢失(依赖日志机制)。
数据能长期保存不丢
# 事务隔离级别
四种事务隔离级别是为了在数据一致性和数据库并发性能之间寻找平衡而设计的。首先需要了解并发事务中可能出现的三种 "数据读取问题":
- 脏读(Dirty Read):事务 A 读取了事务 B 尚未提交的数据。如果 B 后来回滚了,A 读到的就是不存在的无效数据。
- 不可重复读(Non-repeatable Read):针对 update。 事务 A 在同一次事务中两次读取同一条记录,结果不一样 —— 因为两次读取之间,事务 B 修改了这条记录并提交。
- 幻读(Phantom Read):针对 insert 和 delete。 事务 A 在同一次事务中两次执行相同范围查询,第二次结果多出(或减少)了一些行 —— 因为两次查询之间,事务 B 插入或删除了数据并提交。
四种级别:
- Read Uncommitted(读未提交)
- 含义:最低的隔离级别。一个事务可以读取到另一个事务修改但尚未提交的数据。
- 存在的问题:脏读、不可重复读、幻读都有可能发生。
- 应用场景:极少使用,因为数据极不安全,除非是完全不在乎数据准确性的统计场景。
- Read Committed(读已提交)
- 含义:一个事务只能读取到其他事务已经提交的数据。未提交的数据对当前事务是不可见的。
- 解决与存在的问题:解决了脏读;但仍然存在不可重复读和幻读。
- 应用场景:大多数主流数据库(如 Oracle、SQL Server、PostgreSQL)的默认隔离级别。它在性能和安全性之间取得了较好的平衡。
- Repeatable Read(可重复读)
- 含义:保证在同一个事务中,多次读取同样的数据结果是一致的。也就是说,事务开启后,其他事务对这些数据的修改(Update)对该事务是不可见的。
- 解决与存在的问题:解决了脏读和不可重复读;但在 SQL 标准定义中,仍然存在幻读(即其他事务新增的数据行可能会被查出来)。
- 应用场景:MySQL (InnoDB 引擎) 的默认隔离级别。
- Serializable(串行化 / 序列化)
- 含义:最高的隔离级别。它强制事务串行执行(相当于排队,一个接一个地执行),事务之间完全不可能产生干扰。
- 解决与存在的问题:完美解决了脏读、不可重复读、幻读的所有问题。
- 应用场景:极少使用。因为这种级别会在数据上加极严格的锁,导致数据库并发性能极差,极易出现死锁和锁等待。
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 并发性能 |
|---|---|---|---|---|
| Read Uncommitted (读未提交) | ❌ 允许 | ❌ 允许 | ❌ 允许 | 最高 |
| Read Committed (读已提交) | ✅ 避免 | ❌ 允许 | ❌ 允许 | 较高 |
| Repeatable Read (可重复读) | ✅ 避免 | ✅ 避免 | ❌ 允许 | 较低 |
| Serializable (串行化) | ✅ 避免 | ✅ 避免 | ✅ 避免 | 最低 |
隔离级别越高,数据越安全一致,但数据库的并发处理能力就越差。
MySQL 产品设计问题:
transaction 中的操作一起发生,不然就回滚。但是对于 MySQL :
- 纯查询 select 语句走 Repeatable Read,读到 update 前的值;但若命令既有查询又有写入(insert select),则查询时走 Read Committed,能读到 update 后的值。
- 对 DDL 定义数据集(create、drop)、DML(增删改查),DDL 优先级比 transaction 大,没法回滚。
# 主键、外键、索引
- PRIMARY KEY 主键 = 唯一标识一行数据,要求唯一、不重复、非空。
- FOREIGN KEY 外键 = 规定必须引用其他表里的 id。
- 索引:由于全表扫描很慢,数据库会偷偷建一个目录,以后查询直接翻目录,快很多。
SQL 会自动为主键创建索引。
# 数据库相关数据结构
# 平衡二叉树(AVL)
- 左子树小于 node,右子树大于 node。
- 平衡因子 = 左子树高度 − 右子树高度,平衡因子的绝对值 ≤ 1,即平衡因子 ∈
- 增:
- 删:
- 改:
- 查:
# 红黑树
- 左中右:满足二叉搜索树的中序有序性质。
- 根叶黑:根节点为黑色;所有叶子空节点(NIL)也为黑色。
- 不红红:红色节点不能与红色父 / 子节点相邻。
- 黑路同:从任一节点到其所有后代叶子节点的路径,包含相同数量的黑色节点。
# 云数据库
# 性能优化能力
# IBP(InnoDB Buffer Pool,InnoDB 缓冲池)
-
概念本质:它是 MySQL 数据库在内存中划分出的一块区域,专门用来存放最近访问过的数据和索引。
-
为什么需要它:数据库的数据最终是存在硬盘上的,但硬盘读写速度很慢。为了提高速度,数据库会把从硬盘读出来的数据暂时放在内存(也就是 IBP)里。下次再查同样的数据,直接从内存拿,速度极快。
-
举个例子:
假设你有一个千万级用户的user表。-
第一次查询:用户 A 登录,数据库去硬盘里找到 A 的数据,不仅把 A 的数据返回,还顺便把 A 的数据存进 IBP 里。这个过程比较慢。
-
第二次查询:用户 A 刷新了页面,数据库发现 IBP 里已经有 A 的数据了,直接从内存返回。这个过程极快。
-
架构师关注点:在云数据库选型或调优时,IBP 的大小通常占整个数据库服务器内存的 60%-80%。IBP 越大,能装进内存的热点数据就越多,数据库性能越好。
-
# Cache 预热优化(Cache Warm-up)
- 概念本质:在数据库刚启动,或者 IBP(缓冲池)被清空时,主动把常用的热点数据从硬盘提前加载到内存中的过程。
- 为什么需要它:数据库刚重启时,IBP 是空的。这时候如果大量真实用户的请求涌进来,所有请求都会直接去读硬盘,导致硬盘压力瞬间飙升,数据库可能会卡死(这叫 “缓存击穿” 或 “冷启动问题”)。
- 举个例子:
你们的云数据库在凌晨 3 点进行了一次升级重启。重启后内存是空的。- 没有预热:早上 8 点早高峰,大量用户同时打开 APP,数据库疯狂读硬盘,响应极慢,甚至宕机。
- 有预热优化:凌晨 3 点重启完毕后,系统立刻运行一个内部脚本,把昨天访问量最高的 100 万个商品数据主动查一遍。这样这些数据就被放进了 IBP 里。早上 8 点早高峰来临时,用户的查询直接命中内存,平稳度过。
# Fast DDL(Online DDL / Instant DDL)
- 概念本质:在对表结构进行修改(比如加字段、删字段、改字段类型)时,不需要锁死整张表,且能极快完成的技术。
- 为什么需要它:传统的 DDL(Data Definition Language,比如
ALTER TABLE)操作时,数据库会把整张表锁住,并且把老表的数据一行行复制到新表。如果表有 1 亿条数据,这个过程可能需要几小时,期间业务完全无法写入新数据,导致停机。 - 举个例子:
产品经理要求在 1 亿条记录的users表里加一个nickname(昵称)字段。- 传统 DDL:数据库锁表,花 2 小时把 1 亿条数据挪到一个带
nickname字段的新表里。这 2 小时内,用户无法注册、无法修改资料。 - Fast DDL(比如 MySQL 8.0 的 Instant DDL):数据库只在 “数据字典(记录表结构的地方)” 里写一笔:“从今天起,这张表多了一个 nickname 字段,默认值是空”。底层真实的 1 亿行数据根本不动。整个过程不到 1 秒钟就完成了,业务毫无感知。
- 传统 DDL:数据库锁表,花 2 小时把 1 亿条数据挪到一个带
# 索引并行创建(Parallel Index Creation)
- 概念本质:利用服务器的多个 CPU 核心,同时分工合作来为一张表创建索引。
- 为什么需要它:创建索引是一个非常消耗 CPU 的操作,因为需要对表里的海量数据进行读取和排序。以前的数据库通常只用单线程(1 个 CPU 核心)去干这事,如果表很大,会非常慢。
- 举个例子:
你有一张 50GB 的历史日志表,现在需要给create_time字段加个索引,以便快速查询某天的数据。- 单线程创建:数据库派 1 个 CPU 核心去读取这 50GB 数据并排序,花了 1 个小时。
- 索引并行创建:你告诉数据库
PARALLEL 4(开启 4 个并行度)。数据库把 50GB 数据切分成 4 份,派 4 个 CPU 核心同时去读取和排序,最后再合并结果。时间可能直接缩短到 15 分钟。
# 参数模板(Parameter Template)
- 概念本质:云厂商提前配置好的一套数据库引擎参数集合。你可以把它理解为数据库的 “一键优化配置文件”。
- 解决什么痛点(高性能):像 MySQL、PostgreSQL 这样的数据库,底层有几百个参数(比如我们前面提到的 IBP 缓冲池大小、最大连接数、排序内存大小等)。如果让用户自己去配,很容易配错导致性能极差甚至崩溃。
- 举个例子:
- 你买了一个 16 核 64GB 内存的云数据库。
- 手动配置:你需要自己去算,64G 内存里,多少分配给 IBP?多少分配给连接线程?非常考验 DBA(数据库管理员)的功底。
- 使用参数模板:云厂商的顶级 DBA 已经帮你测试过了,针对 16C64G 的规格,他们做了一个 “高性能参数模板”。你只需要在控制台点击 “应用该模板”,系统就会自动把 IBP 设置为 48GB,最大连接数设置为 8000 等等。它能让数据库直接运行在最佳状态。
# 读写分离(Read-Write Splitting)
- 概念本质:把数据库的 “写操作(增删改)” 和 “读操作(查询)” 分开,交给不同的数据库节点去处理。
- 解决什么痛点(高性能):绝大多数的互联网应用,都是 **“读多写少”** 的(比如刷微博、逛淘宝,看的人多,发帖 / 下单的人少,读写比例可能达到 10:1 甚至更高)。如果所有的读写请求都压在一个主节点上,主节点的 CPU 很快就会被打满。
- 举个例子:
- 你有一个 3 节点的云数据库(1 个主节点,2 个只读节点)。
- 没有读写分离:用户注册(写)、用户修改头像(写)、10 万用户同时浏览商品列表(读),全部由主节点处理。主节点不堪重负,响应变慢。
- 开启读写分离:云数据库会提供一个统一的 “读写分离地址”。当你的代码连接这个地址时,云底层的代理网关会自动进行分发:
- 遇到
INSERT、UPDATE、DELETE(写操作),网关把它转发给主节点。 - 遇到
SELECT(读操作),网关把它均匀地分发给那 2 个只读节点。
- 遇到
- 结果:主节点只负责写,压力骤降;海量的查询请求被多个只读节点分摊,整个系统的并发处理能力大幅提升。
# 数据保护能力
# 原生闪回(Native Flashback)
- 概念本质:数据库引擎自带的一种快速数据恢复机制,可以让某张表或整个库的数据快速 “倒退” 到过去的某一个精确时间点。
- 为什么需要它:“原生” 意味着它是数据库底层直接支持的,不需要依赖复杂的第三方工具。传统的恢复方法是找昨天的备份文件,重新导入一遍,再把今天的增量日志重放,耗时可能长达几个小时。闪回则是利用数据库内部的 “撤销日志(Undo Log)” 直接逆向操作。
- 举个例子:
下午 2:00,你不小心执行了一条UPDATE users SET vip_level = 0;(忘记加WHERE条件),把全量用户的 VIP 全清零了。- 传统恢复:下载昨天的全量备份,导入备用库,再导出今天的数据,耗时 3 小时。
- 原生闪回:你直接执行一条命令,告诉数据库 “把
users表闪回到下午 1:59 的状态”。数据库底层自动读取撤销日志,几秒钟或几分钟内就把数据变回去了。
# 原生回收站(Native Recycle Bin)
-
概念本质:和 Windows 电脑的回收站一模一样。当你删除(DROP)一张表时,数据库不立刻在硬盘上抹除它,而是把它重命名并放进一个隐藏的区域
-
为什么需要它:防止 “删库跑路” 或严重的人为误操作。
-
举个例子:
你原本想删除测试表test_orders,结果手抖敲成了DROP TABLE orders;(真实的订单表)。-
没有回收站:表结构和数据瞬间灰飞烟灭,你只能满头大汗地去走上面的 “闪回” 或 “备份恢复” 流程。
-
有原生回收站:表其实还在硬盘上,只是名字变成了类似
__recycle_bin_orders_123并且对业务隐藏了。你只需要执行一句RESTORE TABLE orders;,表瞬间就回来了。
-
# TDE 透明加密(Transparent Data Encryption)
-
概念本质:一种在硬盘存储层面自动对数据进行加密和解密的技术。
-
为什么叫 “透明”:这里的透明不是指 “看得见”,而是指 “对开发人员和应用程序完全无感知”。你的代码不需要做任何修改,不需要自己写加密算法。
-
解决什么痛点(安全):防止 “物理层面的数据泄露”。也就是防止有人直接把云机房的物理硬盘拔走,或者把底层的数据库文件(如
.ibd文件)直接拷走。 -
举个例子:
-
没有 TDE:黑客偷走了硬盘,用文本编辑器打开数据库文件,直接就能看到明文的
password: 123456。 -
开启 TDE:数据库在把数据写入硬盘的最后一刻,自动将其加密成乱码;在从硬盘读到内存(IBP)时,又自动解密。黑客偷走硬盘只能看到一堆乱码。但你的业务 APP 执行
SELECT * FROM users时,拿到的依然是正常数据。
-
# SSL(Secure Sockets Layer / TLS)
-
概念本质:一种在网络传输层面对数据进行加密的技术。
-
解决什么痛点(安全):TDE 保护的是 “躺在硬盘里的数据(静态数据)”,而 SSL 保护的是 “跑在网线里的数据(动态数据)”。它防止的是中间人抓包窃听。
-
举个例子:
你的应用服务器在北京,云数据库在上海。
-
没有 SSL:应用服务器向数据库发送查询请求
SELECT * FROM users WHERE pwd='my_secret_password'。这句话在经过几千公里的光缆、各种路由器时,是明文传输的。如果有人在中间节点拦截网络包,就能把密码看光。 -
开启 SSL:应用服务器和数据库之间建立了一条 “加密隧道”。传输的内容变成了乱码,只有数据库端拥有密钥才能解开,保证了数据在网络传输过程中的绝对安全。
-
架构师小结:TDE 防 "偷硬盘",SSL 防 "网线抓包",两者结合才是完整的安全合规方案。
# 灾备 & 可用
# 容灾备份:副本与备份
当你往云数据库 / 云存储里写入一条数据时,云厂商底层的分布式存储系统会立刻进行复制。
-
副本:行业标准是 3 份(3 副本)。你存入的 1 份数据,会被实时、同步地写到机房里 3 块不同的物理硬盘上(通常还会跨越不同机架,防止一个机柜断电)。
-
备份:为防 "删库跑路" 或代码 Bug 把数据搞乱,会定期把数据打包,存到极其便宜且安全的冷存储(如对象存储 OSS/S3)里。
通常策略是:每天 1 个全量备份(快照)+ 持续不断的增量日志备份(Binlog/Redo Log)。若设置保留 7 天,就是 7 份全量备份加这 7 天内所有操作日志。
# 高可用:3 节点(1 主 2 从)
“3 节点”,指的是运行数据库软件(比如 MySQL 进程)的服务器数量。这通常意味着 1 个主节点(Primary/Master)加上 2 个备用 / 只读节点(Secondary/Slave),防止一台服务器宕机整个业务中断。
# 举例对比
假设你的数据库是一套 “档案管理系统”:
- 3 副本:同一份档案复印 3 份放在 3 个不同保险柜里(硬盘),目的是防数据丢失。主要目的是容灾备份
- 3 节点(1 主 2 从):雇了 3 个档案管理员(服务器),主管理员生病请假(主节点宕机),另外 2 个瞬间接管,保证业务不中断。主要目的是高可用
# 云数据库运维工具
- DTS:负责数据的搬家、跨库同步与分发。
- DMC(Data Management Center):不用装软件、打开网页就能用的数据库操作管理界面,是日常操作数据的入口。
- DBbrain(数据库智能管家):数据库跑久了会 "生病"—— 某条 SQL 写得烂导致全站变慢、磁盘空间莫名被占满、半夜突然卡顿。以前这些得靠经验丰富的 DBA(数据库管理员) 人工排查,既慢又贵。DBbrain 用机器学习 + 专家经验,把资深 DBA 的本事做成 7×24 小时在线的自动服务,做诊断、分析、优化,有些问题还能自动处理。
# 数据检索与分析服务
- ES(Elasticsearch):基于倒排索引技术实现的分布式全文检索引擎,专门用于对海量文本数据进行快速、泛化的搜索。
- BI(Business Intelligence)产品:云端部署的商业智能软件,属于 SaaS。它连接数据库或其他数据源,对数据进行分析,并生成可视化报表和仪表盘,帮助企业快速决策。