MySQL 分表是處理大數(shù)據(jù)量表的常用優(yōu)化手段,通過(guò)將大表拆分為多個(gè)小表,提高查詢效率和管理靈活性。以下是分表的核心方法和實(shí)現(xiàn)方式:
將表中不同行的數(shù)據(jù)拆分到多個(gè)表中,每個(gè)表結(jié)構(gòu)相同。適用場(chǎng)景:表行數(shù)極多(如千萬(wàn)級(jí)以上),查詢常按某字段篩選(如時(shí)間、用戶 ID)。
將表中不同列的數(shù)據(jù)拆分到多個(gè)表中,每個(gè)表存儲(chǔ)部分字段。適用場(chǎng)景:表字段過(guò)多,或包含大字段(如 text、blob),多數(shù)查詢只用到部分字段。
根據(jù)特定規(guī)則手動(dòng)創(chuàng)建分表,在應(yīng)用層控制數(shù)據(jù)路由。
示例:按時(shí)間分表存儲(chǔ)日志
CREATE TABLE log_202301 (
id INT PRIMARY KEY AUTO_INCREMENT,
content TEXT,
create_time DATETIME
) ENGINE=InnoDB;
CREATE TABLE log_202302 LIKE log_202301;
應(yīng)用層邏輯:
-
寫入時(shí)根據(jù)
create_time判斷數(shù)據(jù)應(yīng)存入哪個(gè)表
-
查詢時(shí)根據(jù)時(shí)間范圍確定需要訪問(wèn)的分表
MySQL 5.7 + 支持分區(qū)表,將數(shù)據(jù)在物理上分開存儲(chǔ),但邏輯上仍是一個(gè)表。
示例:按范圍分區(qū)(時(shí)間)
CREATE TABLE logs (
id INT PRIMARY KEY AUTO_INCREMENT,
content TEXT,
create_time DATETIME
) ENGINE=InnoDB
PARTITION BY RANGE (TO_DAYS(create_time)) (
PARTITION p202301 VALUES LESS THAN (TO_DAYS('2023-02-01')),
PARTITION p202302 VALUES LESS THAN (TO_DAYS('2023-03-01')),
PARTITION p_other VALUES LESS THAN MAXVALUE
);
示例:按哈希分區(qū)(用戶 ID)
CREATE TABLE user_data (
id INT PRIMARY KEY,
name VARCHAR(50),
uid INT
) ENGINE=InnoDB
PARTITION BY HASH (uid)
PARTITIONS 10;
當(dāng)分表數(shù)量極多(如數(shù)百個(gè)),可借助中間件自動(dòng)管理:
-
MyCat:開源分布式數(shù)據(jù)庫(kù)中間件
-
ShardingSphere:生態(tài)更完善,支持分庫(kù)分表、讀寫分離等
核心原理:中間件攔截 SQL,根據(jù)分片規(guī)則路由到對(duì)應(yīng)分表,對(duì)應(yīng)用層透明。
將表中不常用或大字段拆分到單獨(dú)表,通過(guò)主鍵關(guān)聯(lián)。
示例:用戶表拆分
CREATE TABLE user_core (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50),
email VARCHAR(100),
create_time DATETIME
) ENGINE=InnoDB;
CREATE TABLE user_extra (
user_id INT PRIMARY KEY,
bio TEXT,
avatar BLOB,
FOREIGN KEY (user_id) REFERENCES user_core(id)
) ENGINE=InnoDB;
查詢時(shí)按需關(guān)聯(lián):
SELECT username, email FROM user_core WHERE id = 1;
SELECT c.username, e.bio
FROM user_core c
JOIN user_extra e ON c.id = e.user_id
WHERE c.id = 1;
-
分片規(guī)則設(shè)計(jì):
-
盡量讓數(shù)據(jù)均勻分布,避免某分表過(guò)大
-
結(jié)合查詢場(chǎng)景,讓常用查詢只命中少數(shù)分表
-
主鍵處理:
-
避免使用自增主鍵(可能重復(fù)),可采用全局 ID 生成器(如雪花算法)
-
分區(qū)表可保持自增主鍵(MySQL 自動(dòng)處理)
-
事務(wù)與關(guān)聯(lián)查詢:
-
跨分表事務(wù)難以保證一致性
-
跨分表 JOIN 效率低,應(yīng)盡量避免
-
維護(hù)成本:
-
手動(dòng)分表需處理分表創(chuàng)建、數(shù)據(jù)遷移等
-
分區(qū)表需定期清理歷史分區(qū)(如
DROP PARTITION)
選擇哪種方式取決于數(shù)據(jù)量、查詢模式和系統(tǒng)架構(gòu),中小規(guī)模推薦分區(qū)表,大規(guī)模分布式系統(tǒng)推薦中間件方案。