代码改变世界

数据库引擎 - 文件和文件组体系结构

2013-02-17 14:26  BIWORK  阅读(593)  评论(0编辑  收藏  举报

SQL Server 将数据库映射为一组操作系统文件. 数据和日志信息绝不会混合在同一个文件中, 而且一个文件只由一个数据库使用.

文件组是命名的文件集合,用于帮助数据布局和管理任务,例如备份和还原操作.


数据库文件

SQL Server 数据库具有三种类型的文件:

  • 主数据文件

    主数据文件是数据库的起点, 指向数据库中的其他文件. 每个数据库都有一个主数据文件, 主数据文件的推荐文件扩展名是 .mdf 

  • 次要数据文件

    除主数据文件以外的所有其他数据文件都是次要数据文件. 某些数据库可能不含有任何次要数据文件, 而有些数据库则含有多个次要数据文件, 次要数据文件的推荐文件扩展名是 .ndf。

  • 日志文件

    日志文件包含着用于恢复数据库的所有日志信息. 每个数据库必须至少有一个日志文件,当然也可以有多个, 日志文件的推荐文件扩展名是 .ldf。

SQL Server 不强制使用 .mdf、.ndf 和 .ldf 文件扩展名, 但使用它们有助于标识文件的各种类型和用途. 

在 SQL Server 中, 数据库中所有文件的位置都记录在数据库的主文件和 master 数据库中. 大多数情况下, SQL Server 数据库引擎使用 master 数据库中的文件位置信息. 但是,在下列情况下, 数据库引擎使用主文件的文件位置信息初始化 master 数据库中的文件位置项:

  • 使用带有 FOR ATTACH 或 FOR ATTACH_REBUILD_LOG 选项的 CREATE DATABASE 语句来附加数据库时. 

  • 从 SQL Server 2000 版或 7.0 版升级时.

  • 还原 master 数据库时.

逻辑和物理文件名称

SQL Server 文件有两个名称:

logical_file_name

logical_file_name 是在所有 Transact-SQL 语句中引用物理文件时所使用的名称. 逻辑文件名必须符合 SQL Server 标识符规则, 而且在数据库中的逻辑文件名中必须是唯一的。

os_file_name

os_file_name 是包括目录路径的物理文件名, 它必须符合操作系统文件命名规则. 

SQL Server 数据和日志文件可以保存在 FAT 或 NTFS 文件系统中。由于 NTFS 在安全方面具有优势,因此, 我们建议您使用 NTFS 文件系统. 可读/写数据文件组和日志文件不能保存在 NTFS 压缩文件系统中, 只有只读数据库和只读次要文件组可以保存在 NTFS 压缩文件系统中.

如果多个 SQL Server 实例在一台计算机上运行, 则每个实例都会接收到不同的默认目录来保存在该实例中创建的数据库文件. 有关详细信息, 请参阅 SQL Server 的默认实例和命名实例的文件位置

数据文件页

SQL Server 数据文件中的页按顺序编号,文件的首页以 0 开始. 数据库中的每个文件都有一个唯一的文件 ID 号, 若要唯一标识数据库中的页, 需要同时使用文件 ID 和页码. 下例显示了包含 4-MB 主数据文件和 1-MB 次要数据文件的数据库中的页码. 

每个文件的第一页是一个包含有关文件属性信息的文件的页首页. 在文件开始处的其他几页也包含系统信息(例如分配映射). 

有一个存储在主数据文件和第一个日志文件中的系统页是包含数据库属性信息的数据库引导页. 有关页和页类型的详细信息, 请参阅页和区

文件大小

SQL Server 文件可以从它们最初指定的大小开始自动增长, 在定义文件时, 您可以指定一个特定的增量. 每次填充文件时, 其大小均按此增量来增长. 如果文件组中有多个文件, 则它们在所有文件被填满之前不会自动增长. 填满后, 这些文件会循环增长. 

每个文件还可以指定一个最大大小. 如果没有指定最大大小, 文件可以一直增长到用完磁盘上的所有可用空间. 如果 SQL Server 作为数据库嵌入某应用程序, 而该应用程序的用户无法迅速与系统管理员联系, 则此功能就特别有用.  用户可以使文件根据需要自动增长, 以减轻监视数据库中的可用空间和手动分配额外空间的管理负担. 


数据库快照文件

数据库快照存储其“写入时复制”数据时所用的文件格式取决于快照是由用户创建,还是在内部使用-

  • 用户创建的数据库快照将其数据存储在一个或多个稀疏文件中。稀疏文件技术是 NTFS 文件系统的一项功能。首先,稀疏文件不包含任何用户数据,并且没有为稀疏文件分配用于用户数据的磁盘空间。有关在数据库快照中使用稀疏文件以及数据库快照增长方式的一般信息,请参阅数据库快照的工作方式了解数据库快照中的稀疏文件大小
  • 数据库快照通过特定的 DBCC 命令在内部使用。这些命令包括 DBCC CHECKDB、DBCC CHECKTABLE、DBCC CHECKALLOC 和 DBCC CHECKFILEGROUP. 内部数据库快照使用原始数据库文件的稀疏备用数据流。和稀疏文件一样,备用数据库流也是 NTFS 文件系统的一项功能。使用稀疏备用数据流,可以进行多项数据分配,使其与单个文件或文件夹进行关联,但不影响文件大小或卷统计信息。

数据库文件组

为便于分配和管理, 可以将数据库对象和文件一起分成文件组. 有两种类型的文件组: 

主文件组

主文件组包含主数据文件和任何没有明确分配给其他文件组的其他文件, 系统表的所有页均分配在主文件组中. 

用户定义文件组

用户定义文件组是通过在 CREATE DATABASE 或 ALTER DATABASE 语句中使用 FILEGROUP 关键字指定的任何文件组. 

日志文件不包括在文件组内, 日志空间与数据空间分开管理. 

一个文件不可以是多个文件组的成员. 表、索引和大型对象数据可以与指定的文件组相关联.  在这种情况下, 它们的所有页将被分配到该文件组, 或者对表和索引进行分区. 

已分区表和索引的数据被分割为单元, 每个单元可以放置在数据库中的单独文件组中. 有关已分区表和索引的详细信息, 请参阅已分区表和已分区索引

每个数据库中均有一个文件组被指定为默认文件组, 如果创建表或索引时未指定文件组, 则将假定所有页都从默认文件组分配. 一次只能有一个文件组作为默认文件组. 

db_owner 固定数据库角色成员可以将默认文件组从一个文件组切换到另一个. 如果没有指定默认文件组, 则将主文件组作为默认文件组. 

文件和文件组示例

以下示例在 SQL Server 实例上创建了一个数据库. 该数据库包括一个主数据文件, 一个用户定义文件组和一个日志文件. 主数据文件在主文件组中, 而用户定义文件组包含两个次要数据文件. ALTER DATABASE 语句将用户定义文件组指定为默认文件组, 然后通过指定用户定义文件组来创建表. 

USE master;
GO
-- Create the database with the default data
-- filegroup and a log file. Specify the
-- growth increment and the max size for the
-- primary data file.
CREATE DATABASE MyDB
ON PRIMARY
  ( NAME='MyDB_Primary',
    FILENAME=
       'c:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\data\MyDB_Prm.mdf',
    SIZE=4MB,
    MAXSIZE=10MB,
    FILEGROWTH=1MB),
FILEGROUP MyDB_FG1
  ( NAME = 'MyDB_FG1_Dat1',
    FILENAME =
       'c:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\data\MyDB_FG1_1.ndf',

    SIZE = 1MB,
    MAXSIZE=10MB,
    FILEGROWTH=1MB),
  ( NAME = 'MyDB_FG1_Dat2',
    FILENAME =
       'c:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\data\MyDB_FG1_2.ndf',
    SIZE = 1MB,
    MAXSIZE=10MB,
    FILEGROWTH=1MB)
LOG ON
  ( NAME='MyDB_log',
    FILENAME =
       'c:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\data\MyDB.ldf',
    SIZE=1MB,
    MAXSIZE=10MB,
    FILEGROWTH=1MB);
GO
ALTER DATABASE MyDB 
  MODIFY FILEGROUP MyDB_FG1 DEFAULT;
GO
 
-- Create a table in the user-defined filegroup.
USE MyDB;
CREATE TABLE MyTable
  ( cola int PRIMARY KEY,
    colb char(8) )
ON MyDB_FG1;
GO

下图总结上述示例的结果