MySQL 提供四種二進制大對象類型,核心差異在於最大存儲容量:
| 類型 | 最大長度 | 適用場景 | 存儲開銷 |
|---|---|---|---|
TINYBLOB | 255 Bytes (28-1) | 極小二進制片段、圖標、縮略圖 | 1 字節長度前綴 |
BLOB | 64 KB (216-1) | 小型文檔、配置文件、中等圖片 | 2 字節長度前綴 |
MEDIUMBLOB | 16 MB (224-1) | 較大圖片、音頻片段、壓縮包 | 3 字節長度前綴 |
LONGBLOB | 4 GB (232-1) | 高清視頻、大型二進制文件 | 4 字節長度前綴 |
注意: 實際最大值受 max_allowed_packet 限制 (默認 4MB/64MB),大文件插入前需調大此參數。
mysqldump 單命令全量備份,無需單獨管理文件系統快照。INDEX idx_blob (data(255))),查詢靈活性極低。CREATE TABLE attachments (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
biz_id BIGINT NOT NULL,
file_path VARCHAR(512) NOT NULL COMMENT '相對存儲路徑',
file_size INT UNSIGNED NOT NULL,
mime_type VARCHAR(100),
checksum CHAR(64) COMMENT 'SHA256 校驗',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_biz (biz_id)
) ENGINE=InnoDB;
文件存儲於對象存儲 (S3/OSS/MinIO) 或分布式文件系統,資料庫僅存元數據。優勢:資料庫輕量、備份秒級、CDN 加速下載、無連接數壓力。
-- 元數據表:高頻查詢、全索引覆蓋
CREATE TABLE doc_meta (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(200),
category_id INT,
status TINYINT,
updated_at TIMESTAMP,
INDEX idx_cat_status (category_id, status)
) ENGINE=InnoDB;
-- 內容表:低頻讀寫、隔離緩衝池壓力
CREATE TABLE doc_content (
doc_id BIGINT PRIMARY KEY,
content MEDIUMBLOB NOT NULL,
compressed TINYINT DEFAULT 0 COMMENT '是否壓縮'
) ENGINE=InnoDB COMPRESSION='zlib'; -- MySQL 8.0+ 支援表級壓縮
業務邏輯:列表/搜索只查 doc_meta;詳情頁按需 JOIN doc_content。可針對內容表配置獨立 Buffer Pool (innodb_buffer_pool_instances) 或放置在較慢存儲介質。
體積膨脹 33%,無法流式讀取,全文檢索失效,堅決避免。
max_allowed_packet=256M:客戶端/服務端通訊包上限,必須大於最大單文件。innodb_log_file_size:增大 Redo Log (如 1G),減少大事務刷盤頻率。innodb_buffer_pool_size:預留 20%+ 空間給溢出頁,或為內容表配置專用實例。innodb_strict_mode=ON:嚴格模式下超長 BLOB 直接報錯而非截斷。若現有系統已大量使用 BLOB,建議分階段遷移:
file_path 列,雙寫模式上線 (寫 DB 同時上傳 OSS)。file_path,清空 BLOB 列或標記 migrated=1。ALTER TABLE ... DROP COLUMN blob_col 釋放空間。