引言
分库分表是应对海量数据的重要方案。本文介绍分库分表的策略和实现。
一、分库分表策略
1.1 垂直拆分
1 2 3 4
| 用户库: users, user_profiles 订单库: orders, order_items 商品库: products, categories
|
1.2 水平拆分
1 2 3 4 5 6
| users_2022, users_2023
users_0, users_1, users_2, users_3
|
二、ShardingSphere
1 2 3 4 5 6 7
| spring.shardingsphere.datasource.names=ds0,ds1
spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes=ds$->{0..1}.t_order_$->{0..1} spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-column=order_id spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-algorithm-name=table-inline
|
三、分页查询优化
1 2 3 4 5 6 7 8 9
| SELECT * FROM users WHERE id > last_id LIMIT 10;
SELECT * FROM ( SELECT * FROM users_0 WHERE age > 18 UNION ALL SELECT * FROM users_1 WHERE age > 18 ) t ORDER BY id LIMIT 10;
|
四、全局ID生成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public class SnowflakeIdGenerator { private long workerId; private long sequence = 0L; private long lastTimestamp = -1L; public synchronized long nextId() { long timestamp = System.currentTimeMillis(); if (timestamp < lastTimestamp) { throw new RuntimeException("Clock moved backwards"); } if (timestamp == lastTimestamp) { sequence = (sequence + 1) & 4095; if (sequence == 0) { timestamp = tilNextMillis(lastTimestamp); } } else { sequence = 0L; } lastTimestamp = timestamp; return ((timestamp - 1288834974657L) << 22) | (workerId << 12) | sequence; } }
|
总结
分库分表核心:
- 拆分策略:垂直、水平拆分
- 路由规则:范围、哈希路由
- 全局ID:保证ID唯一性
- 分布式事务:保证数据一致性
参考资料