介绍
Microsoft SQL Server支持一种特殊的数据类型,叫做“文件流”,它使得数据交换和存储变得更加容易。这个数据类型允许在数据库中存储任何类型的文件,而不是简单地将文件路径和名称存储在一个字段中。
在此之前,开发人员可能需要使用BLOB(二进制大对象)或将文件存储在磁盘上,并将对应的路径存储在数据库中。但这种方法存在一些缺点,例如当需要对文件进行搜索、排序或筛选时,可能会变得非常困难和耗时。此外,BLOB需要很长时间来存储和检索,而将文件存储在磁盘上可能会导致数据丢失或访问不当。
本文将集中讨论如何使用MSSQL文件流实现数据交换
开启文件流
在我们开始之前,请确保你的SQL Server实例启用了文件流功能。如果你已经安装和启用了SQL Server实例,但是尚未启用文件流,则可以按照以下步骤来启用它:
启用文件流步骤
在“SQL Server Configuration Manager”中,选择“SQL Server Services”.
右键单击你的数据库实例,并选择“roperties”.
在“roperties”对话框中,选择“FILESTREAM”标签。
选中“Enable FILESTREAM for Transact-SQL access”和“Enable FILESTREAM for file I/O access”选项,并指定一个名称为“FILESTREAM Access Level”的实例级别设置。
记下你在上一步中创建的值。稍后我们需要在创建数据库时使用。
点击“Apply”和“OK”保存更改并关闭对话框。
重新启动数据库实例。
创建文件流数据库
一旦你的SQL Server实例启用了文件流功能,你可以创建一个包含文件流的数据库。在创建数据库时,你需要指定一些有关文件流的设置,这些设置涉及到文件流的路径、文件命名规则和可访问性等问题。
指定文件流的路径
在创建文件流数据库之前,必须确保已经为其设置了文件流的存储路径。文件流的存储路径与一般的数据库路径不同。默认情况下,MSSQL使用操作系统的文件系统(NTFS)来存储文件流数据,而文件流路径必须在NTFS分区上。你可以将文件流存储在本地磁盘或网络共享上,但你必须指定一个UNC路径(而不是本地路径)。UNC格式为:\\[server]\[share]\,其中server是文件流存储位置的计算机名称,而share是计算机上共享的文件流存储目录的名称。
为了使文件流路径可用,请在SQL Server Configuration Manager中打开FILESTREAM面板并启用"Allow remote clients to have streaming access to FILESTREAM data"。
以下是如何指定文件流存储路径的示例:
EXEC sp_configure filestream_access_level, 2
RECONFIGURE
CREATE DATABASE TestDatabase ON PRIMARY
(NAME = TestDatabase, FILENAME = 'C:\Data\TestDatabase.mdf'),
FILEGROUP FileStreamGroup1 CONTAINS FILESTREAM
(NAME = FileStream1, FILENAME = '\\ComputerName\Share\Stream1')
LOG ON (NAME = TestDatabase_Log, FILENAME = 'C:\Data\TestDatabase.ldf')
GO
在这个例子中,我们使用CREATE DATABASE语句来创建名为TestDatabase的数据库。注意,“FILESTREAM Access Level”被设置为2(表示允许传统的T-SQL操作和文件I/O访问),同时我们创建了一个名称为FileStreamGroup1的文件组,并将其指定为包含文件流的文件组。这个文件组与主文件组是相对独立的,而且必须使用不同的名称来标识。
在文件组上,我们指定了一个名为FileStream1并且位于\\ComputerName\Share\Stream1UNC路径上的文件流文件(这是一个示例路径,你需要替换计算机名称和共享目录的名称)。你可以指定多个文件流文件,在这个示例中只使用了一个。
最后,我们为数据库指定了一个事务日志文件的名称和位置。
指定文件命名规则
在打开文件流功能的情况下,你需要指定一些有关文件命名的规则。例如,默认情况下,MSSQL Server使用随机生成的GUID来命名文件流文件。你可以选择使用另一种命名模式,例如使用原始文件的名称或某个其他值。在命名文件时,还可以指定文件所需的最小大小(在字节中)和最大大小(在MB中)等属性。
下面是一个指定文件名规则的示例:
CREATE DATABASE TestDB ON PRIMARY
(NAME = TestDBData, FILENAME = 'C:\Data\TestDBData.mdf'),
FILEGROUP FileStreamGroup1 CONTAINS FILESTREAM
( NAME = FileStream1, FILENAME = '\\ComputerName\FileStreamShare\TestDBFileStream1')
LOG ON
(NAME = TestDBLog, FILENAME = 'C:\Data\TestDBLog.ldf')
GO
ALTER DATABASE TestDB
ADD FILEGROUP FileStreamGroup2 CONTAINS FILESTREAM
GO
ALTER DATABASE TestDB
ADD FILE (
NAME = FileStream2,
FILENAME = '\\ComputerName\FileStreamShare\TestDBFileStream2')
TO FILEGROUP FileStreamGroup2
GO
USE TestDB
GO
ALTER TABLE MyTable
ADD MyFile varbinary(max) FILESTREAM
NULL
GO
ALTER TABLE MyTable
ADD CONSTRAINT DF_MyTable_FS DEFAULT
(master.dbo.GetFileGUID()) FOR MyFile
GO
在本例中,我们使用了CREATE DATABASE语句来创建TestDB数据库,使用FILEGROUP子句来定义FileStreamGroup1文件组,并指定名称为FileStream1的文件流文件,并将其存储在\\ComputerName\FileStreamShare\TestDBFileStream1UNC路径上。我们还添加了一个文件组FileStreamGroup2,并将其文件流文件(名称为FileStream2)存储在\\ComputerName\FileStreamShare\TestDBFileStream2路径上。最后,我们创建了一个名为MyTable的表,并在其中添加了一个名为MyFile的VARBINARY(MAX)文件流列。
注意,默认情况下,MSSQL Server使用GUID作为文件名。但是,在这个例子中,我们已经定义了一个使用master.dbo.GetFileGUID()函数来获取GUID的默认值约束。
插入文件到文件流
一旦你的文件流数据库准备好使用,就可以使用INSERT语句将文件存储在其中。在插入文件之前,你必须确保文件流列被正确地定义为VARBINARY(MAX)类型。
下面是一个插入文件的示例:
INSERT INTO MyTable (MyFile, MyFileName)
SELECT * FROM
OPENROWSET(BULK N'C:\Photos\MyPhoto.jpg', SINGLE_BLOB) rs
在本示例中,我们使用INSERT语句向MyTable表中插入一张名为“C:\Photos\MyPhoto.jpg”的JPEG图像。我们使用OPENROWSET函数来将文件的内容读取到内存中,然后向MyTable表中插入行。
检索文件流中的文件
要检索文件流中的文件,可以使用SELECT语句。但是,如果要检索文件流中的大型文件,则需要使用特殊技巧来处理它们。例如,你可以使用SQL Server FILESTREAM提供的.NET Framework NUMovc类型来缓冲文件流数据。
下面是一个从文件流检索文件的示例:
SELECT TOP 1 MyFile.PathName(), MyFile.name, MyFile.GetFileNamespacePath(), *
FROM MyTable
在本例中,我们使用SELECT语句查询MyTable表,并使用TOP 1子句限制结果集中的行数。我们选择了MyFile.PathName()、MyFile.name和MyFile.GetFileNamespacePath()来计算文件流路径和文件名称。我们还使用了*通配符来选择所有列。
总结
使用MSSQL文件流可以使数据交换变得更加简单。如果你正在开发需要处理大型文件的应用程序,那么将文件存储在数据库中可能是一个有用的解决方案。在本文中,我们讨论了如何配置和使用MSSQL文件流,以及如何将文件插入到文件流中。通过使用这些技术,你可以在你的应用程序中快速、轻松地实现数据交换。