首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 儲存與輸出二進位影像完整實作:從 IMAGE 型別到 VARBINARY(MAX) 的最佳實踐

     編輯:關於SqlServer

前言

資料庫儲存影像、文件等二進位物件 (BLOB) 是常見需求。SQL Server 提供 IMAGE (舊版) 與 VARBINARY(MAX) (2005+) 資料型別。本文以 ASP.NET (C#) 為例,示範完整的上傳儲存、下載輸出流程,並說明現代最佳實踐 (Filestream/FileTable、雲端 Blob 儲存)。

資料表設計

CREATE TABLE dbo.ImageStore
(
    ID       INT IDENTITY(1,1) PRIMARY KEY,
    ImgTitle NVARCHAR(100) NOT NULL,
    ImgType  NVARCHAR(100) NOT NULL,  -- MIME 類型,如 image/jpeg, application/pdf
    ImgData  VARBINARY(MAX) NOT NULL  -- SQL Server 2005+ 建議用 VARBINARY(MAX) 取代 IMAGE
);

注意:IMAGE 為舊版型別,未來版本將移除,新專案請使用 VARBINARY(MAX)。

前端上傳頁面

<%@ Page Language="C#" %>
<form id="form1" runat="server" enctype="multipart/form-data">
    標題: <asp:TextBox ID="txtTitle" runat="server" /><br />
    檔案: <input type="file" id="File1" runat="server" /><br />
    <asp:Button ID="btnUpload" runat="server" Text="上傳" OnClick="btnUpload_Click" />
</form>

後端上傳邏輯

protected void btnUpload_Click(object sender, EventArgs e)
{
    if (File1.PostedFile == null || File1.PostedFile.ContentLength == 0) return;

    Stream fs = File1.PostedFile.InputStream;
    int len = File1.PostedFile.ContentLength;
    string type = File1.PostedFile.ContentType;
    string title = txtTitle.Text;

    byte[] data = new byte[len];
    fs.Read(data, 0, len);

    string connStr = ConfigurationManager.ConnectionStrings["ImgDB"].ConnectionString;
    using (SqlConnection conn = new SqlConnection(connStr))
    using (SqlCommand cmd = new SqlCommand(
        "INSERT INTO ImageStore (ImgTitle, ImgType, ImgData) VALUES (@Title, @Type, @Data)", conn))
    {
        cmd.Parameters.Add("@Title", SqlDbType.NVarChar, 100).Value = title;
        cmd.Parameters.Add("@Type", SqlDbType.NVarChar, 100).Value = type;
        cmd.Parameters.Add("@Data", SqlDbType.VarBinary, -1).Value = data;  // -1 = MAX

        conn.Open();
        cmd.ExecuteNonQuery();
    }
}

關鍵點:

  • 使用 SqlParameter 參數化,防止 SQL Injection、自動處理二進位編碼。
  • SqlDbType.VarBinary, -1 對應 VARBINARY(MAX)。
  • using 確保連線/命令正確釋放。

影像輸出處理器

public partial class GetImage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string id = Request.QueryString["id"];
        if (string.IsNullOrEmpty(id)) return;

        string connStr = ConfigurationManager.ConnectionStrings["ImgDB"].ConnectionString;
        using (SqlConnection conn = new SqlConnection(connStr))
        using (SqlCommand cmd = new SqlCommand(
            "SELECT ImgData, ImgType FROM ImageStore WHERE ID = @ID", conn))
        {
            cmd.Parameters.Add("@ID", SqlDbType.Int).Value = int.Parse(id);
            conn.Open();
            using (SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
            {
                if (dr.Read())
                {
                    Response.Clear();
                    Response.ContentType = dr.GetString(1);  // ImgType
                    // 使用 GetBytes 串流輸出,避免大檔案記憶體壓力
                    long offset = 0;
                    byte[] buffer = new byte[8192];
                    long bytesRead;
                    while ((bytesRead = dr.GetBytes(0, offset, buffer, 0, buffer.Length)) > 0)
                    {
                        Response.OutputStream.Write(buffer, 0, (int)bytesRead);
                        offset += bytesRead;
                    }
                    Response.End();
                }
            }
        }
    }
}

呼叫方式:<img src="GetImage.aspx?id=123" />

進階主題:大型 BLOB 的現代替代方案

方案適用場景優點缺點
VARBINARY(MAX) 資料庫內儲存小檔案 (< 1MB)、交易一致性要求高、備份單一檔案ACID、備份簡單、權限隨資料庫資料庫膨脹、備份/還原慢、記憶體壓力
FILESTREAM (SQL Server 2008+)大檔案 (1MB~2GB)、Win32 流式存取、需交易一致性NTFS 流效能、不佔資料庫空間、支援備份需啟用檔案群組、僅限本機/Windows 驗證
FileTable (SQL Server 2012+)非結構化檔案目錄、需檔案系統 API (完整路徑、屬性)透過資料表/檔案系統雙重存取、全文檢索版本要求高、管理複雜度較高
Azure Blob / AWS S3 + 資料庫存 URL雲端原生、海量、CDN 分發、跨區域無限擴展、成本低、全球分發、生命週期管理交易一致性最終一致、需應用層協調

安全與效能提醒

  1. 檔案類型驗證:勿信任 ContentType,需檢查檔案簽名 (Magic Number) 或用 System.Drawing.Image 驗證影像合法性。
  2. 大小限制:web.config 設定 <httpRuntime maxRequestLength="10240" /> (KB) + IIS 要求篩選限制。
  3. 串流輸出:大檔案務必用 GetBytes / SqlFileStream 串流,避免一次性載入記憶體導致 OOM。
  4. 快取策略:輸出時加 Response.Cache.SetCacheability(HttpCacheability.Public); Response.Cache.SetMaxAge(TimeSpan.FromDays(30)); 瀏覽器/CDN 快取。
  5. 權限控制:GetImage.aspx 需驗證使用者對該影像的讀取權限,避免 ID 遍舉洩露。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved