FILESTREAM 將 VARBINARY(MAX) 二進制大對象(BLOB)存儲在文件系統中,兼顧資料庫事務一致性與文件流式訪問性能,適用於文檔、圖片、視頻等非結構化數據。
CREATE DATABASE Archive
ON
PRIMARY (
NAME = Arch1,
FILENAME = 'C:\Data\ArchDat1.mdf'
),
FILEGROUP FileStreamGroup1 CONTAINS FILESTREAM (
NAME = Arch3,
FILENAME = 'C:\Data\FileStream1' -- 這是一個「目錄」,非文件
)
LOG ON (
NAME = ArchLog1,
FILENAME = 'C:\Data\ArchLog1.ldf'
);
GO
| 子句 | 說明 |
|---|---|
FILEGROUP ... CONTAINS FILESTREAM | 聲明此文件組存儲 FILESTREAM 數據,必須至少一個。 |
FILENAME = 'C:\Data\FileStream1' | 指向目錄路徑。C:\Data 必須存在,FileStream1 目錄不能預先存在。 |
執行成功後,C:\Data\FileStream1 目錄下將自動生成:
filestream.hdr:容器頭文件,嚴禁刪除/修改。$FSLOG:FILESTREAM 日志子目錄。USE Archive;
GO
CREATE TABLE dbo.Documents (
DocId UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL UNIQUE DEFAULT NEWID(), -- 必須有 ROWGUIDCOL
FileName NVARCHAR(255) NOT NULL,
FileData VARBINARY(MAX) FILESTREAM NULL, -- 關鍵:FILESTREAM 屬性
UploadTime DATETIME2 DEFAULT SYSUTCDATETIME()
)
FILESTREAM_ON FileStreamGroup1; -- 指定 FILESTREAM 文件組
GO
INSERT INTO dbo.Documents (FileName, FileData)
SELECT N'Report.pdf', CAST(BulkColumn AS VARBINARY(MAX))
FROM OPENROWSET(BULK 'C:\Temp\Report.pdf', SINGLE_BLOB) AS F;
-- 1. 獲取事務上下文路徑
DECLARE @Path NVARCHAR(MAX);
SELECT @Path = FileData.PathName() FROM dbo.Documents WHERE DocId = '...';
DECLARE @Token VARBINARY(MAX);
SELECT @Token = GET_FILESTREAM_TRANSACTION_CONTEXT();
-- 2. 應用層 (C#/PowerShell) 使用 @Path + @Token 打開文件流讀寫
-- SqlFileStream fs = new SqlFileStream(path, token, FileAccess.ReadWrite);
ALTER DATABASE Archive
ADD FILEGROUP FSGroup2 CONTAINS FILESTREAM;
ALTER DATABASE Archive
ADD FILE (
NAME = Arch4,
FILENAME = 'C:\Data\FileStream2'
)
TO FILEGROUP FSGroup2;
GO
FILESTREAM_ON 文件組可單獨備份。FILESTREAM 列不能加密(TDE 加密整個數據庫除外)、不支援 FILESTREAM 列上的 FILESTREAM 索引(僅支援全文索引)。