MySQL 分库分表:什么时候需要,怎么设计?

MySQL 分库分表:什么时候需要,怎么设计? MySQL 的单机能力并不是无限的。 当数据规模、并发请求和存储需求持续增长时,即使已经完成索引优化、SQL 优化、缓存、连接池和读写分离,单个 MySQL 实例仍然可能成为系统瓶颈。 这时候才需要考虑一个更重的方案: 分库分表(Sharding)。 分库分表本质上是把原来集中在一个数据库中的数据和请求拆开,让多个数据库实例共同承担存储和访问压力。 但需要注意: 分库分表解决的是容量和并发扩展问题,并不会自动让每一条 SQL 都变快。 而且一旦进入分库分表阶段,原本简单的 SQL、事务、分页、JOIN、统计查询都会变得更加复杂。 因此,分库分表最重要的不是“怎么拆”,而是什么时候拆,以及按照什么规则拆。 1. 为什么需要分库分表 假设有一张订单表: CREATE TABLE orders ( id BIGINT PRIMARY KEY, user_id BIGINT NOT NULL, status TINYINT NOT NULL, amount DECIMAL(12, 2) NOT NULL, created_at DATETIME NOT NULL, KEY idx_user_id (user_id), KEY idx_created_at (created_at) ); 随着业务增长,这张表可能达到数亿甚至更大的数据量。 问题可能来自几个方面。 单表数据量过大 表越来越大以后: 索引越来越大; Buffer Pool 缓存命中率下降; 查询和更新涉及更多磁盘 I/O; 索引维护成本增加; ALTER TABLE 等运维操作更加困难; 备份、恢复时间增加。 即使查询本身使用了正确的索引,大表带来的资源压力仍然存在。 单实例并发能力有限 一个 MySQL 实例需要同时承担:...

2024年09月11日 · 5 min · Leanku

MySQL分库分表(无中间件)

MySQL分库分表(无中间件) 一、 分库分表方案设计 1. 垂直拆分 (按业务模块) -- 原始单体数据库 CREATE DATABASE ecommerce; USE ecommerce; -- 垂直拆分后的数据库 -- 用户库 CREATE DATABASE user_center; USE user_center; CREATE TABLE users ( user_id BIGINT PRIMARY KEY, username VARCHAR(50) UNIQUE, email VARCHAR(100) UNIQUE, password VARCHAR(100), mobile VARCHAR(20), status TINYINT DEFAULT 1, created_at DATETIME, updated_at DATETIME ); CREATE TABLE user_profiles ( user_id BIGINT PRIMARY KEY, real_name VARCHAR(50), avatar VARCHAR(200), gender TINYINT, birthday DATE, bio TEXT ); CREATE TABLE user_address ( address_id BIGINT PRIMARY KEY, user_id BIGINT, province VARCHAR(50), city VARCHAR(50), district VARCHAR(50), detail VARCHAR(200), is_default TINYINT DEFAULT 0, INDEX idx_user_id (user_id) ); -- 订单库 CREATE DATABASE order_center; USE order_center; CREATE TABLE orders ( order_id BIGINT PRIMARY KEY, user_id BIGINT, total_amount DECIMAL(10,2), status TINYINT, payment_status TINYINT, created_at DATETIME, paid_at DATETIME ); CREATE TABLE order_items ( item_id BIGINT PRIMARY KEY, order_id BIGINT, product_id BIGINT, product_name VARCHAR(100), price DECIMAL(10,2), quantity INT, INDEX idx_order_id (order_id) ); -- 商品库 CREATE DATABASE product_center; USE product_center; CREATE TABLE products ( product_id BIGINT PRIMARY KEY, name VARCHAR(100), category_id INT, price DECIMAL(10,2), stock INT, status TINYINT, created_at DATETIME ); CREATE TABLE categories ( category_id INT PRIMARY KEY, name VARCHAR(50), parent_id INT ); 2....

2024年04月23日 · 11 min · Leanku