ビジネス規模の拡大に伴い、データベースで処理する必要のあるデータ量も増加しており、単一のデータベースでは逼迫しています。現時点では、データベースの水平サブデータベース操作を実行してデータを異なるデータベースに分散し、それによってシステムのパフォーマンスとスケーラビリティを向上させる必要があります。この記事では、ThinkPHP6 でデータベースの水平シャーディング操作を実行する方法を紹介します。
1. データベース水平サブデータベースとは何ですか?
データベースの水平シャーディングは、1 つのデータベース内のデータを複数のデータベースに分散するプロセスです。特定のルール (ユーザー ID や期間など) に従ってデータを異なるデータベースに分割することで、単一データベースへの負荷を軽減できます。同時に、データ量が多い場合、水平シャーディングによりクエリ効率が向上し、データのセキュリティが強化されます。
2. ThinkPHP6 での水平サブライブラリの実装
ThinkPHP6 では、データベースミドルウェアを使用して水平サブライブラリを実装できます。 ThinkPHP6 の MySQL 接続にデータベースミドルウェアを配置し、サブデータベースを制御します。
ThinkPHP6 では、データベースミドルウェアとして Thinkswoole が使用されています。プロジェクトに Thinkswoole をインストールする必要があります。
ThinkSwoole のバージョン情報をcomposer.json ファイルに追加し、composer を使用してインストールします。
まず 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 ) を定義しました。 , これは複数のデータノードのサブライブラリを実装するためです。データベース名、ユーザー名、パスワードなどの情報は変更されません。
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 です。
次のコードを config/middleware.php に追加します:
return [ ... appmiddlewareDb::class, ];
このコードはミドルウェアの登録に使用されます。Db ミドルウェアを追加しました。ミドルウェア実行アクティビティのリストに追加します。
次に、モデルに水平サブライブラリ操作を実装します。ユーザーテーブルを例にとると、ユーザー 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 サイトの他の関連記事を参照してください。