最近、Youzan をベースにしたマルチレベルの配信管理システムに取り組んでいます。すべてのメンバーの店舗は Youzan モールにあり、パフォーマンスを取得するために Youzan の API を使用しています。しかし、Youzan は 1 つのレベルの配信しか提供していないため、このシステムを作成しました。ワークロードを軽減し、階層関係を明確にするために、データベースとテーブルを基本クラス、配布メンバー、ストアフロント、その他の継承テーブルにカプセル化する OOP 設計手法が採用されました。
ただし、販売レポートとディストリビュータをリストするときに重大なパフォーマンスの問題が発生しました。ディストリビュータのパフォーマンス報酬はその下位のディストリビュータにリンクされているため、データベースをカプセル化するときに、すべてのディストリビュータの結果を取得するために DFS トラバーサルが実行されました。ただし、売上レポートをリストする場合、DFS は PHP 言語に多くの時間を費やすため、ページを開くのに 10 秒以上かかるため、最初のステップとして DFS スイッチを設定して最適化します。データベースのカプセル化関数内:
これは Database クラスの部分的な実装であり、一部の機密データが隠されています。
<?php namespace System; require_once('KdtApiClient.php'); class Database { const db_adr=""; const db_usr=""; const db_pwd=""; const db_db=""; public $member=array(); public function init($dfs=true,$store=true) { $mysqli=new \mysqli(self::db_adr,self::db_usr,self::db_pwd,self::db_db); if($mysqli->connect_error) throw new Exception('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error); $result=$mysqli->query("select `id` from member_new"); $row=$result->fetch_array(); $i=0; while($row) { $this->member[$i]=new Member($row[0],$dfs,$store); $row=$result->fetch_array(); $i++; } $mysqli->close(); } static public function doQuery($string) { $mysqli=new \mysqli(self::db_adr,self::db_usr,self::db_pwd,self::db_db); if($mysqli->connect_error) throw new Exception('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error); return $mysqli->query($string); } static public function querySell($start,$end) {} }
class Table { public $data=array(); protected $table_name; public function __construct($id) { $this->data['id']=$id; $mysqli=new \mysqli(Database::db_adr,Database::db_usr,Database::db_pwd,Database::db_db); if($mysqli->connect_error) throw new Exception('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error); $result=$mysqli->query("select * from ".$this->table_name." where `id`=$id"); $row=$result->fetch_assoc(); $this->data=$row; $mysqli->close(); } public function updateAll() //Do NOT CHANGE ID!!! { reset($this->data); while($data=each($this->data)) { $querystring="update ".$this->table_name." set `".$data[0]."`='$data[1]' where `id`='".$this->data['id']."'"; Database::doQuery($querystring); } reset($this->data); } public function update($key) { $querystring="update ".$this->table_name." set `$key`='".$this->data[$key]."' where `id`='".$this->data['id']."'"; Database::doQuery($querystring); } public function set($key,$data) //recommended { $this->data[$key]=$data; $this->update($key); } public function get($key) //recommended { return $this->data[$key]; } }
class Member extends Table { protected $table_name="member_new"; public $infer=array(); public $store=array(); public function __construct($id,$dfs=true,$store=true) { parent::__construct($id); $mysqli=new \mysqli(Database::db_adr,Database::db_usr,Database::db_pwd,Database::db_db); if($mysqli->connect_error) throw new Exception('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error); if($dfs){ $result=$mysqli->query("select `id` from ".$this->table_name." where `super`=".$this->data['id']); if($result){ $row=$result->fetch_array(); $i=0; while($row) { $this->infer[$i]=new Member($row[0]); $row=$result->fetch_array(); $i++; } } } if($store) { $result=$mysqli->query("select `id` from store_new where `member`=".$this->data['id']); if($result){ $row=$result->fetch_array(); $i=0; while($row) { $this->store[$i]=new Store($row[0]); $row=$result->fetch_array(); $i++; } } } $mysqli->close(); }
さらに、フロントエンドに応答する PHP スクリプトにキャッシュのサポートが追加されますAJAX は、Youzan の API 呼び出し速度が遅いため、ただし、この種の配信モールのデータはリアルタイム性の要件がそれほど高くないため、Youzan との通信による速度の低下を軽減するためにサーバー キャッシュが使用されます。ローカライズされたオブジェクトは、リモート データベースからの読み取り情報を置き換え、データベースへのクエリのコストも削減します。 Cache オブジェクトの実装は次のとおりで、オブジェクトのシリアル化コードをサーバー上にローカルに保存します。 AJAX 応答ページは、Cache クラスのフィードバックに基づいてローカル データを取得するか、サーバーの更新を要求するかを選択します。 ローカル データ:
<?php namespace System; class Cache { public function __construct() { } static public function readCache($string) { error_reporting(1); $file=fopen($string.".ser","r"); if(!$file)return false; $ser=fread($file,filesize($string.".ser")); fclose($file); $array=array(); $array=unserialize($ser); if(time()-$array['time']>3600*24)return false; return $array['data']; } static public function updateCache($string,$data) { $array=array(); $array['time']=time(); $array['data']=$data; $file=fopen($string.".ser","w"); fwrite($file,serialize($array)); fclose($file); } }
著作権声明: この記事はブロガーによるオリジナルの記事であり、ブロガーの許可なく複製することはできません。
上記では、サードパーティ API データ取得システムをドッキングしたマルチレベルのディストリビューションの最適化について、内容の側面も含めて紹介しました。PHP チュートリアルに興味のある友人の参考になれば幸いです。