MySQLにおけるデータベースとテーブルの分割手法

データ分割の必要性

大規模データ処理において、以下の問題が発生した場合に分割が必要となります:

  • データ量の膨大化
  • クエリ性能の低下(20msから指数関数的な増加)
  • データベース接続数の不足

分割手法の分類

データベースとテーブルの分割には垂直分割と水平分割の2種類があります。

データベース分割

  • 垂直分割:機能単位での分割(例:ユーザー、注文、商品データベース)
  • 水平分割:単一データベースの複数インスタンス化(例:User_DB_0 ~ User_DB_n)

テーブル分割

  • 垂直分割:使用頻度の低い列を別テーブルに分離
  • 水平分割:単一テーブルを複数テーブルに分割(例:User_Table_0 ~ User_Table_n)

適用シナリオ

テーブル分割が必要な場合

テーブルサイズが過大になったとき(ディスクファイルサイズの増大)

データベース分割が必要な場合

接続数不足が発生したとき(例:MySQLの最大接続数4000に対し、40ノード×10接続×10サービス=4000接続)

両方の分割が必要な場合

  • 高負荷の書き込み/読み取り環境
  • 超大規模データセット

ShardingSphereによる実装

Sharding-JDBCを使用した分割実装例:

依存関係の追加

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-core</artifactId>
    <version>5.3.2</version>
</dependency>

分割ルール定義

spring:
  datasource:
    driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
    url: jdbc:shardingsphere:classpath:sharding-config.yaml

設定ファイル例 (sharding-config.yaml)

dataSources:
  primary_ds:
    dataSourceClassName: com.zaxxer.hikari.HikariDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    jdbcUrl: jdbc:mysql://localhost:3306/core_db?serverTimezone=Asia/Tokyo
    username: admin
    password: secure_pass

rules:
  - !SHARDING
    tables:
      customer_data:
        actualDataNodes: primary_ds.customer_${0..9}
        tableStrategy:
          standard:
            shardingColumn: client_id
            shardingAlgorithmName: client_hash_mod
    shardingAlgorithms:
      client_hash_mod:
        type: MOD
        props:
          sharding-count: 10
props:
  sql-show: true

分割キーの選択

分割キーの選択には以下の要素を考慮:

  • アクセス頻度の分布
  • データ均等分散の必要性
  • キー値の不変性

ShardingSphereの基本概念

論理テーブル

分割された物理テーブルを抽象化した論理的な名称

物理テーブル

実際に存在する分割後のテーブル実体

タグ: MySQL ShardingSphere データベース設計 水平分割 垂直分割

6月18日 21:43 投稿