FILESTREAM 可讓 SQL Server 型應用程式在檔案系統上儲存非結構化數據,例如檔和影像。 應用程式可以利用檔系統的豐富串流 API 和效能,同時維護非結構化數據與對應結構化數據之間的交易一致性。
FILESTREAM 藉由將大二進位物件 (BLOB) 資料以檔案形式儲存到檔案系統上,整合了 SQL Server 資料庫引擎與 NTFS 檔案系統。 Transact-SQL 語句可以插入、更新、查詢、搜尋及備份 FILESTREAM 數據。 Win32 檔系統介面提供數據的串流存取。
FILESTREAM 會使用NT系統快取來快取檔案數據。 這有助於降低 FILESTREAM 數據可能對 Database Engine 效能產生的任何影響。 未使用 SQL Server 緩衝池;因此,此記憶體可用於查詢處理。
當您安裝或升級 SQL Server 時,不會自動啟用 FILESTREAM。 您必須使用 SQL Server 組態管理員和 SQL Server Management Studio 來啟用 FILESTREAM。 若要使用 FILESTREAM,您必須建立或修改資料庫,以包含特殊類型的檔案群組。 然後,建立或修改數據表,使其包含 varbinary(max) 具有 FILESTREAM 屬性的數據行。 完成這些工作之後,您可以使用 Transact-SQL 和 Win32 來管理 FILESTREAM 數據。
如需安裝和使用 FILESTREAM 的詳細資訊,請參閱 相關工作清單。
使用 FILESTREAM 的時機
在 SQL Server 中,BLOB 可以是標準 varbinary(max) 數據,可將資料儲存在數據表中,或是將數據儲存在文件系統中的 FILESTREAM varbinary(max) 物件。 數據的大小和使用決定您應該使用資料庫記憶體或檔案系統記憶體。 如果下列條件成立,您應該考慮使用 FILESTREAM:
所儲存的物件平均大於 1 MB。
讀取資料的快速存取很重要。
您正在開發使用中介層進行應用程式邏輯的應用程式。
對於較小的物件,將 varbinary(max) BLOB 儲存在資料庫中通常可提供更佳的串流效能。
FILESTREAM 記憶體
FILESTREAM 儲存會實作為 varbinary(max) 欄位,將資料以 BLOB 形式儲存在檔案系統中。 BLOB 的大小只會受限於文件系統的磁碟區大小。 2 GB 檔案大小的標準 varbinary(max) 限制不適用於儲存在檔案系統中的 BLOB。
若要指定資料行應該將資料儲存在檔案系統上,請在數據行上 varbinary(max) 指定 FILESTREAM 屬性。 這會導致 Database Engine 在文件系統上儲存該數據行的所有數據,但不會儲存在資料庫檔案中。
FILESTREAM 數據必須儲存在 FILESTREAM 檔案群組中。 FILESTREAM 檔案群組是一個特殊的檔案群組,其中包含文件系統目錄,而不是檔案本身。 這些檔案系統目錄稱為 數據容器。 數據容器是Database Engine記憶體與文件系統記憶體之間的介面。
當您使用 FILESTREAM 記憶體時,請考慮下列事項:
當數據表包含 FILESTREAM 數據行時,每個數據列都必須有非 Null 唯一的數據列標識碼。
您可以將多個數據容器新增至 FILESTREAM 檔案群組。
FILESTREAM 數據容器無法巢狀化。
當您使用故障轉移叢集時,FILESTREAM 檔案群組必須位於共用磁碟資源上。
FILESTREAM 檔案群組可以在壓縮的磁碟區上。
整合式管理
由於 FILESTREAM 會實作為數據 varbinary(max) 行並直接整合到 Database Engine 中,因此大部分的 SQL Server 管理工具和函式都無法修改 FILESTREAM 數據。 例如,您可以使用所有備份和恢復模式搭配 FILESTREAM 數據,而且 FILESTREAM 數據會以資料庫中的結構化數據進行備份。 如果您不想要將 FILESTREAM 資料與關聯式資料一起備份,您可以使用部分備份來排除 FILESTREAM 檔案群組。
整合式安全性
在 SQL Server 中,FILESTREAM 數據會像其他數據一樣受到保護:藉由授與數據表或數據行層級的許可權。 如果使用者具有數據表中 FILESTREAM 數據行的許可權,用戶可以開啟相關聯的檔案。
備註
FILESTREAM 數據不支援加密。
只有執行 SQL Server 服務帳戶的帳戶會授與 FILESTREAM 容器的 NTFS 許可權。 我們建議沒有其他帳戶獲授與數據容器的許可權。
備註
SQL 登入不適用於 FILESTREAM 容器。 只有 NTFS 驗證可與 FILESTREAM 容器搭配使用。
使用 Transact-SQL 和文件系統串流存取來存取 BLOB 數據
將資料儲存在 FILESTREAM 數據行之後,您可以使用 Transact-SQL 交易或使用 Win32 API 來存取檔案。
Transact-SQL 存取
藉由使用 Transact-SQL,您可以插入、更新和刪除 FILESTREAM 數據:
您可以使用插入操作,將 FILESTREAM 欄位預先填入 Null 值、空值或相對簡短的內嵌資料。 不過,大量數據會更有效率地串流至使用 Win32 介面的檔案。
當您更新 FILESTREAM 欄位時,您會修改檔案系統中的基礎 BLOB 資料。 當 FILESTREAM 欄位設定為 NULL 時,與此欄位有關聯的 BLOB 資料會遭到刪除。 您無法使用 Transact-SQL 區塊式更新,實作為 UPDATE**.**Write(), 來執行數據的部分更新。
當您刪除資料列或刪除或截斷包含 FILESTREAM 資料的資料表時,您會刪除檔案系統中的底層 BLOB 資料。
檔系統串流存取
Win32 串流支援可在 SQL Server 交易的內容中運作。 在交易中,您可以使用 FILESTREAM 函式來取得檔案的邏輯 UNC 檔案系統路徑。 接著,您可以使用 OpenSqlFilestream API 來取得檔案控制碼。 然後,Win32 檔案串流介面可以使用此句柄,例如 ReadFile() 和 WriteFile(),透過文件系統存取和更新檔案。
因為檔案作業是交易式的,所以您無法透過文件系統刪除或重新命名 FILESTREAM 檔案。
語句模型
FILESTREAM 檔案系統透過開啟與關閉檔案來模擬 Transact-SQL 語句的存取模型。 語句會在開啟檔句柄時啟動,並在句柄關閉時結束。 例如,當寫入控制代碼關閉時,數據表上註冊的任何可能的 AFTER 觸發程序都會觸發,如同 UPDATE 語句完成一樣。
記憶體命名空間
在 FILESTREAM 中,Database Engine 會控制 BLOB 實體文件系統命名空間。 新的內部函數 PathName 提供 BLOB 的邏輯 UNC 路徑,其對應至數據表中的每個 FILESTREAM 單元格。 應用程式會使用此邏輯路徑來取得 Win32 句柄,並使用一般 Win32 檔案系統介面對 BLOB 數據進行作。 如果 FILESTREAM 資料行的值為 NULL,此函式會傳回 NULL。
交易文件系統存取
新的內部函數 GET_FILESTREAM_TRANSACTION_CONTEXT() 提供代表目前交易的令牌,該交易是與這個會話相關聯的。 交易必須已啟動,但尚未中止或認可。 藉由取得令牌,應用程式會將 FILESTREAM 檔案系統串流作業與已啟動的交易系結。 函式在沒有明確啟動交易的情況下會傳回 NULL。
所有檔案控制項都必須在交易提交或中止之前關閉。 如果句柄在交易範圍之外保持開啟狀態,則針對句柄的其他讀取會導致失敗;針對句柄的其他寫入將會成功,但實際數據不會寫入磁碟。 同樣地,如果 Database Engine 的資料庫或實例關閉,則所有開啟的句柄都會失效。
交易式持久性
當交易提交時,透過 FILESTREAM,資料庫引擎能確保從檔案系統串流存取被修改的 FILESTREAM BLOB 資料的交易持久性。
隔離語意
隔離語意是由 Database Engine 交易隔離等級所控管。 讀取提交隔離等級可用於 Transact-SQL 和文件系統存取。 支援重複讀取操作,以及可序列化和快照隔離。 不支援髒讀。
檔案系統存取的開啟操作不會等待任何鎖定。 相反地,如果開啟作業因為交易隔離而無法存取數據,則會立即失敗。 如果開啟作業因隔離違規而無法繼續,則會發生 ERROR_SHARING_VIOLATION,導致串流 API 呼叫失敗。
為了允許進行部分更新,應用程式可以發出設備檔案系統控制命令(FSCTL_SQL_FILESTREAM_FETCH_OLD_CONTENT),以將舊內容擷取到該打開的句柄所指向的檔案中。 這會觸發伺服器端舊的內容複製。 為了提升應用程式效能,以及避免在處理非常大的檔案時發生潛在的逾時,我們建議您使用異步 I/O。
如果在寫入句柄之後發出 FSCTL,最後一次寫入的操作將會保持,其它所有先前對句柄的寫入將會丟失。
檔系統 API 和支援的隔離等級
當文件系統 API 因為隔離違規而無法開啟檔案時,會傳回ERROR_SHARING_VIOLATION例外狀況。 當兩筆交易嘗試存取相同的檔案時,就會發生此隔離違規。 存取作業的結果取決於開啟檔案的模式,以及執行交易的 SQL Server 版本。 下表概述存取相同檔案之兩筆交易的可能結果。
| 交易 1 | 交易 2 | SQL Server 2008 的結果 | SQL Server 2008 R2 和更新版本的結果 |
|---|---|---|---|
| 開啟以供讀取。 | 開啟以供讀取。 | 兩者都成功。 | 兩者都成功。 |
| 開啟以供讀取。 | 開啟以進行寫入。 | 兩者都成功。 交易 2 下的寫入作業不會影響在交易 1 中執行的讀取作業。 | 兩者都成功。 交易 2 下的寫入作業不會影響在交易 1 中執行的讀取作業。 |
| 開啟以進行寫入。 | 開啟以供讀取。 | 交易 2 開啟失敗,出現 ERROR_SHARING_VIOLATION 例外狀況。 | 兩者都成功。 |
| 開啟以進行寫入。 | 開啟以進行寫入。 | 針對交易 2 開啟失敗,並出現ERROR_SHARING_VIOLATION例外狀況。 | 交易 2 的開啟失敗,並出現 ERROR_SHARING_VIOLATION 例外。 |
| 開啟以供讀取。 | 開啟以供 SELECT 使用。 | 兩者都成功。 | 兩者都成功。 |
| 開啟以供讀取。 | 開啟 UPDATE 或 DELETE。 | 兩者都成功。 交易 2 下的寫入作業不會影響在交易 1 中執行的讀取作業。 | 兩者都成功。 交易 2 下的寫入作業不會影響在交易 1 中執行的讀取作業。 |
| 開啟以進行寫入。 | 可供 SELECT 使用。 | 交易 2 會封鎖直到交易 1 認可或結束交易,或交易鎖定逾時為止。 | 兩者都成功。 |
| 開啟以進行寫入。 | 開啟 UPDATE 或 DELETE。 | 交易 2 會封鎖直到交易 1 認可或結束交易,或交易鎖定逾時為止。 | 交易 2 會封鎖直到交易 1 認可或結束交易,或交易鎖定逾時為止。 |
| 為 SELECT 開放 | 開啟以供讀取。 | 兩者都成功。 | 兩者都成功。 |
| 針對 SELECT 開啟。 | 開啟以進行寫入。 | 兩者都成功。 交易 2 下的寫入作業不會影響交易 1。 | 兩者都成功。 交易 2 下的寫入作業不會影響交易 1。 |
| 開啟更新或刪除。 | 開啟以供讀取。 | 交易 2 上的開啟作業失敗,並出現ERROR_SHARING_VIOLATION例外狀況。 | 兩者都成功。 |
| 開啟以進行更新或刪除。 | 開啟以進行寫入。 | 交易 2 上的開啟作業失敗,並出現ERROR_SHARING_VIOLATION例外狀況。 | 交易 2 上的開啟作業失敗,並出現 ERROR_SHARING_VIOLATION 例外狀況。 |
| 針對具有可重複讀取的SELECT開啟。 | 開啟以供讀取。 | 兩者都成功。 | 兩者都成功。 |
| 針對 SELECT 開啟可重複讀取模式。 | 開啟以進行寫入。 | 交易 2 上的開啟作業失敗,並出現ERROR_SHARING_VIOLATION例外狀況。 | 交易 2 上的開啟作業失敗,並出現ERROR_SHARING_VIOLATION例外狀況。 |
Write-Through 從遠端用戶端
透過伺服器消息塊 (SMB) 通訊協定啟用 FILESTREAM 數據的遠端檔案系統存取。 如果客戶端是遠端的,用戶端不會快取任何寫入作業。 寫入作業一律會傳送至伺服器。 數據可以在伺服器端快取。 建議在遠端用戶端上執行的應用程式合併小型寫入作業,以使用較大的數據大小來減少寫入作業。
不支援使用 FILESTREAM 句柄建立記憶體對應檢視表(記憶體對應 I/O)。 如果記憶體對應用於 FILESTREAM 數據,Database Engine 無法保證數據的一致性和持久性或資料庫的完整性。
相關工作
啟用和設定 FILESTREAM
建立 FILESTREAM-Enabled 資料庫
建立用來儲存 FILESTREAM 數據的數據表
使用 Transact-SQL 存取 FILESTREAM 數據
建立 FILESTREAM 資料的用戶端應用程式
使用 OpenSqlFilestream 存取 FILESTREAM 資料
對 FILESTREAM 數據進行部分更新
避免與 FILESTREAM 應用程式中的資料庫作業發生衝突
移動 FILESTREAM-Enabled 資料庫
在故障轉移叢集上設定 FILESTREAM
設定 FILESTREAM 存取的防火牆