关于SQL Server中数据存储的那些事

知道91 | 教程 | 2015-11-29 | 阅读:3688

我们知道,目前的关系型数据库都是将文件存储在物理磁盘上面,既然是存储在磁盘上面,那么就会涉及到数据存储问题。本文我们主要探讨数据库中数据的存储。

database-wordcloud

与数据库有关的文件有3种,即主数据库文件,次数据库文件和数据库日志文件。主数据库文件和次数据库文件里面存储的是我们的数据和对象,例如表,视图,存储过程等等,是我们程序所要用到的。数据库日志文件包含恢复数据库所需的完整的事务信息,日志文件平时并没有什么特殊的用途,只是记录对数据库的操作,但是当数据库发生误操作或者错误甚至是灾难性的后果时,日志文件就能派上用场。三种数据库文件如下:

主要

主要数据文件包含数据库的启动信息,并指向数据库中的其他文件。用户数据和对象可存储在此文件中,也可以存储在次要数据文件中。每个数据库有一个主要数据文件。主要数据文件的建议文件扩展名是 .mdf。

次要

次要数据文件是可选的,由用户定义并存储用户数据。通过将每个文件放在不同的磁盘驱动器上,次要文件可用于将数据分散到多个磁盘上。另外,如果数据库超过了单个 Windows 文件的最大大小,可以使用次要数据文件,这样数据库就能继续增长。

次要数据文件的建议文件扩展名是 .ndf。

事务日志

事务日志文件保存用于恢复数据库的日志信息。每个数据库必须至少有一个日志文件。事务日志的建议文件扩展名是 .ldf。

文件组(filegroup)

文件组是一个逻辑概念,一个数据库可以包含多个文件组,一个文件组可以包含多个物理数据库文件,每个数据库至少有一个文件组,一个文件组里面至少有一个文件,这就是我们在创建数据库的时候默认的情形。数据库文件组如下图所示:

数据库

那有人会问,为什么要有文件组的概念呢,文件组的作用是什么?通常情况下,有两种情形可以使用文件组:

1.在大型的应用程序中,数据库中存储的数据量也会很大,可能达到几十几百GB,甚至达到数TB,那在这种情况下,用单个数据库文件存储数据,就会出现如索引慢等问题,性能出现瓶颈。这时使用文件组就能比较好的解决这个问题,因为文件组中的某个表,其中的数据会分布在这个文件组所有物理文件中,因此,如果将文件组包含的文件建在不同的磁盘下,那么对一个表的查询将会分散到多个磁盘上,这样就提高了查询效率。

2 . 在某些场景中,需要对业务进行划分,每一块业务相对独立,这个时候可以使用文件组将数据库中的各个业务的数据分开,这时,只需要将各自业务下的表和对象创建在该业务对应的文件组里即可。

文件组中的文件可能分布在各个文件夹下,但是这些文件是一个逻辑整体,文件组中的任何文件都缺一不可,因此如果将文件组中的文件做迁移的时候要注意,不要将某个文件遗漏,否则数据库将无法运行。另外说一点就是文件组里面可以包含主数据库文件,次数据库文件,但是不能包含日志文件。

区段(extent)

区段是用来为表和给定文件中的索引分配空间的基本存储单元。它由8个连续的大小为64KB的数据页组成,即大小为512KB。

关于区段的要点包括:

1.一旦一个区段已满,那么下一条记录将占用一个完整的新区段大小,而不是记录本身的大小。我们可以理解为SQL Server每次分配的空间是一个区段的大小。

2.通过预先分配空间,SQL Server省下了为每一条记录分配新空间的时间。

仅仅因为要添加的行比现在分配的区段所能容纳的行多了一行,就要另外占用整个区段,这似乎是一种浪费。但是,这种方式浪费的空间总量通常并不会那么多,只占了数据库空间很小的比例,但是在高碎片化的环境中,这种浪费可能就比较多了。

占用整个区段空间的好处是SQL Server省去了一些分配空间的时间上的开销。SQL Server不必每写入一行就考虑分配问题,而是在需要新的区段时才处理额外空间的分配。

页(page)和页拆分

与区段是数据库中的分配单元类似,页是区段的分配单元。每一个区段包含8个页,每个页的大小为8KB。

页是到达真正的数据行的最后一个级别。尽管每个区段中页的数量是固定的,但是页中的行数是不固定的,这个取决于行的大小,是可变的。可以把页想成是表和索引行数据的某种容器。数据行是不允许跨页的。

SQL Server中的页有很多种类型,如索引页,数据页等,这里只是一提,不做具体讨论。

当页满时,会对其做拆分。在拆分页时,会创建一个新页,并将已满的页上大约一半的数据移动到新页上存储。但是这也有例外,那就是使用聚集索引的时候。当在表上创建了聚集索引,而且下一个插入的行物理上位于表的最后一行时,那么将创建一个新页并把新的行添加到新的页上,不会把已满的行上一半的数据移动到新页上面。关于页拆分的更深入的探讨,我会在下一篇博客《SQL Server中的索引》中详细呈现,敬请关注^_^。

行(row)

行是数据存储的单位,在SQL Server中,行的大小限制在8KB(8060个字符,此时,页上只有1条记录),行中最大的列数限制在1024列。在数据页上,列最大的限制是8KB(此时的记录是1行1列,并且页上面只有1条记录),这应该就是SQL Server中varchar类型数据最大只能是8000的缘故吧。

总结

本篇博客已经写完了,这是行客第一次真正写完一篇技术博客。在写博客的过程当中,有些知识点不是很确定还参考了一些资料。