首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 直接儲存二進位檔案(圖片/文件)完整實作指南

     編輯:MySQL 資料庫相關知識

將圖片、PDF 等二進位檔案直接存入 MySQL 資料庫(而非僅存路徑)在特定場景下具備優勢:資料完整性強、備份單一化、權限控管集中。本文示範如何建立資料表、透過 HTML 表單上傳、以及以 PHP 腳本讀取輸出,並說明大檔案儲存的關鍵調校參數。

一、建立資料庫與資料表

CREATE DATABASE binary_data;
USE binary_data;

CREATE TABLE binary_data (
    id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    description CHAR(50),
    bin_data LONGBLOB,
    filename CHAR(50),
    filesize CHAR(50),
    filetype CHAR(50)
);

欄位說明: LONGBLOB 可儲存最多 4GB 二進位資料;filetype 儲存 MIME 類型(如 image/jpeg),供瀏覽器正確渲染。

二、上傳儲存腳本 store.php

<?php
// store.php - 儲存二進位檔案至 MySQL
$host = 'localhost'; $user = 'root'; $pass = 'password'; $db = 'binary_data';

if (isset($_POST['submit'])) {
    $conn = mysqli_connect($host, $user, $pass, $db);
    if (!$conn) die('連線失敗: ' . mysqli_connect_error());

    $desc = mysqli_real_escape_string($conn, $_POST['form_description']);
    $file = $_FILES['form_data'];
    $data = addslashes(file_get_contents($file['tmp_name']));
    $name = mysqli_real_escape_string($conn, $file['name']);
    $size = $file['size'];
    $type = mysqli_real_escape_string($conn, $file['type']);

    $sql = "INSERT INTO binary_data (description, bin_data, filename, filesize, filetype)
            VALUES ('$desc', '$data', '$name', '$size', '$type')";
    if (mysqli_query($conn, $sql)) {
        $id = mysqli_insert_id($conn);
        echo "檔案已儲存,資料庫 ID: $id(請記下此 ID 供後續讀取)";
    } else {
        echo "錯誤: " . mysqli_error($conn);
    }
    mysqli_close($conn);
} else {
?>

上傳檔案至資料庫
檔案描述:

選擇檔案:

<?php } ?>

關鍵點:表單必須設 enctype="multipart/form-data";使用 $_FILES 陣列取得暫存檔路徑 tmp_name;addslashes() 處理二進位資料中的特殊字元(現代建議改用 mysqli_real_escape_string 或預處理語句)。

三、讀取輸出腳本 getdata.php

<?php
// getdata.php - 依 ID 輸出二進位內容
$host = 'localhost'; $user = 'root'; $pass = 'password'; $db = 'binary_data';

if (isset($_GET['id']) && ctype_digit($_GET['id'])) {
    $id = (int)$_GET['id'];
    $conn = mysqli_connect($host, $user, $pass, $db);
    if (!$conn) die('連線失敗');

    $sql = "SELECT bin_data, filetype FROM binary_data WHERE id = $id";
    $res = mysqli_query($conn, $sql);
    if ($row = mysqli_fetch_assoc($res)) {
        header("Content-Type: " . $row['filetype']);
        echo $row['bin_data'];
    } else {
        header("HTTP/1.0 404 Not Found");
        echo "找不到指定 ID 的檔案";
    }
    mysqli_close($conn);
} else {
    echo "請提供有效的 id 參數,例如:getdata.php?id=3";
}
?>

前端引用範例

<!-- 直接當作圖片來源 -->
<img src="getdata.php?id=3" alt="資料庫圖片">

<!-- 或提供下載連結 -->
<a href="getdata.php?id=5">下載檔案 (ID=5)</a>

四、突破 1MB 預設限制,支援大檔案(至 24MB 為例)

預設 PHP 與 MySQL 多項設定限制上傳大小,需同步調整:

層面設定項目建議值 (24MB)
HTML 表單<input type="hidden" name="MAX_FILE_SIZE" value="24000000">24000000
PHP (php.ini)upload_max_filesize24M
PHP (php.ini)post_max_size32M (略大於 upload_max_filesize)
PHP (php.ini)memory_limit64M 以上
MySQL 啟動參數max_allowed_packet24M

MySQL 啟動範例:

/usr/local/bin/mysqld_safe --max_allowed_packet=24M --key_buffer=16M --table_cache=128 --sort_buffer=4M --record_buffer=1M &

注意:資料庫儲存大量二進位資料會導致備份檔案極大、記憶體壓力增加,生產環境建議評估「儲存檔案路徑 + 物件儲存(S3/MinIO)」架構。

五、安全性與最佳實踐補充

  • SQL 注入防護:實務上務必使用預處理語句(mysqli_prepare / PDO::prepare)替代字串拼接。
  • 檔案類型驗證:勿只信任 $_FILES['type'],建議用 finfo_file() 偵測真實 MIME。
  • 權限控管:資料庫帳號僅授予必要權限(INSERT、SELECT),避免使用 root 直連。
  • 效能考量:頻繁讀寫大 BLOB 會影響緩衝池效率,可考慮將 bin_data 拆分至獨立資料表甚至獨立資料庫實例。

透過本文完整範例,您可以快速建立「資料庫即檔案儲存」的原型系統,並理解相關參數調校與安全性要點,為後續架構決策提供實證依據。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved