根据我的理解(到目前为止),任何给定的用户数据库都包含三种类型的文件——mdf、ndf 和 ldf。
MDF 代表元数据文件并存储数据定义和数据(在小数据库的情况下并且没有其他文件存在数据)。
NDF基本上是针对表数据存储数据的,我们可以根据文件组来决定这里可以分配哪个表。
LDF 代表日志数据文件。这存储 VLF(虚拟日志文件)
我的印象是,只有一个 .mdf 文件属于主文件组,n个 .ndf 文件属于主文件组或用户定义的文件组。
我正在创建一个数据库,并为所有这些文件组和扩展名 .mdf(错误地)创建了多个文件组,令我惊讶的是,现在我的数据库有三个属于不同文件组的 .mdf 文件,如下所示:
CREATE DATABASE [TEST_DBASE]
ON PRIMARY
( NAME = N'TEST_DBASE', FILENAME = N'E:\DB\TEST_DBASE.mdf' , SIZE = 8192KB , FILEGROWTH = 65536KB ),
FILEGROUP [ACCNTS_FILEGROUP]
( NAME = N'ACCNTS_FILE', FILENAME = N'E:\DB\ACCNTS_FILE.mdf' , SIZE = 8192KB , FILEGROWTH = 65536KB ),
FILEGROUP [LOAN_FILEGROUP]
( NAME = N'LOAN_FILE', FILENAME = N'E:\DB\LOAN_FILE.mdf' , SIZE = 8192KB , FILEGROWTH = 65536KB )
这种情况下,如果只需要让Accounts表上线,我们应该如何进行分段恢复呢?
早些时候我们遵循以下步骤:
RESTORE DATABASE [TEST_DBASE]
FILEGROUP = 'PRIMARY' FROM DISK = 'E:\BACKUPS\FullBackup.BAK' with NORECOVERY, PARTIAL
RESTORE DATABASE [TEST_DBASE]
FILEGROUP = 'ACCNTS_FILEGROUP' FROM DISK = 'E:\BACKUPS\FullBackup.BAK' with NORECOVERY
RESTORE LOG [TEST_DBASE] FROM DISK = 'E:\BACKUPS\LogBackup.trn' with RECOVERY
上述步骤使 Accounts 表在线且可访问。
为了在稍后的某个时间点(非关键表)使贷款表联机,我们过去常常执行以下步骤:
BACKUP LOG [BANK_DATABASE] TO DISK = 'E:\BACKUPS\Backup_tail.trn' with FORMAT, NORECOVERY
RESTORE DATABASE [TEST_DBASE]
FILEGROUP = 'LOAN_FILEGROUP' FROM DISK = 'E:\BACKUPS\FullBackup.BAK' with NORECOVERY
RESTORE LOG [TEST_DBASE] FROM DISK = 'E:\BACKUPS\LogBackup.trn' with NORECOVERY
RESTORE LOG [TEST_DBASE] FROM DISK = 'E:\BACKUPS\Backup_tail.trn' with RECOVERY
在上述情况下,我担心的是 - 考虑到元数据文件现在分布在所有文件组中并且不仅仅属于主文件组这一事实,零碎恢复是否会有任何变化。
对于任何部分恢复,主文件组的恢复是强制性的,因为它包含所有元数据,但是如果所有文件现在都是 .mdf,它将如何工作?
文件扩展名对应用程序没有意义。例如,创建一个文本文件并命名
textfile.foo
并在记事本中打开它。记事本不关心文件名是什么——它只是打开它,因为你告诉它打开它。SQL Server 的工作方式相同。您可以使用您想要的任何扩展名来命名文件,这不会改变 SQL Server 使用它们的方式。第一个数据文件(通常是带有 .mdf 文件的文件)将始终保存元数据并且永远无法删除。元数据不会仅仅因为您为它们提供了 .mdf 文件扩展名而散布到其他文件中。
文件扩展名几乎总是为人类而设——这样我们就可以更轻松地跟踪事物。因此,我们在第一个数据文件上使用 .mdf 扩展名,在其他数据文件上使用 .ndf 扩展名,以便人们能够轻松分辨哪个文件包含元数据并且永远不会从数据库中删除。
我确信有一些应用程序需要文件扩展名来满足某些要求,但 SQL Server 不是其中之一,至少在数据库文件的文件扩展名方面不是。