FILESTREAM を使用すると、SQL Server ベースのアプリケーションで非構造化データ (ドキュメントやイメージなど) をファイル システムに格納できます。 これにより、ファイル システムの豊富なストリーミング API と高いパフォーマンスをアプリケーションで活用できるほか、非構造化データとそれに対応する構造化データの間でトランザクションの一貫性も維持されます。
FILESTREAM は、バイナリ ラージ オブジェクト (BLOB) データvarbinary(max)ファイル システム上のファイルとして格納することで、SQL Server データベース エンジンを NTFS ファイル システムと統合します。 Transact-SQL ステートメントでは、FILESTREAM データの挿入、更新、クエリ、検索、バックアップを行うことができます。 Win32 ファイル システム インターフェイスによるデータへのストリーミング アクセスが可能になります。
FILESTREAM では、NT システム キャッシュを使用してファイル データをキャッシュします。 これにより、FILESTREAM データがパフォーマンスに及ぼす影響データベース エンジン軽減できます。 SQL Server バッファー プールは使用されないため、このメモリはクエリ処理に使用できます。
SQL Serverをインストールまたはアップグレードしても、FILESTREAM は自動的に有効になりません。 FILESTREAM は、SQL Server 構成マネージャーと SQL Server Management Studio を使用して有効にする必要があります。 FILESTREAM を使用するには、特殊なファイル グループを格納するためにデータベースを作成または変更する必要があります。 次に、FILESTREAM 属性を持つ varbinary(max) 列が含まれるようにテーブルを作成または変更します。 これらの手順を完了すると、Transact-SQL および Win32 を使用して FILESTREAM データを管理できるようになります。
FILESTREAM のインストールと使用の詳細については、 関連タスクの一覧を参照してください。
FILESTREAM を使用する場合
SQL Serverでは、BLOB は、データをテーブルに格納する標準のvarbinary(max) データ、またはファイル システムにデータを格納する FILESTREAM varbinary(max) オブジェクトにすることができます。 データベース ストレージとファイル システム ストレージのどちらを使用するかは、データのサイズと用途によって決まります。 次の条件が true の場合は、FILESTREAM を使用することを検討する必要があります。
格納するオブジェクトの平均的なサイズが 1 MB より大きい。
高速な読み取りアクセスが重要とされる。
あなたは、アプリケーション ロジックに中間層を使用するアプリケーションを開発しています。
小さいオブジェクトの場合、多くの場合、 varbinary(max) BLOB をデータベースに格納すると、ストリーミング パフォーマンスが向上します。
FILESTREAM ストレージ
FILESTREAM ストレージは、データが BLOB としてファイル システムに格納される varbinary(max) 列として実装されます。 BLOB のサイズはファイル システムのボリューム サイズによってのみ制限されます。 ファイル サイズが 2 GB の標準的な varbinary(max) 制限は、ファイル システムに格納されている BLOB には適用されません。
列がファイル システムにデータを格納するように指定するには、 varbinary(max) 列に FILESTREAM 属性を指定します。 これにより、データベース エンジンは、その列のすべてのデータをファイル システムに格納しますが、データベース ファイルには格納しません。
FILESTREAM データは FILESTREAM ファイル グループに格納する必要があります。 FILESTREAM ファイル グループは特殊なファイル グループで、ファイルそのものではなくファイル システム ディレクトリが含まれます。 これらのファイル システム ディレクトリは、 データ コンテナーと呼ばれます。 データ コンテナーは、データベース エンジン ストレージとファイル システム ストレージの間のインターフェイスです。
FILESTREAM ストレージを使用する際は、以下の点を考慮してください。
テーブルに FILESTREAM 列が含まれている場合、各行には NULL 以外の一意の行 ID が必要です。
FILESTREAM ファイル グループには、複数のデータ コンテナーを追加できます。
FILESTREAM データ コンテナーを入れ子にすることはできません。
フェールオーバー クラスタリングを使用する場合、FILESTREAM ファイル グループは共有ディスク リソース上に存在する必要があります。
FILESTREAM ファイル グループは、圧縮されたボリューム上にあってもかまいません。
管理の統合
FILESTREAM はvarbinary(max)列として実装され、データベース エンジンに直接統合されるため、ほとんどのSQL Server管理ツールと関数は FILESTREAM データを変更せずに動作します。 たとえば、すべてのバックアップ モデルと復旧モデルを FILESTREAM データで使用できるため、FILESTREAM データをデータベースの構造化データと共にバックアップできます。 FILESTREAM データをリレーショナル データと共にバックアップしない場合は、部分バックアップを使用して FILESTREAM ファイル グループを除外できます。
統合セキュリティ
SQL Server の FILESTREAM データは、その他のデータと同じように、テーブルまたは列のレベルで権限を与えることによってセキュリティで保護されます。 テーブルの FILESTREAM 列に対する権限を持つユーザーは、関連付けられているファイルを開くことができます。
Note
FILESTREAM データでは暗号化はサポートされていません。
SQL Server サービス アカウントが実行されているアカウントにのみ、FILESTREAM コンテナーへの NTFS アクセス許可が付与されます。 データ コンテナーに対するアクセス許可を他のアカウントに付与することはお勧めしません。
Note
SQL ログインは、FILESTREAM コンテナーで使用できません。 FILESTREAM コンテナーでは NTFS 認証のみが機能します。
Transact-SQL およびファイル システム ストリーミング アクセスを使用した BLOB データへのアクセス
FILESTREAM 列にデータを格納した後、それらのファイルにアクセスするには、Transact-SQL トランザクションか Win32 API を使用します。
Transact-SQL アクセス
Transact-SQL を使用して、FILESTREAM データの挿入、更新、および削除を行うことができます。
挿入操作を使用すると、null 値、空の値、または比較的短いインライン データを FILESTREAM フィールドに事前設定することができます。 ただし、大量のデータをファイルにストリーミングする場合は、Win32 インターフェイスを使用する方が効率的です。
FILESTREAM フィールドを更新すると、その基となるファイル システムの BLOB データが変更されます。 FILESTREAM フィールドを NULL に設定すると、フィールドに関連付けられている BLOB データが削除されます。 UPDATE****Write() として実装された Transact-SQL チャンク更新を使用して、データの部分的な更新を実行することはできません。
FILESTREAM データを含む行を削除したり、FILESTREAM データを含むテーブルを削除したり切り捨てたりすると、その基となるファイル システムの BLOB データが削除されます。
ファイル システム ストリーミング アクセス
Win32 のストリーミング サポートを SQL Server トランザクションのコンテキストで使用できます。 トランザクション内で、まず、FILESTREAM 関数を使用してファイルの論理 UNC ファイル システム パスを取得します。 次に、OpenSqlFilestream API を使用してファイル ハンドルを取得します。 そのハンドルを Win32 ファイル ストリーミング インターフェイス (ReadFile() や WriteFile() など) で使用することにより、ファイル システム経由でファイルにアクセスしてファイルを更新できます。
ファイル操作はトランザクションであるため、ファイル システムを介して FILESTREAM ファイルを削除または名前変更することはできません。
ステートメント モデル
FILESTREAM のファイル システム アクセスは、ファイルのオープンとクローズを使用して Transact-SQL ステートメントを実現しています。 ファイル ハンドルを開くとステートメントが開始され、ハンドルを閉じると終了します。 たとえば、書き込みハンドルが閉じられると、テーブルに登録されている AFTER トリガーが、 UPDATE ステートメントが完了したかのように起動します。
Storage 名前空間
FILESTREAM では、データベース エンジンが BLOB の物理ファイル システムの名前空間を制御します。 新しい組み込み関数の PathNameを使用すると、テーブルの各 FILESTREAM セルに対応する BLOB の論理 UNC パスを取得できます。 アプリケーションでは、この論理パスを使用して Win32 ハンドルを取得し、標準の Win32 ファイル システム インターフェイスを使用して BLOB データを操作します。 FILESTREAM 列の値が NULL の場合、この関数は NULL を返します。
Transacted File System Access
新しい組み込み関数 GET_FILESTREAM_TRANSACTION_CONTEXT()は、セッションが関連付けられている現在のトランザクションを表すトークンを提供します。 このトランザクションは、既に開始され、まだ中止もコミットもされていないトランザクションである必要があります。 アプリケーションでは、トークンを取得することにより、FILESTREAM のファイル システム ストリーミング操作を、既に開始されているトランザクションにバインドできます。 明示的に開始されたトランザクションがない場合、この関数は NULL を返します。
トランザクションをコミットしたり中止したりする前にすべてのファイル ハンドルを閉じる必要があります。 トランザクション スコープを超えてハンドルを開いたままにすると、ハンドルに対する追加の読み取りによってエラーが発生します。ハンドルに対する追加の書き込みが成功しますが、実際のデータはディスクに書き込まれません。 同様に、データベース エンジンのデータベースやインスタンスがシャットダウンすると、開いているハンドルはすべて無効になります。
トランザクションの持続性
FILESTREAM では、トランザクションのコミット時に、ファイル システム ストリーミング アクセスから変更された FILESTREAM BLOB データのトランザクションの持続性がデータベース エンジンによって確保されます。
分離セマンティクス
分離のセマンティクスは、データベース エンジンのトランザクション分離レベルに従います。 Transact-SQL およびファイル システム アクセスでは、Read Committed 分離レベルがサポートされます。 反復可能な読み取り操作、およびシリアル化可能な分離とスナップショットの分離もサポートされています。 ダーティ リードはサポートされていません。
ファイル システム アクセスのオープン操作は、ロックを待機しません。 代わりに、トランザクションの分離のためにデータにアクセスできない場合、開いている操作はすぐに失敗します。 分離違反のために開いている操作を続行できない場合、ストリーミング API 呼び出しは ERROR_SHARING_VIOLATION で失敗します。
アプリケーションでは、部分更新を実行できるようにするために、デバイス FS 制御 (FSCTL_SQL_FILESTREAM_FETCH_OLD_CONTENT) を発行して、開いているハンドルが参照しているファイルに古い内容をフェッチすることができます。 これにより、サーバー側の古いコンテンツ コピーがトリガーされます。 アプリケーションのパフォーマンスを向上させ、非常に大きなファイルを操作しているときにタイムアウトが発生しないようにするには、非同期 I/O を使用することをお勧めします。
ハンドルへの書き込みが行われた後に FSCTL を発行すると、最後の書き込み操作は維持され、それより前の書き込みは失われます。
ファイル システム API とサポートされている分離レベル
分離違反のためにファイル システム API がファイルを開くことができない場合は、ERROR_SHARING_VIOLATION例外が返されます。 この分離違反は、2 つのトランザクションが同じファイルにアクセスしようとしたときに発生します。 アクセス操作の結果は、ファイルが開かれたモードと、トランザクションが実行されている SQL Server のバージョンに依存します。 次の表は、同じファイルにアクセスしている 2 つのトランザクションの結果の概要を示しています。
| トランザクション 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 には影響しません。 |
| UPDATEまたはDELETE用に開きます。 | 読み取り用に開く。 | トランザクション 2 の開く操作は、ERROR_SHARING_VIOLATION 例外で失敗します。 | どちらも成功します。 |
| UPDATEまたはDELETE用に開きます。 | 書き込み用に開く。 | トランザクション 2 の開く操作は、ERROR_SHARING_VIOLATION 例外で失敗します。 | トランザクション 2 の開く操作は、ERROR_SHARING_VIOLATION 例外で失敗します。 |
| 反復可能な読み取りを使用して SELECT 用に開きます。 | 読み取り用に開く。 | どちらも成功します。 | どちらも成功します。 |
| 反復可能な読み取りを使用して SELECT 用に開きます。 | 書き込み用に開く。 | トランザクション 2 の開く操作は、ERROR_SHARING_VIOLATION 例外で失敗します。 | トランザクション 2 の開く操作は、ERROR_SHARING_VIOLATION 例外で失敗します。 |
リモート クライアントからのWrite-Through
FILESTREAM データへのリモート ファイル システム アクセスは、サーバー メッセージ ブロック (SMB) プロトコルによって実現されます。 クライアントがリモート クライアントの場合は、書き込み操作がクライアント側でキャッシュされず、 常にサーバーに送信されます。 サーバー側でデータをキャッシュできます。 リモート クライアントで実行されているアプリケーションでは、小さな書き込み操作を統合して、より大きなデータ サイズを使用する書き込み操作を減らすることをお勧めします。
FILESTREAM ハンドルを使用したメモリ マップビュー (メモリ マップ I/O) の作成はサポートされていません。 FILESTREAM データにメモリ マッピングを使用する場合、データベース エンジンは、データの整合性と持続性、またはデータベースの整合性を保証できません。
関連タスク
FILESTREAM の有効化と構成
FILESTREAM が有効なデータベースを作成する方法
FILESTREAM データを格納するテーブルを作成する方法
Transact-SQLを使用して FILESTREAM データにアクセスする
FILESTREAM データ用のクライアント アプリケーションの作成
OpenSqlFilestream による FILESTREAM データへのアクセス
FILESTREAM データの部分的な更新
FILESTREAM アプリケーションでのデータベース操作との競合の回避
FILESTREAM-Enabled データベースを移動する
フェールオーバー クラスターでの FILESTREAM の設定
FILESTREAM アクセスのためのファイアウォールの構成