如何使用 SQL Server FILESTREAM 存储非结构化数据?这篇文章告诉你!
作者 |?ALEN ?BRI?
譯者 | 火火醬,責編 | Carol
封圖 |?CSDN 付費下載于視覺中國?
? ?
在本文中,我將解釋如何使用SQL Server FILESTREAM來存儲非結構化數據。同時,還會介紹FILESTREAM的優缺點。
在SQL Server的早期版本中,非結構化數據的存儲在維持結構化和非結構化數據間一致性、管理備份/還原過程、性能問題、可擴展性等方面提出了許多挑戰。在SQL Server 2008之前的MSSQL早期版本中,存在各種用于存儲非結構化數據的機制。這些信息通常被以文件的形式存儲在共享文件夾中,其訪問權限被授予了某些用戶。
這些文件的UNC路徑通常作為表(varchar (n))中的一列存儲于數據庫中,以便應用程序邏輯可以訪問特定的文件。但文件的安全性、管理其訪問權并對其進行維護方面存在一定問題。
后來的二進制大對象(Binary Large Objects,BLOB)概念在一定程度上有助于存儲非結構化數據。這個概念的主要優點是數據庫中的集成管理和事務一致性。在這種情況下,安全問題(以前的文件解決方案)得到了解決。但仍存在一些問題,即2GB的限制以及日志文件過載。
為了解決這些問題,SQL Server 2008首次引入了名為FILESTREAM的增強功能。
它不是VARBINARY (MAX)這樣的數據類型,而是通過VARBINARY列設置的attribute/property,表明數據應該被直接存儲在文件系統上。這些數據仍然是系統的組成部分,并保持事務一致性。
以下是FILESTREAM的一些特征:
二進制數據作為單獨的文件存儲在數據庫之外。
可以通過WIN32 API對這些單獨的文件進行操作。
T-SQL語句適用。
通過FILESTREAM存儲在文件系統中的對象已經取消了VARBINARY (MAX)列的2GB文件大小限制。
FILESTREAM還可以被用在壓縮文件、磁盤、卷中。
要使用FILESTREAM,必須將其激活。FILESTREAM可在兩個級別上啟用。第一級是SQL Server級別。該級別在安裝SQL Server時被啟用。如果沒這樣做的話,可以選中SQL Server FILESTREAM選項卡上的復選框,通過SQL Server 配置管理器來啟用(圖1)。? ? ? ?
??圖1. 使用SQL Server 配置管理器在SQL Server級別啟用FILESTREAM
啟用FILESTREAM的第二個級別是SQL Server Instance(實例)級別。通過執行腳本1中提供的T-SQL腳本來實現。
EXEC?sp_configure?filestream_access_level,?2 RECONFIGURE?
腳本1:在Server Instance 級別啟用FILESTREAM
表 1 列出了filestream_access_level的可能值。
值 | 描述 |
0 | 禁用FILESTREAM 對此實例的支持. |
1 | 啟用FILESTREAM 進行Transact-SQL 訪問. |
2 | 啟用FILESTREAM 進行Transact-SQL 和Win32 流訪問. |
表1. filestream_access_level的可能值
下一步是創建一個數據庫,可以在其中創建將使用FILESTREAM的表。腳本2給出了一個T-SQL腳本示例,該腳本能夠創建可以使用FILESTREAM的數據庫。
CREATE?DATABASE?Test_FILESTREAM ON PRIMARY( NAME=Test_FILESTREAM_Prmary, FILENAME='d:\sqlbaza2019\mssql\data\FILESTREAM\Test_FILESTREAM.mdf'), FILEGROUP?FileStreamGroup?CONTAINS?FILESTREAM( NAME=Test_FILESTREAM_FM, FILENAME='d:\sqlbaza2019\mssql\data\FILESTREAM\Test_FILESTREAM_FM') LOG?ON?( NAME=Test_FILESTREAM_Log, FILENAME='d:\sqlbaza2019\mssql\data\FILESTREAM\Test_FILESTREAM.log')腳本2:創建可以使用FILESTREAM的數據庫的示例
在文件系統上執行腳本2將創建一個$ FSLOG文件夾和文件filestream.hdr。該filestream.hdr文件是FILESTREAM容器的頭文件。
下一步要創建一個具有列VARBINARY (MAX)和FILESTREAM屬性(腳本3)的表。
USE?Test_FILESTREAM CREATE?TABLE?[dbo].[Fajlovi] ( ID?UNIQUEIDENTIFIER?NOT?NULL?ROWGUIDCOL?PRIMARY?KEY, Fajl?VARBINARY(MAX)?FILESTREAM?DEFAULT?NULL )腳本3. 使用VARBINARY (MAX) FILESTREAM 列創建表
仍然需要將記錄插入到新創建的表中(腳本4)。
INSERT?INTO?Fajlovi VALUES?(newid(),?cast('My?test?FIESTREAM-a'?as?varbinary(max))) ?腳本4.使用 VARBINARY (MAX) FILESTREAM 列將記錄插入到表中
用腳本4插入記錄還將在文件系統上創建一個新文件夾。
可以通過執行腳本5從具有VARBINARY (MAX) FILESTREAM列的表中獲取記錄。
select?*?from?[Test_FILESTREAM].[dbo].[Fajlovi]?腳本5. 使用VARBINARY (MAX) FILESTREAM 列從表中查看記錄
執行腳本5的結果如圖2所示。
? ? ? ?? ? ?
圖2. 具有VARBINARY (MAX) FILESTREAM列的表中的紀錄
FILESTREAM列中的每個單元格都是一個與其關聯的文件系統上的文件路徑。要想讀取路徑的話,需要在T-SQL語句中使用varbinary (max)列的PathName屬性。腳本6提供了如何讀取varbinary (max)列文件路徑的示例。
DECLARE?@filePath?varchar(max) SELECT?@filePath?=?Fajl.PathName() FROM?dbo.Fajlovi WHERE?ID?=?'F9A149D0-F5F0-4FC5-9F59-1D27E4D10C1D' PRINT?@filepath?
腳本6. 讀取文件系統上的FILESTREAM 文件路徑的示例
可以使用T-SQL處理FILESTREAM數據,但這是一個更自然的MS Visual Studio環境。通過System.Data.SqlTypes.SqlFileStream 類,可以在應用程序邏輯中使用FILESTREAM功能。為了保持數據的一致性,每個SQL FILESTREAM操作都必須是事務的一部分。MARS(多個活動結果集Multiple Active Result Sets)連接具有批處理事務的特殊規則,而T-SQL BEGIN TRANSACTION語句違反了這些規則。為了避免這個問題,應用程序客戶端應該使用合適的事務管理API來表示類System.Data.SqlClient.SqlTransaction。
為了允許事務訪問FILESTREAM數據文件系統,需要使用T-SQL函數GET FILESTREAM TRASACTION CONTEXT()來提供表示特定會話(C # code 1)中當前事務的令牌。
SqlConnection?sqlConnection?=?new?SqlConnection( "Integrated?Security=true;server=(local)"); SqlCommand?sqlCommand?=?new?SqlCommand(); sqlCommand.Connection?=?sqlConnection; SqlTransaction?transaction?=?sqlConnection.BeginTransaction("mainTranaction"); sqlCommand.Transaction?=?transaction; sqlCommand.CommandText?= "SELECT?GET_FILESTREAM_TRANSACTION_CONTEXT()"; Object?obj?=?sqlCommand.ExecuteScalar(); byte[]?txContext?=?(byte[])obj;?
C # code 1. 使用 GET_FILESTREAM_TRASACTION_CONTEXT () 函數
這樣一來,事務已啟動,但還沒有提交或回滾。使用FILESTREAM數據的多個操作可以在一個事務中執行。在C # code 2中給出了使用Win32 API的數據輸入代碼的示例,其中sqlFileStream對象最初是基于System.Data.SqlType類創建的。
SqlFileStream?sqlFileStream?=?new?SqlFileStream(filePath,?txContext,?FileAccess.ReadWrite); byte[]?buffer?=?new?byte[512]; int?numBytes?=?0; //Write?string,?"FILESTREAM?test?data"?in?FILESTREAM. string?someData?=?"FILESTREAM?test?data"; Encoding?unicode?=?Encoding.GetEncoding(0); sqlFileStream.Write(unicode.GetBytes(someData.ToCharArray()),0,someData.Length);?
C # code 2. 在FILESTREAM中輸入數據的示例代碼
C # code 3中給出了使用Win32 API讀取FILESTREAM數據的示例代碼。這里使用的是在c# code 1示例開始時創建的同一個sqlFileStream對象。
sqlFileStream.Seek(0L,?SeekOrigin.Begin); numBytes?=?sqlFileStream.Read(buffer,?0,?buffer.Length); string?readData?=?unicode.GetString(buffer); if?(numBytes?!=?0) Console.WriteLine(readData);?
C # code 3. 讀取FILESTREAM數據的示例代碼
在完成FILESTREAM注冊事務(C # code 1)并讀取FILESTREAM數據(C # code 2)之后,sqlFileStream對象(在C # code 1示例的開頭基于System.Data.SqlTypes.SqlFileStream類創建的)必須關閉并提交事務(C # code 4)。sqlCommand對象是在示例C # code1的開頭創建的。
sqlFileStream.Close(); sqlCommand.Transaction.Commit();?
C # code 4. 關閉sqlFileStream對象并提交事務
在圖3中給出了VARBINARY (MAX)和FILESTREAM被用于存儲非結構化數據和使用T-SQL 或Win32訪問數據時數據加載性能的對比圖。
?
圖3.不同大小的 BLOB的負載性能
還應該注意,FILESTREAM也被用于其他SQL Server技術中,例如FileTable和In-Memory OLTP。
最后
與其他技術一樣,FILESTREAM也有其優缺點。
優點:
作為FILESTREAM的一部分創建的文件由SQL Server本身在其自己的文件組中進行管理,在這些文件組中可以與其他SQL Server數據一起進行備份和還原。
讀寫這些文件是數據庫事務的一部分。
可以存儲非常大的BLOB對象。
缺點:
FILESTREAM數據只能被存儲在本地磁盤卷中。
數據庫快照中不支持。
數據庫鏡像不支持。
不支持透明數據加密。
不能與表值參數一起使用。
原文鏈接:https://www.experfy.com/blog/how-to-use-sql-server-filestream-to-store-unstructured-data
本文為 CSDN 翻譯,轉載請注明出處。
?
推薦閱讀
對不起,我把APP也給爬了
震驚!阿里的程序員竟被一個簡單的 SQL 查詢難住了!
巧用 Trie 樹,實現搜索引擎關鍵詞提示功能
第一個"國產"Apache 頂級項目 Kylin,了解一下!| 原力計劃
華為 5G、阿里檢測病毒算法、騰訊 AI 一分鐘診斷,國內抗疫科技大閱兵!
超級賬本Hyperledger Fabric中的Protobuf到底是什么?
真香,朕在看了!
總結
以上是生活随笔為你收集整理的如何使用 SQL Server FILESTREAM 存储非结构化数据?这篇文章告诉你!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Wi-Fi 6到底有什么特别?
- 下一篇: 广东制造按下加速键 千家中小企业上阿里