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
相关推荐
一 乐6 小时前
婚纱摄影网站|基于ssm + vue婚纱摄影网站系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·spring boot·后端
码事漫谈7 小时前
Protocol Buffers 编码原理深度解析
后端
码事漫谈7 小时前
gRPC源码剖析:高性能RPC的实现原理与工程实践
后端
踏浪无痕8 小时前
AI 时代架构师如何有效成长?
人工智能·后端·架构
程序员小假9 小时前
我们来说一下无锁队列 Disruptor 的原理
java·后端
武子康10 小时前
大数据-209 深度理解逻辑回归(Logistic Regression)与梯度下降优化算法
大数据·后端·机器学习
maozexijr10 小时前
Rabbit MQ中@Exchange(durable = “true“) 和 @Queue(durable = “true“) 有什么区别
开发语言·后端·ruby
源码获取_wx:Fegn089510 小时前
基于 vue智慧养老院系统
开发语言·前端·javascript·vue.js·spring boot·后端·课程设计
独断万古他化10 小时前
【Spring 核心: IoC&DI】从原理到注解使用、注入方式全攻略
java·后端·spring·java-ee
毕设源码_郑学姐10 小时前
计算机毕业设计springboot基于HTML5的酒店预订管理系统 基于Spring Boot框架的HTML5酒店预订管理平台设计与实现 HTML5与Spring Boot技术驱动的酒店预订管理系统开
spring boot·后端·课程设计