Schema 設計直接決定系統性能上限、擴展邊界與運維成本。本文基於生產實戰總結 11 大設計模式:反範式冗余、大字段垂直拆分、寬表瘦身、分頁優化、熱點讀寫隔離、準實時/實時統計、分區表與數據淘汰、周邊需求預留、自動時間戳、前瞻性演進,附帶反模式對比圖解。
場景:訂單表頻繁 JOIN 用戶表查詢用戶名、手機號
反模式:純正規化,每次查詢 JOIN
優化:訂單表冗余 buyer_name、buyer_phone,寫入時同步冗余,讀取零 JOIN
-- 寫入觸發器/應用層雙寫
INSERT INTO orders (..., buyer_name, buyer_phone)
SELECT ..., u.name, u.phone FROM users u WHERE u.id = ?
場景:商品表含 description TEXT、images JSON,列表查詢不需要
拆分:product_base (id, name, price, status) + product_detail (product_id, description, images)
收益:基表行長度短,Buffer Pool 容納更多熱數據,列表查詢避免讀取大字段溢出頁
限制:InnoDB 行長度 ≤ 65535 字節,超限報錯
拆分策略:核心屬性留主表,擴展屬性按業務域拆子表 (1:1 關聯)
user_core (id, phone, pwd_hash, status, create_time)
user_profile (user_id, nickname, avatar, gender, birthday)
user_settings (user_id, notify_email, notify_sms, theme, lang)
問題:LIMIT 1000000, 20 掃描 100 萬行再丟棄
方案 A:延遲關聯
SELECT t.* FROM t
INNER JOIN (SELECT id FROM t WHERE cond ORDER BY id LIMIT 1000000, 20) tmp USING (id);
方案 B:游標/ID 下標
WHERE id > last_max_id ORDER BY id LIMIT 20 -- 適合無限滾動
方案 C:覆蓋索引:INDEX (cond_col, id) 索引下推完成排序定位
場景:置頂文章、熱門評論、大 V 動態,訪問量佔 80%+
隔離:article_hot (置順/熱門) + article_normal (普通),應用層路由或 UNION ALL
SELECT * FROM article_hot WHERE id=?
UNION ALL
SELECT * FROM article_normal WHERE id=?
場景:微博大 V 發文,百萬粉絲寫入收件箱 (扇出寫入)
拉/推混合:
-- 大 V 專屬表
CREATE TABLE feed_vip (vip_id, content, create_time);
-- 普通用戶收件箱
CREATE TABLE inbox (user_id, feed_id, create_time);
定時聚合表:每分鐘跑批,按 last_update_time 增量統計
INSERT INTO stats_hourly (hour, metric, value)
SELECT DATE_FORMAT(create_time, '%Y-%m-%d %H'), 'orders', COUNT(*)
FROM orders WHERE create_time >= last_update_time
ON DUPLICATE KEY UPDATE value=value+VALUES(value);
| 方案 | 原理 | 優點 | 缺點 |
|---|---|---|---|
| 觸發器 | INSERT/UPDATE 觸發更新統計表 | 強一致、簡單 | 寫入延遲增加、鎖爭用 |
| 緩存聚合 | 應用層內存計數,定期/失效落庫 | 極快、無 DB 壓力 | 進程重啟丟失、一致性弱 |
| 最大自增 ID | 自增 ID 即總量 (無刪除/回滾場景) | 零成本、精確 | 業務限制嚴格 |
-- RANGE 分區 (按時間)
CREATE TABLE logs_2023 PARTITION BY RANGE (YEAR(create_time)) (
PARTITION p202301 VALUES LESS THAN (20230201),
PARTITION p202302 VALUES LESS THAN (20230301),
PARTITION pmax VALUES LESS THAN MAXVALUE
);
-- 淘汰舊數據 (秒級)
ALTER TABLE logs_2023 DROP PARTITION p202301;
-- LIST 分區 (按業務類型)
PARTITION BY LIST COLUMNS (biz_type) (
PARTITION p_order VALUES IN ('order','pay'),
PARTITION p_user VALUES IN ('login','register')
);
-- HASH 分區 (均勻分布)
PARTITION BY HASH (user_id) PARTITIONS 16;
INDEX idx_create_time_status (create_time, status))create_time/update_time (自動維護),支持增量同步operator_id/operator_ip-- 5.6.5+ 支持
CREATE TABLE t (
id INT PRIMARY KEY,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- 兼容舊版:觸發器
CREATE TRIGGER t_bi BEFORE INSERT ON t FOR EACH ROW SET NEW.create_time = NOW();
CREATE TRIGGER t_bu BEFORE UPDATE ON t FOR EACH ROW SET NEW.update_time = NOW();
業務加密改造:需對用戶手機號、身份證加密存儲
sensitive_data_vault 表 (user_id, field_name, encrypted_value, version),應用層統一讀寫入口,遷移時僅遷移數據、應用無感優秀 Schema 設計 = 業務正確 + 查詢友好 + 寫入高效 + 擴展彈性 + 運維友好。11 大模式非孤立,需組合應用:寬表拆分+冗余字段+分區淘汰+統計預聚合。建立 Schema 變更審查機制:新建表必審索引、大表 DDL 必走在線工具、字段類型變更必評估數據截斷、業務調整必考慮歷史數據兼容。記錄每次 Schema 變更動機與後果,構建團隊設計知識庫,實現真正的前瞻性演進。