MySQL データベースの最適化: テーブルとデータベースのシャーディング操作の詳細な説明

MySQL データベースの最適化: テーブルとデータベースのシャーディング操作の詳細な説明

この記事では、例を使用して、MySQL データベースの最適化のためのテーブルおよびデータベース シャーディング操作について説明します。ご参考までに、詳細は以下の通りです。

サブテーブルとサブデータベース

垂直分割

垂直分割とは、モジュールに応じてテーブルを異なるデータベース テーブルに分割することです (もちろん、原則として第 3 正規形を破壊しません)。この種の分割は、大規模な Web サイトの進化において非常に一般的です。ウェブサイトがまだ非常に小さい場合、開発と保守を行う人数は少なく、すべてのモジュールとテーブルが一緒になっています。ウェブサイトが充実して成長するにつれて、複数のサブシステムによってサポートされるようになります。このとき、モジュールと機能に応じてテーブルを分割する必要があります。実は、垂直分割と比較すると、サービス指向の変革は一歩進んでいます。簡単に言えば、元の強く結合したシステムを複数の弱く結合したサービスに分割し、サービス間の呼び出しを通じてビジネスニーズを満たすことです。したがって、テーブルを分割した後は、異なるモジュールのテーブルを直接呼び出すのではなく、サービスの形で公開する必要があります。タオバオのアーキテクチャの継続的な進化の中で最も重要なのは、サービス指向の変革です。ユーザー、トランザクション、ストア、製品などのコアコンセプトを独立したサービスに抽出することは、ローカル最適化とガバナンスにも非常に役立ち、コアモジュールの安定性を確保します。垂直分割は、分散シナリオで使用されます。

水平分割

上記の垂直分割は、テーブルをモジュールごとに異なるデータベースに分割するだけであり、単一のテーブルに大量のデータがあるという問題は解決されません。水平分割は、特定のルールに従って、テーブルのデータを異なるテーブルまたはデータベースに分割することです。たとえば、課金システムでは、システムが一定期間内にデータを処理するため、テーブルを時間で分割する方が適切です。 SaaS アプリケーションの場合、ユーザーは互いに分離されており、通常、複数のユーザー データを処理する必要がないため、ユーザー ディメンションでデータを分割する方が適切です。user_id 範囲で水平に分割するだけです。簡単に言うと、行を水平に分割し、行データを異なるテーブルに分割し、列を垂直に分割し、テーブル データを異なるテーブルに分割します。

スプリットホライズンの例

アイデア: 大規模な電子商取引システムでは、メンバーの数は毎日増加し続けています。特定のボトルネックに到達した後にクエリを最適化する方法。
インデックスについて考えるかもしれません。ユーザー数が数億人に達したらどうなるでしょうか? どのように最適化すればよいでしょうか?
水平パーティション分割を使用してデータベース テーブルを分割します。

水平分割データベースの使い方

ビジネス ニーズに応じて、登録時間、抽選、アカウント ルール、年などに基づいてテーブルを分割するには、水平パーティションを使用します。

タッチ方式でテーブルを分割する

まず、user0 / user1 / user2 の 3 つのテーブルを作成し、次に自動増分 ID を提供するために使用される uuid テーブルを作成します。

テーブルuser0を作成(
id int 符号なし主キー、
名前 varchar(32) nullでないデフォルト ''
pwd varchar(32) NULLでないデフォルト '')
エンジン=myisam 文字セット utf8;
テーブルuser1を作成します(
id int 符号なし主キー、
名前 varchar(32) nullでないデフォルト ''
pwd varchar(32) NULLでないデフォルト '')
エンジン=myisam 文字セット utf8;
テーブルuser2を作成します(
id int 符号なし主キー、
名前 varchar(32) nullでないデフォルト ''
pwd varchar(32) NULLでないデフォルト '')
エンジン=myisam 文字セット utf8;
テーブルuuidを作成(
id int 符号なし主キー auto_increment)engine=myisam charset utf8;

デモプロジェクトを作成する

POM ファイル

    <親>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <バージョン>1.3.3.RELEASE</バージョン>
    </親>
    <依存関係>
        <依存関係>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </依存関係>
        <依存関係>
            <groupId>org.springframework.boot</groupId>
            <artifactId>スプリングブートスターター</artifactId>
        </依存関係>
        <依存関係>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>テスト</scope>
        </依存関係>
        <依存関係>
            <グループID>mysql</グループID>
            <artifactId>mysql-コネクタ-java</artifactId>
        </依存関係>
        <依存関係>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </依存関係>
    </依存関係>

サービスコード

@サービス
パブリッククラスUserService{
    オートワイヤード
    プライベート JdbcTemplate jdbcTemplate;
    パブリック文字列regit(文字列名、文字列パスワード) {
        // 1. まずカスタム成長IDを取得する
        文字列 idInsertSQL = "uuid VALUES (NULL) に INSERT INTO";
        jdbcTemplate.update(idInsertSQL);
        Long insertId = jdbcTemplate.queryForObject("last_insert_id() を選択する", Long.class);
        // 2. ストレージテーブル名を決定します。String tableName = "user" + insertId % 3;
        // 3. 登録データ String insertUserSql = "INSERT INTO " + tableName + " VALUES ('" + insertId + "','" + name + "','" + pwd
                + "');";
        System.out.println("insertUserSql:" + insertUserSql);
        jdbcTemplate.update(ユーザーSQLの挿入);
        「成功」を返します。
    }
    パブリック文字列 get(Long id) {
        文字列 tableName = "user" + id % 3;
        文字列 sql = "select name from " + tableName + " where id="+id;
        System.out.println("SQL:" + sql);
        文字列名 = jdbcTemplate.queryForObject(sql, String.class);
        名前を返します。
    }
}

コントローラ

@レストコントローラ
パブリッククラスUserController{
    オートワイヤード
    プライベート UserService userService;
    @RequestMapping("/regit")
    パブリック文字列regit(文字列名、文字列パスワード) {
        userService.regit(名前、パスワード) を返します。
    }
    @リクエストマッピング("/get")
    パブリック文字列 get(Long id) {
        文字列名 = userService.get(id);
        名前を返します。
    }
}

MySQL 関連のコンテンツに興味のある読者は、このサイトの次のトピックをチェックしてください: 「MySQL クエリ スキル」、「MySQL 共通関数の概要」、「MySQL ログ操作スキル」、「MySQL トランザクション操作スキルの概要」、「MySQL ストアド プロシージャ スキル」、および「MySQL データベース ロック関連スキルの概要」

この記事が皆様のMySQLデータベース設計に役立つことを願っています。

以下もご興味があるかもしれません:
  • MySQLデータベース最適化技術の簡単な紹介
  • MYSQLデータベースの最適化段階を簡単に理解する
  • MySQL データベースの最適化: インデックスの実装原則と使用状況の分析
  • MySQL データベースを最適化する 8 つの方法の詳細な説明 (必読の定番)
  • MySQLスタンドアロンデータベースの最適化のいくつかの実践
  • MySQLデータベース最適化技術とインデックス使用スキルの概要
  • MySQLデータベース最適化技術の構成手法の概要
  • 運用と保守の観点から見た MySQL データベースの最適化についての簡単な説明 (Li Zhenliang)
  • MySQL データベースの最適化の詳細
  • MySQL データベースの最適化に関する 9 つのヒント

<<:  jQuery はラブエフェクトをクリックする

>>:  JavaScript Canvas で三目並べゲームを実装

推薦する

CentOS 8/RHEL 8 に Cockpit をインストールして使用する方法

Cockpit は、CentOS および RHEL システムで使用できる Web ベースのサーバー管...

Linux ディスクのシーケンシャル書き込みとランダム書き込みの方法

1. はじめに● ランダム書き込みではヘッドがトラックを頻繁に変更するため、効率が大幅に低下します。...

Vue3 ドラッグ可能な左パネルと右パネルの分割コンポーネントの実装

目次コンポーネントの分解左パネル右パネル入力パラメータの分解小道具スロット具体的な実装ドラッグする方...

Vue での ref の使用法とデモンストレーション

ref 定義:要素またはサブコンポーネントの参照情報を登録するために使用されます。参照情報は、親コン...

Mysqlがデータベースに接続するときのホストとユーザーのマッチングルールについての簡単な説明

--データベースに接続するとき、ホストとユーザーのマッチングルール公式ドキュメント: https:/...

WeChatミニプログラムビデオ集中砲火位置ランダム

この記事では、WeChatミニプログラムのビデオ弾幕の位置をランダム化するための具体的なコードを紹介...

VMwareを使用したPermeateレンジシステムのインストール手順の詳細説明

1. 背景私たちは時々社内研修を行っており、実験環境をよく利用しています。最初はdockerコンテナ...

デザイン理論: デザインにおける階層

<br />原文: http://andymao.com/andy/post/80.ht...

MySQLトリガーの使用

目次1. トリガーの紹介1. トリガーとは何ですか? 2. トリガーの特徴2. トリガーを作成する1...

サーバーの購入と初期構築方法

しばらくサーバーいじってなかったけど、やることがなくなったのでモバイルワークスに行って海外サーバーを...

CSS で実現される HTML 背景色のグラデーション

エフェクトのスクリーンショット:実装コード:コードをコピーコードは次のとおりです。 <!DOC...

Zabbix設定 DingTalkアラーム機能実装コード

必要Zabbix で DingTalk アラームを設定する方法は、Prometheus で Ding...

HTML に FLASH へのリンクを追加し、すべての主要ブラウザと互換性を持たせる方法

まずコードを見てみましょうコードをコピーコードは次のとおりです。 <div style=&qu...

Web コンポーネントの内部イベント コールバックと問題点の分析

目次前面に書かれたWC とは何でしょうか?現在の欠陥1. コンポーネント内部イベントのコールバック2...

MySQLのSQLモードの特徴のまとめ

序文SQL モードは、MySQL がサポートする SQL 構文と、実行されるデータ検証チェックに影響...