电商系统中的订单数据通常具有以下特点: - 数据量增长迅速(日均订单可达数百万) - 查询模式多样(按用户ID、时间范围、订单状态等) - 历史数据访问频率低但需要保留 - 需要支持高并发读写
按时间范围分区(最常用):
CREATE TABLE orders (
order_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
order_date DATETIME NOT NULL,
amount DECIMAL(10,2),
status VARCHAR(20),
-- 其他字段
PRIMARY KEY (order_id, order_date)
) PARTITION BY RANGE (TO_DAYS(order_date)) (
PARTITION p202301 VALUES LESS THAN (TO_DAYS('2023-02-01')),
PARTITION p202302 VALUES LESS THAN (TO_DAYS('2023-03-01')),
-- 后续月份分区
PARTITION pmax VALUES LESS THAN MAXVALUE
);
按用户ID哈希分区(适合用户维度查询):
CREATE TABLE orders (
-- 字段同上
PRIMARY KEY (order_id, user_id)
) PARTITION BY HASH(user_id)
PARTITIONS 10;
复合分区策略(时间+哈希):
CREATE TABLE orders (
-- 字段同上
PRIMARY KEY (order_id, order_date, user_id)
) PARTITION BY RANGE (TO_DAYS(order_date))
SUBPARTITION BY HASH(user_id)
SUBPARTITIONS 10 (
PARTITION p202301 VALUES LESS THAN (TO_DAYS('2023-02-01')),
-- 其他时间分区
);
自动添加新分区(使用存储过程):
DELIMITER //
CREATE PROCEDURE add_order_partition(IN p_name VARCHAR(50), IN p_date DATE)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
-- 错误处理
END;
SET @sql = CONCAT('ALTER TABLE orders ADD PARTITION (PARTITION ', p_name,
' VALUES LESS THAN (TO_DAYS(''', p_date, ''')))');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLIPREPARE stmt;
END //
DELIMITER ;
定期归档旧数据:
-- 1. 创建归档表
CREATE TABLE orders_archive LIKE orders;
-- 2. 交换分区到归档表
ALTER TABLE orders EXCHANGE PARTITION p202201
WITH TABLE orders_archive;
-- 3. 可考虑将归档表迁移到低成本存储
利用分区裁剪:
-- 好的查询(能利用分区裁剪)
SELECT * FROM orders
WHERE order_date BETWEEN '2023-01-01' AND '2023-01-31';
-- 不好的查询(无法利用分区裁剪)
SELECT * FROM orders WHERE YEAR(order_date) = 2023;
跨分区查询处理:
-- 使用UNION ALL查询多个分区
SELECT * FROM orders PARTITION(p202301)
WHERE user_id = 1001
UNION ALL
SELECT * FROM orders PARTITION(p202302)
WHERE user_id = 1001;
SELECT partition_name, table_rows
FROM information_schema.partitions
WHERE table_name = 'orders';
-- 检查是否发生分区锁升级
SHOW STATUS LIKE 'innodb_row_lock%';
当单表数据超过5亿条或日增数据量极大时,可考虑: - 分库分表(如ShardingSphere) - 时序数据库(如InfluxDB)存储订单状态变更 - 数据分层存储(热数据MySQL,温数据TiDB,冷数据对象存储)
分区表在单实例MySQL中仍然是中等规模电商系统(日订单100万以下)的优选方案,因其实现简单且能有效解决大部分性能问题。