タグ: データベース

  • Custom Options Plus Post In バージョンアップ

    このたび、CUSTOM OPTIONS PLUS POST IN のバージョンアップをおこないました。

    最新バージョンは、1.2となります。
    主にデータベース周りの格納方法の更新を行いました。

     

    一度シリアライズしたデータを格納、取り出す際はシリアライズし、
    ひとつのデータを取り出す形式について、おそらく処理を指摘されていたので変更しました。

     

    今まで

    wp_options 内に、キー coppi として格納

    coppi1.2以前の格納方法
    coppi1.2以前の格納方法

     

    現在

    テーブルを用意した格納方法

     

    coppiテーブル
    coppiテーブル
    データ格納サンプル
    データ格納サンプル

    update_option 及び get_optionを使わずに、テーブルを用意するので、そもそも、

    どうやってやるんだろう。。と色々思考錯誤しましたが、下記の記事に感謝です。

     

    Creating_Tables_with_Plugins

    http://codex.wordpress.org/Creating_Tables_with_Plugins

    ■ WordPressでデータベースを使ったプラグインを作成する

    http://takahashifumiki.com/web/programing/1440/

     

    テーブルを用意することでのメリットは、まずは ソート がかなり楽になりました。
    今まではget_option全データをとにかく取得し、指定されたソートの順序になるようarray_multisortを行っていたのですが、sqlクエリとして投げるだけなので、返ってきたデータがソート済み。

    次に、一つのデータを取り出すのも楽になりました。

     

    プラグインが有効化された際に、テーブルを作成し、元のデータを取得しそこに複製された時は、
    おぉーってなりましたねw

     

    ただ、sqlクエリを直接書くことになるので、脆弱性が気になります。
    (sqlに限った事じゃないですが)

    試していて、よく分からなかった 「$wpdb->prepare」。

    wordpress 3.4.2 のバージョンでテスト動作を繰り替えし、動作確認をして、
    いざ wordpress 3.5 で動作をすると、

    Warning: Missing argument 2 for wpdb::prepare()

    が連発。んん??どういうエラーなんだろうと色々とぐぐってみました。

    $wpdb->prepare() 自体の動作は、SQL インジェクション攻撃からクエリを保護する によると、
    クエリを保護するためにエスケープするためのもの。らしいのですが、こんな記事もありました。

    Warning: Missing argument 2 for wpdb::prepare()は危険!

    正しい使い方をしないと、危ないよ。という事らしいです。

    3.4ではエラーも出ないのか。。そもそも使い方を間違っていたと。

    この記事の下のほうまで読んでいくと、akismetプラグインの場合の記述リンクがあったので見てみると、

     $remaining = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->commentmeta WHERE meta_key = 'akismet_error'" ) );

    $remaining = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->commentmeta WHERE meta_key = 'akismet_error'" );

    こうなっていました。

    $wpdb->prepare を外したんですね。

    今回はakismetプラグインを参考にして、$wpdb->prepare を外すと動作OK。3.4.2で試しもてもOK。

    とりあえず、今回はこれでよしとして、アップデートしました。

     

    こういう面を色々と考えると、難しいです。
    出来る限り、使えるテーブルは使ったほうが、ありがたい。のかも。

     

    ダウンロードはこちら http://wordpress.org/extend/plugins/custom-options-plus-post-in/

  • データベースへのオーバーヘッドを試してみた

    ひとつのキーに、まとめてデータを入れるとオーバーヘッドがかかるかもしれないよ」

    と教えられ、現在ひとつのキーに入れないような設計をしている最中で、

     

    じゃあ、試しに、1,000の値 を、

    • ひとつのキーに全データをシリアライズして入れる
    • 1,000のキーとして入れる

    というそれぞれの方法では、実際にどれだけオーバーヘッドの可能性があるかどうか。

     

    ターゲットは wp_options

    オーバーヘッドは一切ありません。

    テーブル一覧
    テーブル一覧

    ここで挿入する値の定義

    1,000個の1~10,000,000の乱数を作成して挿入

    つまり、

    array(
    0 => 2384、093,
    1 => 6923230,
    2 => 8053892,
    ...
    999 => 1034544
    );

    のようなデータです。

    データには日本語や英文が入る場合が多いので、今回はデータ量が少ない気がして、

    良いテストかどうかと聞かれれば、分かりません。としか答えられませんが、

    少しぐらいは何か分かるのではないかと思い、やってみることにしました。

     

    wp_options にまずは、ひとつのキーに1,000の配列を挿入することを仮定して、試してみました。

    $SampleData = array();
     for( $i=0; $i<1000; $i++ ) {
     $SampleData[$i] = rand( 1 , 1000000 );
     }
     print_r($SampleData);

    print_r で値を確認。1,000の配列が出来ています。

    これを、wp_optionsへひとつのキーとして、シリアライズしたデータをupdate_optionで挿入してみると、

    ひとつのキーに挿入
    ひとつのキーに挿入

    ぎっしりはいりました。結果…

    オーバーヘッドはなし。

     

    えっ? これじゃ検証にならない。。もっとデータ量を増やして試してみよう。

    ということで、オーバーヘッドされるまで、データ量を増やしながら色々と試行錯誤…。

    結果。どんなに頑張ってもオーバーヘッドしなかった。。

     

    参ったなぁ。指摘されているから、オーバーヘッドするはずなんだけど…

    実際にオーバーヘッドしているテーブルがあったので、そのテーブルとひたすらにらめっこ。

    すると、気づきました…。

    データ型
    データ型

    MyISAM

    ん?「MyISAM」?私のイサム?メルティーラブ??

    軽めにググってみました。

     

    あ、データベースにも色々とデータの種類があるのね。全く知りませんでした。

    で、さっそくテスト環境に使っているテーブルの型を、MyISAMに変更。

    同じように1,000個の値を持つ乱数配列で再度update_optionでデータを挿入すると…

    でました。オーバーヘッド。

    ひとつのキーに挿入時
    ひとつのキーに挿入時

    ひとつのキーに、1,000個の、乱数で作成された値をもつ配列を、シリアライズして挿入すると、

    29.5 KiB (KiBって何?キロバイトじゃなくて?)

    計10回、挿入してみましたが、 29.5 KiBから変わらなかったです。

    なるほど。何度も値を挿入しても、値は変わらないのか。配列の値も色々と変えてみる。

     

    ここまでで分かったこと

    × 1回のオーバーヘッド量 29.5 KiB × 10回updateすると = 295KiB になるわけではなく、

    ○ 挿入するデータ量に応じて、オーバーヘッドのサイズが変わる。何度更新しても。

     

    そっか。

    これじゃあ何度テーブルの最適化をしても、そのupdateをする限りいつまでもオーバーヘッドするじゃないか。

     

    よし。

    次の検証にうつります。その前に、オーバーヘッドの最適化。

     

    次は、1,000のキーとして、値を挿入。の検証

    挿入するデータは以下。

     for( $i=0; $i<1000; $i++ ) {
     update_option( 'sampledata' . $i , rand( 1 , 1000000 ) );
     }

    結果は。オーバーヘッドなし

    確かにこの方法がいいかもしれない。

    ん?ちょっとここでもうひとつ試してみることにしました。

     

    update_optionの値を、ただの配列にするとどうなるか

     for( $i=0; $i<1000; $i++ ) {
     update_option( 'sampledata' . $i , array( rand( 1 , 1000000 ) ) );
     }

    結果はこちら。

    値を配列に変更後
    値を配列に変更後

    20 バイト。配列にするだけで、オーバーヘッドが起こるのか。

     

    wordpress の update_option()の流れとしては(ざっくり)、

    • update_option() の値に配列やオブジェクトをつっこむ
    • maybe_serialize()という処理が入る

    この”たぶん、シリアライズ機能”のほうで、

    if ( is_array( $data ) || is_object( $data ) )
     return serialize( $data );

    シリアライズされたデータを返し、データベースのデータが更新されます。

     

     

    じゃあ、配列でupdate_optionデータを更新する限り、シリアライズされる。

    シリアライズされたデータで、 データベースの型が MyISAM なら、ほぼオーバーヘッドが起こる。

    (データベースの環境も左右されるかもしれませんね)

     

    いい勉強になりました。

    オーバーヘッドを避ける為には、1キーに1つの値。

    という事ですね。

     

    今公開中のプラグインは、ほとんどがシリアライズされたデータなので、いくつかは変更する予定です。

    >>追記

    実際には、1キー に 1つの値 にしても、オーバーヘッドを避ける事はできませんでした。

    どういう事かというと…

    作成したキーを、削除するだけでもオーバーヘッドが出ました。

    また、コメントでbloger323さんがおっしゃる通り、データの増減が激しい場合もオーバーヘッドが出るようです。

     

    うーん、どういう構造がいいんでしょうね。。