zoukankan      html  css  js  c++  java
  • SQL Server中数据的存储

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

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

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

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

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

    1 文件组(filegroup)

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

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

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

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

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

    2 区段(extent)

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

          关于区段的要点包括:

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

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

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

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

    3 页(page)和页拆分

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

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

          上图展示了数据是如何存放在页中的。对于插入的每一行,为了表明特定行的数据开始于页中的何处,每一页的末尾都用一小块空间记录的每一行相对于页头位置的偏移量。

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

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

    4 行(row)

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

    5 参考资料

          1)  《SQL Server 2008高级程序设计》 (美)Robert Vieira著,清华大学出版社。

          2)  SQL Server 2008联机丛书。

          3)  MSDN。

    6 结语

          本篇博客已经写完了,这是行客第一次真正写完一篇技术博客。在写博客的过程当中,有些知识点不是很确定还参考了一些资料。限于本人水平,文中难免有纰漏或者某些地方没有表述清楚,望读者见谅!在阅读过程中如有发现错误或表述不清的地方,望不吝指教,谢谢!

          读者若想做更深入的了解,建议去MSDN或者查看联机丛书。

          另外,本篇文章系原创,转载请注明出处,谢谢!

  • 相关阅读:
    stenciljs 学习四 组件装饰器
    stenciljs 学习三 组件生命周期
    stenciljs 学习二 pwa 简单应用开发
    stenciljs ionic 团队开发的方便web 组件框架
    stenciljs 学习一 web 组件开发
    使用npm init快速创建web 应用
    adnanh webhook 框架 hook rule
    adnanh webhook 框架 hook 定义
    adnanh webhook 框架request values 说明
    adnanh webhook 框架execute-command 以及参数传递处理
  • 原文地址:https://www.cnblogs.com/fanlinjun/p/5003399.html
Copyright © 2011-2022 走看看