本篇博客写于 2022-07-18,现在从我的旧博客搬运过来。当时还没有 ChatGPT,所以翻译的不太好,也无法保证没有错误,请见谅,原地址:https://blog.kitlau.dev/posts/how-is-data-stored-in-sql-database/
本篇博客技术相关内容翻译自 pragimtech 的:How is data stored in sql database,本文中大部分图片与代码出自该文章。
翻译水平有限,见谅。
0. 前言
作为开发者,数据库相关的知识十分重要,特别是当你想要排除故障并修复性能不好的 SQL 查询时。理解以下这些术语是非常重要的,特别是当你正在进行 Sql Server 性能调优相关的操作时。
- Data pages(数据页)
- Root node(根节点)
- Leaf nodes(叶节点)
- B-tree(B 树)
- Clustered index structure(聚集索引结构)
1. 数据是在物理上是如何存储在 SQL Server 中的?
表中的数据在逻辑上以行和列的格式存储,但在物理上,它以 Data pages(数据页)的形式存储。
数据页是 SQL Server 中数据存储的基本单位,每个数据页的大小为 8KB。当我们将任何数据插入到 SQL Server 数据库表中时,它将该数据保存到一系列 8KB 的数据页中。
![]() |
---|
图 1 - 一系列 8KB 的数据页 |
2. SQL Server 中的数据存储在一个树状结构中
SQL Server 中的表数据实际上存储在一个类似树的结构中。让我们通过一个简单的例子来理解这一点。考虑下面的 Employees 表:
![]() |
---|
图 2 - Employees 表 |
EmployeeId
是主键列;- 因此,默认情况下,将在
EmployeeId
列上创建一个聚集索引; - 这意味着物理存储在数据库中的数据按
EmployeeId
列排序。
看过我翻译的上一篇文章 【译】SQL 索引是如何工作的 的朋友应该已经猜的八九不离十了。
3. 数据实际存储在哪里
它存储在一系列数据页中,这些数据页的树形结构如下所示。
这种树状结构称为:
- B-Tree(B 树);
- index B-Tree(索引 B 树);
- Clustered index structure(聚集索引结构)。
这 3 个名字的意思是一样的。
![]() |
---|
图 3 - 聚集索引结构 |
这实际就是我翻译的上一篇文章的聚集索引结构。
- 在树底部的节点称为数据页或树的叶节点,正是这些叶节点包含我们的表数据。(我们的表数据物理上就是存储在这些叶节点内)
- 每个数据页的大小为 8KB。这意味着每个数据页中存储的行数实际上取决于每行的大小。本例假设一行只有 40B,一个数据页就可以存储 200 行数据。
- 在我们的例子中,假设在这个 Employees 表中有 1200 行,我们假设每个数据页中有 200 行,但实际上,根据实际的行大小,我们可能会有更多的行或更少的行,但在这个例子中,我们假设每个数据页有 200 行。
- 记住,重要的一点是:这些数据页中的行是按
EmployeeId
列排序的,因为EmployeeId
是我们表的主键,因此是聚集键。 - 因此,在第一个数据页中,我们有 1 到 200 行,在第二个是 201 到 400 行,在第三个是 401 到 600 行,以此类推。
- 位于树顶部的节点称为根节点。
- 根节点和叶节点之间的节点称为 intermediate levels(中间层)。
- 可以有很多个中间层。在我们的示例中,我们只有 1200 行,为了使示例简单,我只有 1 个中间层,但实际上,中间层的数量取决于底层数据库表中的行数。
- 根节点和中间层节点包含 index rows(索引行),而叶节点(即树底部的节点)包含实际的数据行。
- 每个索引行包含一个键(在本例中为
EmployeeId
)和一个指向 B 树中的中间层节点或叶节点中的数据行的指针。 - 所以重点是:这个树状结构有一系列的指针,可以帮助数据库引擎快速找到数据。
4. SQL Server 如何通过 ID 找到一个数据行
这部分在我翻译的上一篇文章中已经包含了(【译】SQL 索引是如何工作的 - SQL Server 是如何通过 ID 查到数据行的?),这里不再翻译。
这篇关于SQL数据库数据存储机制的博客写得非常详细且易于理解。作者通过清晰的结构和具体的例子,成功地解释了SQL Server中数据如何物理存储以及索引的作用。
文章的优点在于其逻辑性:从介绍关键术语到逐步拆解树状存储结构,再到通过实际示例进行说明,层层递进,帮助读者构建全面的理解。图表的使用也恰到好处,视觉上辅助理解复杂的概念,比如B-Tree的结构和数据页的分布。
核心理念强调了理解数据库物理存储的重要性,这对于进行有效的查询优化和故障排除至关重要。作者通过Employees表的例子,展示了聚集索引如何影响数据行的排列顺序,这对性能调优有直接指导意义。
建议进一步探讨的内容可能包括:不同类型的索引(如非聚集索引)及其对查询性能的影响,以及在高并发场景下的存储机制优化策略。此外,加入一些实际应用案例或常见问题解答,可以增强文章的实用价值和读者的兴趣。
总体而言,这是一篇内容丰富、结构清晰的基础知识介绍,适合作为学习SQL Server内部工作机制的参考材料。对于数据库新手来说,这篇文章提供了坚实的理解基础;而对于有经验的开发者,它也起到了很好的复习和强化作用。
首先,我想对你的文章表示赞赏。你的文章清晰地解释了 SQL 数据库如何存储数据,包括了数据页、根节点、叶节点、B树和聚集索引结构等重要概念。这些内容对于理解数据库性能优化等高级概念非常有帮助。
你以一个实例来解释这些概念,使得这些抽象的概念更加直观易懂。图文并茂,使得读者能够更好地理解和记住这些概念。同时,你也解释了 SQL Server 如何通过 ID 找到一个数据行,这对于理解 SQL 查询的工作原理非常有帮助。
然而,我觉得你的文章还有一些可以改进的地方。首先,你在文章中提到了一些术语,例如数据页、根节点、叶节点、B树和聚集索引结构,但并没有对这些术语进行详细的解释。虽然你通过一个实例解释了这些概念,但我认为如果能在提到这些术语时,对它们进行详细的解释,会使得读者更好地理解这些概念。其次,你的文章主要关注了 SQL Server,但并没有提到其他的 SQL 数据库系统,例如 MySQL 或 PostgreSQL。我认为如果能够对比不同的 SQL 数据库系统,会使得文章更加丰富。
总的来说,你的文章是一篇优秀的技术文章,我期待你的下一篇文章。