0

私が知っているように、バージョン 2012 以降の SQL Server には新しい機能FileTable. ファイルをファイル システムに保存し、T-SQL から使用できるようにします。

この機能を使用しようとしていますが、適切に使用する方法がわかりません。

通常、ファイル テーブルに保存されているファイルにアクセスする方法がわかりません。asp.net MVC アプリがあり、web ページに img タグで表示する画像がたくさんあるとします。これらの画像を Filetable に保存し、ファイルシステムからファイルとしてアクセスしたいと思います。しかし、これらのファイルがどこに保存されているのか、ファイルとして使用する方法がわかりません。これで、私の画像はフォルダー画像の Web アプリケーション ディレクトリに保存され、次のように記述します。

<img src='/images/mypicture.png' />

画像をファイル テーブルに移動する場合、src に何を書き込む必要がありますか?

<img src='path-toimage-in-filetable' />
4

2 に答える 2

-1

FileTable とは、実際には FileStream を意味すると思います。それについてのいくつかのメモ:

  1. この機能は、ファイルが実際にファイルである場合に最適です
  2. ファイルは、平均して 1 MB を超える必要があります。この規則には例外がありますが、ファイルが平均で 1 MB 未満の場合は、必要に応じてVARBINARY(MAX)またはXMLデータ型を使用する方がよい場合があります。画像が平均して非常に小さい (わずか数 KB) 場合は、VARBINARY(MAX)列の使用を検討してください。
  3. これらのファイルにアクセスするには、開いているトランザクションが必要であり、データベースが適切に構成されている必要があります。FILESTREAM
  4. ファイルに直接アクセスすることを SQL Server に指示することで、通常の SQL エンジン/データベース ファイル方式のデータ アクセスをバイパスすることで、いくつかの大きな利点を得ることができます。これらのファイルの SQL の管理 (トランザクションの一貫性、追跡、ロックなど) を壊します。
  5. このために 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 トランザクション スコープを使用しないでください)。 - このコードはそれを処理しません)。

于 2017-01-17T13:52:27.733 に答える