web-dev-qa-db-ja.com

トランジェントAPIを使用するためのベストプラクティス

私が書いているプラ​​グインのパフォーマンスを向上させることを望んで、私は最近WordpressのトランジェントAPIに出くわしました。

基本的にプラグインはデータベースにAmazonの製品広告APIからの製品詳細を保存しています。製品の詳細は、配列のjsonエンコード表現を使用して保管されます。

管理者がデータベースレコードを削除するたびにトランジェントAPIを使用して更新するように、トランジェントAPIを使用しようとしています。

私が現在やっていることはset_transientメソッドを使ってjsonエンコード値を保存することです。このようなもの:

$data = array(
 '123' => "{'title' : '', 'price' : '', 'brand' : ''}"
 '456' => ...
);

$value = json_encode($data);
set_transient('Amazon_items', $value, 60 * 60);

そしてget_transientを使ってそこから取得します

$asin = '123';
$data = json_decode(get_transient('Amazon_items'), true);
print_r($data[$asin]);

json_decodeを使わずに直接アクセスできるようにしても大丈夫ですか、それとも配列形式で格納するだけですか?私のユースケースは受け入れ可能ですか、それはやりすぎですか?私はまだこれを改善することができますか?トランジェントAPIを使用して格納できるデータ量に特定の制限はありますか?この特定のユースケースでは、私はそれが50Mbを超えるデータであることを期待しています。

5
soul

これでよろしいですか、それとも配列形式で格納して、json_decodeを使用せずに直接アクセスできるようにする必要がありますか。

あなたの場合は 直接 を格納することはそれを格納することを意味します 直列化 $dataは配列であり、そのまま格納することはできませんが、文字列に変換されるためです。

あなたが直接それにアクセスするとしても:

$data = get_transient('Amazon_items');
print_r( $data[0] );

serialize php関数を使用するWP get_transient関数を使用して、set_transient関数 unserialize maybe_unserialze serialize のような)背後の値。

そのためjson_encode/json_decodeを使うか標準的なphp-serializeメソッドを使うことでいくつかの違いがありますが、パフォーマンスはほとんど同じです。テストをしたことのある人はjson_encodeのほうが少し速いと言っています。

あなたが選ばなければならない方法はあなたがデータをどう扱わなければならないかに依存します:もしあなたがjsで(あるいはphp以外の他の言語でも)それを操作するつもりならば、正しい選択はたぶんjsonです。

Phpオブジェクトをシリアライズする必要がある場合は、元のクラスを維持しながらphpシリアライゼーションを使用する必要があります。

$a = new MyClass;
$b = json_encode($a);
$c = json_decode($b);
$test = is_a($c, 'MyClass'); // false

$a = new MyClass;
$b = serialize($a);
$c = unserialize($b);
$test = is_a($c, 'MyClass'); // true

トランジェントAPIを使用して格納できるデータ量に特定の制限はありますか?

一時APIは{$wpdb->prefix}_optionsを使用してデータを保存します。このテーブルでは、データが格納されるoption_value列は、 理論的には4Gbのデータを含む _を含むことができるlongtext列です。実スペースがそれほど少なくても、50Mbが問題になることはないはずです(もちろん、サーバー内のdbスペースが十分に大きい場合)。

サイドノート

  1. 直列化されたデータ(jsonまたはphpによる違いはありません)を扱うときは、それらを利用するあらゆる種類のSQLクエリを実行することはほとんど不可能です。 "ほぼ" いくつかのLIKE %..%クエリがあります...
  2. シリアライゼーション/デシリアライゼーションのプロセスは、特にビッグデータの場合は、少しコストがかかります。そのため(実際には)便利ですが、この種の呼び出しはできるだけ頻繁に行わないようにし、可能であれば値が取得されたら、何らかの方法でキャッシュしてみてください。
7
gmazzap

私はトランジェントとして50メガ以上を保存することはありません。どういうわけかそれをファイルシステムに格納するか、データを格納するために私自身の特定のdbテーブルを作成することを検討します。

トランジェントをデータベースに格納している場合、それを取得するたびに、処理のためにDBからWebサーバーに送信される必要がある50メガバイトのデータです。それを保持するためにPHPに割り当てなければならないメモリは50メガです。などなど。あなたは毎回その全部で50メガを使っていますか?いいえ?それは無駄で愚かです。

データを分割します。それを1つの大きなBLOBとして扱うのではなく、代わりに独自のテーブルに格納するか、独自の投稿タイプとして格納するなどしてください。キーを使ってアクセスし、必要なものだけにアクセスしてください。あなたはスピード上の利点を見て、この方法で作業するためのより良いコードベースを持つでしょう。

9
Otto