分库分表(四)

真实互联网公司常见的订单分库分表架构设计。这个设计基本是很多大厂(电商、外卖、支付系统)使用的模式。🚀

我会从 设计目标 → 分片键选择 → 分库分表结构 → 表结构设计 → 查询优化 → 扩容方案 一步一步讲。


一、订单系统的真实规模

假设一个电商系统:

指标 数量
每天订单 1000万
每年订单 36亿
订单表数据 几十亿

如果只有一张表:

复制代码

order

问题:

  • 表太大(几十亿行)

  • 索引巨大

  • 查询慢

  • MySQL 扛不住

所以必须:

复制代码

分库 + 分表


二、常见分库分表结构

典型架构:

复制代码

Application

ShardingSphere

┌───────────┼───────────┐

│ │ │

DB0 DB1 DB2 DB3

order_0..7 order_0..7 order_0..7 order_0..7

总表数量:

复制代码

4库 × 8表 = 32张订单表

逻辑表:

复制代码

order

真实表:

复制代码

db0.order_0

db0.order_1

...

db3.order_7


三、为什么订单要按 user_id 分片(重点)

很多人第一反应:

复制代码

按 order_id 分片

大厂基本不会这样做

原因:

1 用户订单查询最多

用户最常见操作:

复制代码

查看我的订单

SQL:

复制代码

SELECT * FROM order WHERE user_id = ?

如果按 user_id 分片:

复制代码

user_id % 32

只查:

复制代码

1张表

如果按 order_id 分片:

复制代码

必须扫描32张表

性能很差。


2 用户订单列表

例如:

复制代码

用户订单列表

SQL:

复制代码

SELECT * FROM order

WHERE user_id = 1001

ORDER BY create_time DESC

LIMIT 10

按 user_id 分片:

复制代码

只查一个表

速度极快。


四、分片算法设计

假设:

复制代码

4库

8表

总分片数:

复制代码

32

算法:

复制代码

dbIndex = user_id % 4

tableIndex = user_id % 8

最终表:

复制代码

db{dbIndex}.order_{tableIndex}

例子:

复制代码

user_id = 1001

计算:

复制代码

1001 % 4 = 1

1001 % 8 = 1

路由:

复制代码

db1.order_1


五、ShardingSphere 配置示例

复制代码

spring:

shardingsphere:

datasource:

names: ds0,ds1,ds2,ds3

rules:

sharding:

tables:

order:

actual-data-nodes: ds-\>{0..3}.order_->{0..7}

database-strategy:

standard:

sharding-column: user_id

sharding-algorithm-name: db_inline

table-strategy:

standard:

sharding-column: user_id

sharding-algorithm-name: order_inline

sharding-algorithms:

db_inline:

type: INLINE

props:

algorithm-expression: ds$->{user_id % 4}

order_inline:

type: INLINE

props:

algorithm-expression: order_$->{user_id % 8}


六、订单表真实结构(非常重要)

互联网订单表一般不会只存 ID。

典型结构:

复制代码

CREATE TABLE order_0 (

id BIGINT PRIMARY KEY,

user_id BIGINT,

user_name VARCHAR(64),

shop_id BIGINT,

shop_name VARCHAR(128),

product_id BIGINT,

product_name VARCHAR(128),

price DECIMAL(10,2),

status INT,

create_time DATETIME

);

注意:

复制代码

user_name

shop_name

product_name

这些都是:

复制代码

冗余字段

原因:

避免 JOIN。


七、订单系统为什么大量冗余字段

如果不冗余:

复制代码

SELECT *

FROM order o

JOIN user u

JOIN product p

在分库环境:

复制代码

非常慢

互联网解决方案:

复制代码

订单快照

订单生成时:

复制代码

复制用户信息

复制商品信息

所以订单表里会有:

复制代码

buyer_name

buyer_phone

product_name

shop_name

好处:

复制代码

订单查询无需 join


八、订单表必须有的索引

订单系统最常见查询:

1 用户订单

复制代码

WHERE user_id

索引:

复制代码

(user_id, create_time)


2 单个订单

复制代码

WHERE id

主键:

复制代码

id


3 商家订单

复制代码

WHERE shop_id

索引:

复制代码

(shop_id, create_time)


九、主键生成(雪花算法)

订单 ID 不用自增。

因为:

复制代码

分库后无法自增

一般用:

复制代码

Snowflake

64位ID:

复制代码

时间戳 + 机器ID + 序列号

ShardingSphere 自带:

复制代码

key-generators:

snowflake:

type: SNOWFLAKE

优点:

复制代码

全局唯一

高性能


十、历史订单如何处理

订单表会越来越大。

解决方案:

复制代码

冷热数据分离

例如:

复制代码

order_hot (最近3个月)

order_hist (历史订单)

查询:

复制代码

最近订单 → hot

历史订单 → hist


十一、未来扩容问题

假设:

复制代码

32表

不够用了。

扩容:

复制代码

32 → 64

问题:

复制代码

旧数据怎么办?

解决:

复制代码

一致性哈希

双写迁移

很多公司用:

复制代码

ShardingSphere Scaling

在线迁移数据。


十二、完整订单系统架构

真实架构:

复制代码

API

Order Service

ShardingSphere

┌───────────┼───────────┐

│ │ │

DB0 DB1 DB2

order_0..7 order_0..7 order_0..7

配合:

复制代码

Redis 订单缓存

Kafka 订单消息

ES 订单搜索


十三、真实互联网订单查询流程

用户打开订单列表:

复制代码

APP

API

OrderService

ShardingSphere

db1.order_3

只查:

复制代码

1张表

速度:

复制代码

毫秒级


十四、总结(核心设计)

互联网订单系统核心设计:

1 分片键

复制代码

user_id

原因:

复制代码

用户查询最多


2 分库分表

复制代码

4库 × 8表


3 冗余字段

避免:

复制代码

跨库 join


4 雪花ID

保证:

复制代码

全局唯一


十五、一个真正的架构经验(非常重要)

很多新系统一开始:

复制代码

只建一张 order 表

等数据上亿:

复制代码

再拆分

这会非常痛苦。

正确方式:

复制代码

一开始就设计分库分表

即使:

复制代码

只有几万数据

相关推荐
zklgin2 小时前
【MySQL】深度学习数据库开发技术:使用CC++语言访问数据库
数据库·mysql·数据库开发
2401_889884662 小时前
使用Pandas进行数据分析:从数据清洗到可视化
jvm·数据库·python
李宥小哥2 小时前
SQLite04-表数据管理
java·jvm·数据库
Smoothcloud_润云2 小时前
GORM 事务管理与 Repository 模式完整指南
前端·数据库·代码规范
aq55356002 小时前
SQL 注入漏洞原理以及修复方法
网络·数据库·sql
七夜zippoe2 小时前
PostgreSQL高级特性在Python中的实战:JSONB、全文搜索、物化视图与分区表深度解析
数据库·python·postgresql·性能优化·分区表
七七powerful2 小时前
养龙虾--codebuddy调用mysql-mcp-server 查询MySQL
服务器·数据库·mysql·mcp
@insist1232 小时前
软件设计师-E-R 模型核心原理与应用指南
数据库·oracle·软考·软件设计师·软件水平考试
Insist7533 小时前
Kingbase--单机部署完整流程
运维·数据库