FileTable とは、実際には FileStream を意味すると思います。それについてのいくつかのメモ:
- この機能は、ファイルが実際にファイルである場合に最適です
- ファイルは、平均して 1 MB を超える必要があります。この規則には例外がありますが、ファイルが平均で 1 MB 未満の場合は、必要に応じて
VARBINARY(MAX)
またはXML
データ型を使用する方がよい場合があります。画像が平均して非常に小さい (わずか数 KB) 場合は、VARBINARY(MAX)
列の使用を検討してください。
- これらのファイルにアクセスするには、開いているトランザクションが必要であり、データベースが適切に構成されている必要があります。
FILESTREAM
- ファイルに直接アクセスすることを SQL Server に指示することで、通常の SQL エンジン/データベース ファイル方式のデータ アクセスをバイパスすることで、いくつかの大きな利点を得ることができます。これらのファイルの SQL の管理 (トランザクションの一貫性、追跡、ロックなど) を壊します。
- このために SQL が本当に必要な場合は、CDN を使用してイメージ URL をテーブルに保存することで、ここでのユース ケースがより適切に処理される可能性が高くなります。を使用してこれを行うことができ
FILESTREAM
ます(1 つの実装については、以下のコード サンプルを参照してください) が、ブラウザが適切にキャッシュできる別の場所に画像を保存しない限り、リクエストごとに SQL サーバーを攻撃することになります (私の例ではそれを行いません)。 ) - そして、ブラウザでレンダリングするためにそれらを別の場所に保存する場合は、最初からそこに保存することもできます (これらの画像を他のドライブ/ディスク/場所にコピーすると、トランザクションの一貫性が失われます) .
FILESTREAM
以上のことから、 ADO.NET を使用してデータにアクセスする方法の例を次に示します。
public static string connectionString = ...; // get your connection string from encrypted config
// assumes your FILESTREAM data column is called Img in a table called ImageTable
const string sql = @"
SELECT
Img.PathName(),
GET_FILESTREAM_TRANSACTION_CONTEXT()
FROM ImageTagble
WHERE ImageId = @id";
public string RetreiveImage(int id)
{
string serverPath;
byte[] txnToken;
string base64ImageData = null;
using (var ts = new TransactionScope())
{
using (var conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add("@id", SqlDbType.Int).Value = id;
using (SqlDataReader rdr = cmd.ExecuteReader())
{
rdr.Read();
serverPath = rdr.GetSqlString(0).Value;
txnToken = rdr.GetSqlBinary(1).Value;
}
}
using (var sfs = new SqlFileStream(serverPath, txnToken, FileAccess.Read))
{
// sfs will now work basically like a FileStream. You can either copy it locally or return it as a base64 encoded string
using (var ms = new MemoryStream())
{
sfs.CopyTo(ms);
base64ImageData = Convert.ToBase64String(ms.ToArray());
}
}
}
ts.Complete();
// assume this is PNG image data, replace PNG with JPG etc. as appropraite. Might store in table if it will vary...
return "data:img/png;base64," + base64ImageData;
}
}
明らかに、このように処理する画像がたくさんある場合、これは理想的な方法ではありません.CDNを使用する必要があるものにSQLサーバーのインスタンスを作成しようとしないでください...正当な理由として、1 回のリクエスト/トランザクションでできるだけ多くの画像を取得するようにしてください (たとえば、ページに 50 枚の画像を表示していることがわかっている場合は、1 つのトランザクション スコープで 50 個すべてを取得し、50 トランザクション スコープを使用しないでください)。 - このコードはそれを処理しません)。