BLOB (Binary Large Object) 用於儲存二進制大物件:圖片、音訊、文件等。資料庫僅負責存取,不解析內容。
雙刃劍警示: 大量/大型 BLOB 會嚴重影響資料庫效能 (緩衝池污染、備份緩慢、複制延遲)。生產環境強烈建議:檔案存對象儲存 (S3/MinIO),資料庫只存路徑/元數據。
| 類型 | 最大儲存量 | 適用場景 | 儲存開銷 |
|---|---|---|---|
TINYBLOB | 255 Bytes | 極小二進制片段 | 1 Byte 長度前綴 |
BLOB | 64 KB | 小圖示、縮圖 | 2 Bytes 長度前綴 |
MEDIUMBLOB | 16 MB | 一般文件、照片 | 3 Bytes 長度前綴 |
LONGBLOB | 4 GB | 大型媒體檔案 | 4 Bytes 長度前綴 |
控制單次網路封包/語句最大長度,必須大於最大 BLOB 大小。
[mysqld] max_allowed_packet = 64M # 建議設為 64M 或更大 [mysqldump] max_allowed_packet = 64M # 備份工具獨立配置
SET GLOBAL max_allowed_packet = 67108864; -- 64M SHOW VARIABLES LIKE 'max_allowed_packet';
CREATE TABLE documents ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, filename VARCHAR(255) NOT NULL, mime_type VARCHAR(100), content MEDIUMBLOB, -- 16MB 足多數文件 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB;
-- 使用 LOAD_FILE (需 FILE 權限、檔案在 Server 端)
INSERT INTO documents (filename, mime_type, content)
VALUES ('report.pdf', 'application/pdf', LOAD_FILE('/data/report.pdf'));
$stmt = $pdo->prepare("INSERT INTO documents (filename, mime_type, content) VALUES (?, ?, ?)");
$stmt->bindParam(1, $filename);
$stmt->bindParam(2, $mime);
$stmt->bindParam(3, $blob, PDO::PARAM_LOB); -- 關鍵:PARAM_LOB
$stmt->execute();
COMPRESSED 行格式 + innodb_compression_levelmysqli_stmt_send_long_data() 分塊傳輸,避免記憶體飆升-- 階段 1:新增路徑欄位 ALTER TABLE documents ADD COLUMN storage_path VARCHAR(500); -- 階段 2:應用雙寫 (資料庫 + S3) -- 階段 3:歷史資料遷移腳本 -- 階段 4:切換讀取至 S3,資料庫僅存路徑 -- 階段 5:清理 BLOB 欄位 (ALTER TABLE ... DROP COLUMN content)
合理選擇 BLOB 類型、調整 max_allowed_packet、評估對象儲存替代方案,是處理二進制資料的三大關鍵決策。