MySQL(182) 如何进行MySQL的分库分表?

MySQL的分库分表(Sharding)是一种将数据水平拆分为多个库和表的技术,以解决单个数据库性能瓶颈和存储限制。这种技术可以提高数据库的并发处理能力,分散数据存储负载。下面详细介绍如何进行MySQL的分库分表,并结合代码进行说明。

一、分库分表的策略

  1. 水平分表:将一张大表拆分为多张小表。
  2. 水平分库:将一个库的数据拆分到多个库中,每个库包含部分数据。
  3. 垂直分表:将一张大表按列拆分为多张小表(通常不涉及水平分库分表的讨论)。

二、分库分表的实现步骤

1. 设计分库分表策略

常见的分库分表策略有Hash分片、Range分片和List分片。以下以水平分库分表为例,采用Hash分片策略。

假设我们有一个用户表users,需要进行分库分表。

1.1 选择分片键

选择一个确定分片方法的字段,比如用户ID (user_id)。

1.2 确定分片规则

假设我们将数据拆分到4个库中,每个库包含4张表,总共16张表。分片规则可以是:

  • 库编号 = user_id % 4
  • 表编号 = user_id / 4 % 4
1.3 创建数据库和表
sql 复制代码
-- 创建4个数据库
CREATE DATABASE user_db_0;
CREATE DATABASE user_db_1;
CREATE DATABASE user_db_2;
CREATE DATABASE user_db_3;

-- 在每个数据库中创建4张用户表
USE user_db_0;
CREATE TABLE users_0 (user_id INT PRIMARY KEY, user_name VARCHAR(255), ...);
CREATE TABLE users_1 (user_id INT PRIMARY KEY, user_name VARCHAR(255), ...);
CREATE TABLE users_2 (user_id INT PRIMARY KEY, user_name VARCHAR(255), ...);
CREATE TABLE users_3 (user_id INT PRIMARY KEY, user_name VARCHAR(255), ...);

USE user_db_1;
CREATE TABLE users_0 (user_id INT PRIMARY KEY, user_name VARCHAR(255), ...);
CREATE TABLE users_1 (user_id INT PRIMARY KEY, user_name VARCHAR(255), ...);
CREATE TABLE users_2 (user_id INT PRIMARY KEY, user_name VARCHAR(255), ...);
CREATE TABLE users_3 (user_id INT PRIMARY KEY, user_name VARCHAR(255), ...);

-- 重复以上步骤在 user_db_2 和 user_db_3 中创建表

2. 实现数据的插入、查询和管理

2.1 插入数据

根据分片规则插入数据:

python 复制代码
def insert_user(user_id, user_name):
    db_index = user_id % 4
    table_index = (user_id // 4) % 4
    db_name = f"user_db_{db_index}"
    table_name = f"users_{table_index}"

    sql = f"INSERT INTO {db_name}.{table_name} (user_id, user_name) VALUES (%s, %s)"
    # 执行SQL插入操作(使用具体的数据库连接库,比如pymysql)
    cursor.execute(sql, (user_id, user_name))
    connection.commit()

# 示例插入
insert_user(123, 'John Doe')
2.2 查询数据

根据分片规则查询数据:

python 复制代码
def get_user(user_id):
    db_index = user_id % 4
    table_index = (user_id // 4) % 4
    db_name = f"user_db_{db_index}"
    table_name = f"users_{table_index}"

    sql = f"SELECT * FROM {db_name}.{table_name} WHERE user_id = %s"
    # 执行SQL查询操作
    cursor.execute(sql, (user_id,))
    result = cursor.fetchone()
    return result

# 示例查询
user = get_user(123)
print(user)

3. 使用中间件进行分库分表

手动管理分库分表较为复杂,通常使用中间件来简化分库分表的实现。常用的分库分表中间件包括ShardingSphere、Mycat和Vitess等。

3.1 使用ShardingSphere

ShardingSphere是一个开源的分布式数据库中间件,支持分库分表、读写分离和数据加密等功能。

3.1.1 安装ShardingSphere

下载并解压ShardingSphere Proxy:

bash 复制代码
wget https://archive.apache.org/dist/shardingsphere/5.0.0/apache-shardingsphere-5.0.0-shardingsphere-proxy-bin.tar.gz
tar xzf apache-shardingsphere-5.0.0-shardingsphere-proxy-bin.tar.gz
3.1.2 配置ShardingSphere

编辑conf/server.yamlconf/config-sharding.yaml文件。

server.yaml

yaml 复制代码
authentication:
  users:
    root:
      password: root
    sharding:
      password: sharding
props:
  max-connections-size-per-query: 1
  acceptor-size: 16  # The default value is available processors count * 2.
  executor-size: 16  # Infinite by default.
  proxy-frontend-flush-threshold: 128  # The default value is 128.
  proxy-transaction-type: LOCAL
  proxy-opentracing-enabled: false
  proxy-hint-enabled: false
  query-with-cipher-column: true
  sql-show: false
  check-table-metadata-enabled: false

config-sharding.yaml

yaml 复制代码
schemaName: sharding_db

dataSources:
  ds_0:
    url: jdbc:mysql://127.0.0.1:3306/user_db_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: root
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
  ds_1:
    url: jdbc:mysql://127.0.0.1:3306/user_db_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: root
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
  ds_2:
    url: jdbc:mysql://127.0.0.1:3306/user_db_2?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: root
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
  ds_3:
    url: jdbc:mysql://127.0.0.1:3306/user_db_3?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: root
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50

shardingRule:
  tables:
    users:
      actualDataNodes: ds_${0..3}.users_${0..3}
      tableStrategy:
        inline:
          shardingColumn: user_id
          algorithmExpression: users_${user_id % 4}
      keyGenerator:
        type: SNOWFLAKE
        column: user_id
  defaultDatabaseStrategy:
    inline:
      shardingColumn: user_id
      algorithmExpression: ds_${user_id % 4}
  defaultTableStrategy:
    none:
3.1.3 启动ShardingSphere
bash 复制代码
sh bin/start.sh

现在,您可以通过连接到ShardingSphere Proxy来进行数据库操作,而不需要手动管理分库分表逻辑:

python 复制代码
# 示例连接
import pymysql

connection = pymysql.connect(
    host='127.0.0.1',
    port=3307,  # ShardingSphere默认监听端口
    user='sharding',
    password='sharding',
    db='sharding_db'
)

cursor = connection.cursor()
cursor.execute("INSERT INTO users (user_id, user_name) VALUES (%s, %s)", (123, 'John Doe'))
connection.commit()

cursor.execute("SELECT * FROM users WHERE user_id = %s", (123,))
result = cursor.fetchone()
print(result)

三、总结

分库分表可以有效地解决单库性能瓶颈问题,提高数据库的扩展性和并发处理能力。我们通过手动分库分表和中间件(如ShardingSphere)两种方式进行了详细说明。

  1. 手动分库分表:适用于简单场景,但需要手动管理分片逻辑和数据分布。
  2. 中间件分库分表:如Sharding
相关推荐
程序猿DD7 分钟前
OctaFuse Gateway 2.9.0:用户限流控制、自定义转发头与管理后台升级
后端·api
三千星8 分钟前
Java开发者转型AI工程化Week 5:让RAG学会思考、看见与自检
后端
一个Ai的杂货铺11 分钟前
exit 0 也会撒谎:一个"绿灯盲跑"了一个月的定时任务,尸检报告
后端
北漂EDA码路12 分钟前
现代 C++20:move、forward 与完美转发,EDA 大型程序为什么离不开它
后端
泡海椒14 分钟前
JQuick-Java快速入门教程:轻量级规则引擎环境搭建与首个脚本运行实战
后端
stark张宇1 小时前
分布式事务最全图解(6种方案):从强一致的2PC到最终对账,彻底搞懂数据一致性
分布式·后端
IT毕设实战小研1 小时前
基于大数据的WTA职业网球赛事演变与竞技格局数据可视化分析
大数据·后端·爬虫·python·信息可视化·课程设计
IT_陈寒2 小时前
Java字符串判等踩坑记:==和equals真的不能乱用
前端·人工智能·后端
小马过河R2 小时前
微信小程序自定义登录态维护:从入门到生产级落地
后端·微信小程序·小程序·架构·登录态
计算机学姐2 小时前
基于SpringBoot的高校爱心慈善管理系统
java·vue.js·spring boot·后端·spring·tomcat·mybatis