MySQL 分表是处理大数据量表的常用优化手段,通过将大表拆分为多个小表,提高查询效率和管理灵活性。以下是分表的核心方法和实现方式:
将表中不同行的数据拆分到多个表中,每个表结构相同。适用场景:表行数极多(如千万级以上),查询常按某字段筛选(如时间、用户 ID)。
将表中不同列的数据拆分到多个表中,每个表存储部分字段。适用场景:表字段过多,或包含大字段(如 text、blob),多数查询只用到部分字段。
根据特定规则手动创建分表,在应用层控制数据路由。
示例:按时间分表存储日志
CREATE TABLE log_202301 (
id INT PRIMARY KEY AUTO_INCREMENT,
content TEXT,
create_time DATETIME
) ENGINE=InnoDB;
CREATE TABLE log_202302 LIKE log_202301;
应用层逻辑:
-
写入时根据
create_time判断数据应存入哪个表
-
查询时根据时间范围确定需要访问的分表
MySQL 5.7 + 支持分区表,将数据在物理上分开存储,但逻辑上仍是一个表。
示例:按范围分区(时间)
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
);
示例:按哈希分区(用户 ID)
CREATE TABLE user_data (
id INT PRIMARY KEY,
name VARCHAR(50),
uid INT
) ENGINE=InnoDB
PARTITION BY HASH (uid)
PARTITIONS 10;
当分表数量极多(如数百个),可借助中间件自动管理:
-
MyCat:开源分布式数据库中间件
-
ShardingSphere:生态更完善,支持分库分表、读写分离等
核心原理:中间件拦截 SQL,根据分片规则路由到对应分表,对应用层透明。
将表中不常用或大字段拆分到单独表,通过主键关联。
示例:用户表拆分
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;
查询时按需关联:
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;
-
分片规则设计:
-
尽量让数据均匀分布,避免某分表过大
-
结合查询场景,让常用查询只命中少数分表
-
主键处理:
-
避免使用自增主键(可能重复),可采用全局 ID 生成器(如雪花算法)
-
分区表可保持自增主键(MySQL 自动处理)
-
事务与关联查询:
-
跨分表事务难以保证一致性
-
跨分表 JOIN 效率低,应尽量避免
-
维护成本:
-
手动分表需处理分表创建、数据迁移等
-
分区表需定期清理历史分区(如
DROP PARTITION)
选择哪种方式取决于数据量、查询模式和系统架构,中小规模推荐分区表,大规模分布式系统推荐中间件方案。