10.实现SQL Server 2008中的文件流功能
SQL Server 2008中最新的文件流功能使得你可以配制一个数据类型为varbinary(max)的列,以便将实际数据存储在文件系统中,而非在数据库中。只要愿意,你仍可以作为一个常规的二进制列来查询此列,即使数据自身存储在外部。
文件流特性通过将二进制大字段数据存储在本地文件系统中,从而将Windows新技术文件系统(NTFS)和SQL Server数据库引擎集成在一起。你可以使用Transact-SQL语句来查询、插入或更新数据,或者使用Win32文件系统界面来直接访问数据。
微软建议你仅在以下几种情况下使用文件流:(1)你的二进制大字段数据文件平均大于1M,(2)你需要快速读取此数据,(3)你的应用程序使用中间列来处理应用逻辑。否则,你应该使用常规的varbinary(max)列。
要激活SQL Server 2008服务中的文件流支持,需要遵照以下几步:
·配制数据库来支持文件流存储。
·定义支持文件流存储的列。
·启动SQL Server服务中的文件流支持
要激活SQL Server 2008中指定实例的文件流支持,你必须首先配制此实例的SQL Server服务。在SQL Server配制管理器中,打开服务属性并选择“文件流”页签。
你至少需要选上“启动Transact-SQL文件流访问”勾选框。因为插入及更新数据最有效的方法是通过Win32界面,然而,你也需要激活服务来持文件流(如果有必要,也可以启动允许远程客户端访问文件流数据)。
在你激活了SQL Server服务中的文件流支持后,必须设置文件流访问级别,你可以在SQL Server管理器中设置。要设置访问级别,需执行以下T-SQL语句:
GO
RECONFIGURE
GO
在这里,我使用系统存储过程sp_configure将访问级别设为2,这个级别可同时支持T-SQL和Win32流访问。如果我想只是支持T-SQL访问,则需要将访问级别设为1。如果设置为0,将会禁用SQL Server实例的文件流支持。在你运行存储过程后,需要运行RECONFIGURE命令来应用新的选项设置。
配制数据库来支持文件流存储
支持文件流存储的下一步操作是向数据库定义中添加一个文件流文件组。文件流文件组是一个特殊的文件组类型,它包含文件系统目录(数据容器)。例如,在下边的数据库定义中,我创建了一个名为FileStreamGrp的文件流文件组。
GO
IF EXISTS
SELECT name FROM sys.databases
WHERE name = 'HumanResources')
DROP DATABASE HumanResources
GO
CREATE DATABASE HumanResources
ON
PRIMARY(
NAME = HumanRscsDat,
FILENAME = 'C:\Data\HR\HumanRscsDat.mdf'),
FILEGROUP FileStreamGrp CONTAINS FILESTREAM(
NAME = HumanRscsFs,
FILENAME = 'C:\Data\HR\FileStream')
LOG ON(
NAME = HumanRscsLog,
FILENAME = 'C:\Data\HR\HumanRscsLof.ldf')
注意,文件流文件组定义包括“文件流关键字”,后边跟着逻辑名与文件名。在这里,此文件名仅仅是一个目录路径,没有一个真实的名称。当你指定了路径,每个对象(除了最深的一个)必须存在,且最深的一个不存在。举个例子,目录C:\DATA\HR必须在你运
行此语句之前存在,但是C:\Data\HR\FileStream不能存在。 当你向数据库定义中增加一个文件流文件组,SQL Server将自动创建必要的文件夹及filestream.hdr文件(这个文件是文件流容器的头文件)和$FSLOG文件夹(支持文件流日志)。
定义支持文件流存储的列
设置文件流存储的下一步是配制文件流列。要使一张表包含一个文件流列,它必须也要包含一个ROWGUIDCOL关键字,且此关键字需要配制为非空和唯一约束。这个文件流列对于支持Win32文件流访问来说是必须的。
此文件流列本身必须配制为varbinary(max)类型,并包含FILESTREAM关键字,如下边的建表语句:
GO
IF OBJECT_ID ( N'Candidate', N'U') IS NOT NULL
DROP TABLE dbo.Candidate
GO
CREATE TABLE Candidate(
CandidateId INT IDENTITY PRIMARY KEY,
CandidateGuid UNIQUEIDENTIFIER ROWGUIDCOL
NOT NULL UNIQUE DEFAULT NEWID(),
CandidateResume VARBINARY(MAX) FILESTREAM NULL
正如你看到的,列CandidateResume包含FILESTREAM关键字,它在数据类型名称之后。
查询文件流列
一旦你建立了SQL Server来支持文件流存储,就可以使用T-SQL语句来查询并修改数据。例如,以下的插入语向CandidateResume列中添加二进制数据。
VALUES (CAST(
'Resume test data' AS VARBINARY(MAX)))
然后你可以获取CandidateResume列返回的数据,就好像你从任何其它列获取数据一样。
FROM Candidate
WHERE CandidateId = 1
此SELECT语句返回以下二进制数据集:0x526573756D6520746573742064617461 你也可以轻松地通过替换值来更新数据:
SET CandidateResume =
CAST( 'New resume test data' AS VARBINARY(MAX))
WHERE CandidateId = 1
注意,我传递进去的是一个二进制值。如果你重新执行上边的SELECT语句,你现在会获以下结果:
0x4E657720726573756D6520746573742064617461
正如你在前边的例子中看到的,使用T-SQL语句来访问列CandidateResume的数据是一个便捷的过程。然而,很显然,我插入并更新的测试数据要比你在一般情况下存储在FILESTREAM列中的数据要小很多。实际上,你通常会希望使用Win32文件流来访问数据。
为了支持Win32文件流,SQL Server 2008提供函数和API,可使得从你的应用程序访问。尽管关于Win32文件流不是本篇文章讨论的范围之内,但了解SQL Server2008中文件流功能轻松地支持从应用程序高效数据访问是很重要的。
获得更多关于文件流数据的Win32流细节信息,请参考SQL Server 2008在线图书中的主题:通过使用Win32来管理文件流数据。你通常也可以在主题文件流存储的设计与实现中获得更多关于文件流存储的细节信息。同时,你目前应该已经有了当你在SQL Server实例中建立文件流存储并定义支持文件流存储的列时所需要的相关细节信息。