ホームページ >PHPフレームワーク >ThinkPHP >ThinkPHP6 でデータベースの水平サブデータベース操作を実行するにはどうすればよいですか?

ThinkPHP6 でデータベースの水平サブデータベース操作を実行するにはどうすればよいですか?

WBOY
WBOYオリジナル
2023-06-12 11:39:161990ブラウズ

ビジネス規模の拡大に伴い、データベースで処理する必要のあるデータ量も増加しており、単一のデータベースでは逼迫しています。現時点では、データベースの水平サブデータベース操作を実行してデータを異なるデータベースに分散し、それによってシステムのパフォーマンスとスケーラビリティを向上させる必要があります。この記事では、ThinkPHP6 でデータベースの水平シャーディング操作を実行する方法を紹介します。

1. データベース水平サブデータベースとは何ですか?

データベースの水平シャーディングは、1 つのデータベース内のデータを複数のデータベースに分散するプロセスです。特定のルール (ユーザー ID や期間など) に従ってデータを異なるデータベースに分割することで、単一データベースへの負荷を軽減できます。同時に、データ量が多い場合、水平シャーディングによりクエリ効率が向上し、データのセキュリティが強化されます。

2. ThinkPHP6 での水平サブライブラリの実装

ThinkPHP6 では、データベースミドルウェアを使用して水平サブライブラリを実装できます。 ThinkPHP6 の MySQL 接続にデータベースミドルウェアを配置し、サブデータベースを制御します。

  1. Thinkswoole のインストール

ThinkPHP6 では、データベースミドルウェアとして Thinkswoole が使用されています。プロジェクトに Thinkswoole をインストールする必要があります。

ThinkSwoole のバージョン情報をcomposer.json ファイルに追加し、composer を使用してインストールします。

  1. データベース構成を変更する

まず config/database.php ファイルを見つけて、MySQL 接続を Swoole 接続に置き換えます。元の MySQL 接続情報をコメントアウトします:

// 'mysql' => [
    //     // 默认数据连接标识
    //     'default' => env('database.driver', 'mysql'),
    //     // 数据库连接信息
    //     'connections' => [
    //         'mysql' => [
    //             // 数据库类型
    //             'type' => 'mysql',
    //             // 主机地址
    //             'host' => env('database.hostname', '127.0.0.1'),
    //             // 数据库名
    //             'database' => env('database.database', ''),
    //             // 用户名
    //             'username' => env('database.username', 'root'),
    //             // 密码
    //             'password' => env('database.password', ''),
    //             // 端口
    //             'hostport' => env('database.hostport', '3306'),
    //             // 数据库连接参数
    //             'params' => [],
    //             // 数据库编码默认采用utf8
    //             'charset' => 'utf8',
    //             // 数据库表前缀
    //             'prefix' => env('database.prefix', ''),
    //             // 数据库调试模式
    //             'debug' => env('database.debug', true),
    //             // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
    //             'deploy' => 0,
    //             // 数据库读写是否分离 主从式有效
    //             'rw_separate' => false,
    //             // 读写分离后 主服务器数量
    //             'master_num' => 1,
    //             // 指定从服务器序号
    //             'slave_no' => '',
    //             // 是否严格检查字段是否存在
    //             'fields_strict' => true,
    //             // 数据集返回类型
    //             'resultset_type' => 'array',
    //             // 自动写入时间戳字段
    //             'auto_timestamp' => false,
    //             // 时间字段取出后的默认时间格式
    //             'datetime_format' => false,
    //             // Builder类
    //             'builder' => '',
    //             // Query类
    //             'query' => '\think\db\Query',
    //             // 是否需要进行SQL性能分析
    //             'sql_explain' => false,
    //         ],
    //     ],
    // ],

Swoole 接続情報を追加します:

 // swoole
    'swoole' => [
        // 默认数据连接标识
        'default' => 'swoole',
        // 数据库连接信息
        'connections' => [
            'swoole' => [
                // 数据库类型
                'type' => 'mysql',
                // 服务器地址
                'hostname' => [
                    '127.0.0.1:3305',
                    '127.0.0.1:3306',
                ],
                // 数据库名
                'database' => 'test',
                // 用户名
                'username' => 'root',
                // 密码
                'password' => '',
                // 端口
                'hostport' => '',
                // 数据库连接参数
                'params' => [],
                // 数据库编码默认采用utf8mb4
                'charset' => 'utf8mb4',
                // 数据库表前缀
                'prefix' => '',
                // 数据库调试模式
                'debug' => true,
                // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
                'deploy' => 0,
                // 数据库读写是否分离 主从式有效
                'rw_separate' => false,
                // 读写分离后 主服务器数量
                'master_num' => 1,
                // 指定从服务器序号
                'slave_no' => '',
                // 自动写入时间戳字段
                'auto_timestamp' => false,
                // 时间字段取出后的默认时间格式
                'datetime_format' => 'Y-m-d H:i:s',
                // Builder类
                'builder' => '',
                // Query类
                'query' => '\think\db\Query',
                // 是否需要进行SQL性能分析
                'sql_explain' => false,
            ],
        ],
    ],

上記のコードでは、2 つのサーバー アドレス (127.0.0.1:3305 と 127.0.0.1:3306 ) を定義しました。 , これは複数のデータノードのサブライブラリを実装するためです。データベース名、ユーザー名、パスワードなどの情報は変更されません。

  1. データベース ミドルウェアの作成

Db.php のデータベース ミドルウェアを app/middleware ディレクトリに作成し、次のコードを追加します:

<?php
namespace appmiddleware;

use thinkRequest;
use thinkContainer;

class Db
{
    public function handle(Request $request, Closure $next)
    {
        $serverIds = $this->getServerIds($request);
        //定义一个连接池
        $conns = [];
        foreach($serverIds as $sid) {
            $sid = $request->$sid;
            if(empty($conns[$sid])) {
                $conns[$sid] = Container::getInstance()
                                         ->make('db')->connect($sid);
            }
        }
        Container::getInstance()->bind('db', function() use ($conns) {
            return $conns;
        });
        return $next($request);
    }

    protected function getServerIds(Request $request)
    {
        return ['uid'];
    }
}

ここに作成Db というミドルウェアが作成されます。 handle メソッドでは、まず現在のリクエストのサーバー ID 配列を取得します。次に、これらのサーバー アドレスを接続プール $cons 内の既存のアドレスと比較し、存在しない場合は接続プールに追加します。最後に、接続プール $conns をコンテナー インスタンスにバインドします。 getServerIds メソッドでは、サーバー ID の名前を設定できます。デフォルトは uid です。

  1. ミドルウェアの登録

次のコードを config/middleware.php に追加します:

return [
    ...
    appmiddlewareDb::class,
];

このコードはミドルウェアの登録に使用されます。Db ミドルウェアを追加しました。ミドルウェア実行アクティビティのリストに追加します。

  1. サブライブラリ操作の実装

次に、モデルに水平サブライブラリ操作を実装します。ユーザーテーブルを例にとると、ユーザー ID はデータベースの制限として 100,000 と 100,000 に分割されます。これは、ユーザー ID が 0 から 100,000 までのデータがデータベースに格納されることを意味し、ユーザー ID が一致するまで続きます。 10 番目のデータベースには 90 万から 100 万件のデータが格納されます。

<?php
namespace appmodel;

use thinkModel;

class User extends Model
{
    protected $connection = [
        1 => 'user_1',
        2 => 'user_2',
        3 => 'user_3',
        4 => 'user_4',
        5 => 'user_5',
        6 => 'user_6',
        7 => 'user_7',
        8 => 'user_8',
        9 => 'user_9',
        10 => 'user_10',
    ];

    protected $pk = 'uid';

    public function getTableName(): string
    {
        $id = ceil($this->id / 100000);
        return $this->connection[$id] . '.' . $this->table;
    }
}

ここでは 10 個のデータベース接続を定義します。各接続はデータベース シャードを表し、水平シャーディングの目的を達成します。次に、現在のモデルに対応するデータ テーブル名を取得する getTableName メソッドを定義します。モデル内の主キー ID 値に基づいてアクセスする必要があるデータベース接続を計算し、データベース接続とデータ テーブル名の組み合わせを返します。

概要:

この記事では、ThinkPHP6 の水平サブライブラリ操作を紹介します。ビジネスが拡大し続け、データの規模が増大するにつれて、水平シャーディングによってシステムのパフォーマンスと拡張性が向上し、データのセキュリティも強化されます。 ThinkPHP6 では、Thinkswoole ミドルウェアおよびその他のメソッドを使用して、水平サブライブラリ操作を実装できます。

以上がThinkPHP6 でデータベースの水平サブデータベース操作を実行するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。