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
相关推荐
程序员爱钓鱼24 分钟前
Rust 开发环境安装(Windows|macOS|Linux)
后端·rust
爱勇宝9 小时前
第 1 章:别把“需求文档”当成真正的需求
前端·后端·程序员
IT_陈寒13 小时前
闭包陷阱让我加了两天班,JavaScript你真行
前端·人工智能·后端
易协同低代码14 小时前
通达OA核心类库TD类深度解析
后端
Gopher_HBo14 小时前
Go语言学习笔记(十八)Gin处理Session
后端
谭光志15 小时前
工具塞满上下文窗口怎么办?深度拆解 AI Agent Tool Search 按需加载实现原理
前端·后端·ai编程
她说..15 小时前
Java 默认值设置方式
java·开发语言·后端·springboot
foggyprojects15 小时前
从0开始,一句话启动AI DataAgent
后端·数据分析·ai编程
郡杰15 小时前
一些基础和问题解决
后端
陈随易16 小时前
前端项目部署只要30秒
前端·后端·程序员