優秀的表結構設計是高效能資料庫的基石。本文從字符集選擇、主鍵設計、外鍵權衡、索引策略、特殊字段處理、分表分庫六大維度,系統總結建表優化最佳實踐。
utf8mb4_general_ci 或 utf8mb4_0900_ai_ci(8.0+)。GBK(2 字節/漢字)較 UTF8(3 字節)節省 33% 空間,但不支援 Emoji、國際化擴展受限。| 原則 | 說明 |
|---|---|
| 短小精悍 | 優先 BIGINT/INT UNSIGNED AUTO_INCREMENT,避免 UUID、MD5、長字串 |
| 業務無關 | 主鍵不承載業務含義,避免業務變更導致主鍵變更 |
| 單調遞增 | InnoDB 聚簇索引按主鍵順序存儲,遞增寫入減少頁分裂 |
| 類型足夠 | TINYINT(255) → SMALLINT(65K) → MEDIUMINT(16M) → INT(42億) → BIGINT |
| 一對一共用主鍵 | 從表主鍵即為主表主鍵,省去額外索引 |
注意: 主鍵自帶聚簇索引,無需額外建單列索引;允許在二級索引中包含主鍵列(覆蓋索引)。
FOREIGN_KEY_CHECKS;跨庫/分表不支援。INDEX idx_a_b_c (a, b, c)
-- 可匹配:a | a,b | a,b,c
-- 不可匹配:b | b,c | c
聯合索引等價於建立 (a)、(a,b)、(a,b,c) 三個索引,節省空間、提升組合查詢效能。
CREATE INDEX idx_name_prefix ON t_main(name(3));
-- 僅索引前 3 字符,適用於長字符串高重複前綴(如 URL、郵箱域名)
-- 最大 1000 字節(InnoDB 767/3072),GBK 下約 500 漢字
| 類型 | 策略 | 權衡 |
|---|---|---|
| 冗餘字段 | 以空間換時間:如訂單表冗餘 user_name、goods_name,避免 JOIN | 需同步機制(觸發器/應用雙寫/消息隊列),數據一致性風險 |
| 拆分字段 | 頻繁 SUBSTRING 查詢的列拆分存儲:如 full_name → first_name + last_name | 寫入稍複雜,查詢大幅加速 |
| 層級結構 | 樹狀結構拆分 level1_id, level2_id, level3_id 或 Closure Table | 避免遞歸查詢,支援任意層級祖先/後代查詢 |
| BLOB/TEXT/CLOB | 極力避免存入資料庫:存檔案系統/對象存儲,庫存路徑/URL | 減小備份體積、提升緩存命中、避免主從同步延遲 |
大表中高頻列(id、name、status)與低頻列(detail、blob、log)分離,主表瘦身,熱數據緩存命中率提升。
按範圍(時間)、哈希(ID)、列表(地區)分區,實現分區裁剪、歸檔快速 DROP PARTITION。