ようこそ!浜村拓夫の世界へ

    ブログ内検索

    最近の記事

    ブックマーク数の多い記事

    Blog Translation

    Powered By FC2ブログ

    Powered By FC2ブログ
    ブログやるならFC2ブログ


    FC2ブログ LOGIN

    with Ajax Amazon

    CodeIgniterで「INSERT IGNORE」を使う方法

    このエントリーを含むはてなブックマーク はてなブックマーク - CodeIgniterで「INSERT IGNORE」を使う方法 あとで読む
    CodeIgniterActive Record クラスにあるメソッドで、使いたい機能が用意されていませんでした。


    ●データ挿入のSQL発行
    ・「INSERT INTO」 → $this->db->insert() を使えばOK。
    ・「INSERT IGNORE INTO」 → 対応するメソッドがありません。

    どうすればいいか調べたら、便利な方法が紹介されていました。

    [CodeIgniter] INSERT IGNORE INTOを使う | きほんのき

    $data = array( 'column_name' => 'value' );
    $insert_query = $this->db->insert_string('table_name', $data );
    $insert_query = str_replace('INSERT INTO','INSERT IGNORE INTO',$insert_query);
    $this->db->query($insert_query);


    $this->db->insert_string()を使ってSQL文を生成し、その後INSERTをINSERT IGNOREに置換するというやり方です。



    これでうまくできました!

    いや~、便利、便利!


    ●INSERT IGNOREの欠点
    ただし、「INSERT IGNORE」には、欠点?もあって、使い方には注意が必要です。

    新たなデータをINSERTしようとして、キーに重複があったら、IGNORE(無視)して、INSERTを中止してくれるけど、
    auto_incrementのカラム(「id」とか)だけは、勝手にガンガン増えていきます。

    ・IGNOREした分だけ、idに欠番ができる。
    ・idが、連番じゃないと困る場合は、INSERT IGNOREは不向き?

    id欠番の解決方法は、
    (1) そもそも、INSERT IGNOREを使わない(笑)
    (2) 欠番の修正=ときどき、auto_incrementなidを、バッチ処理で連番に直す。
    (3) innodb_autoinc_lock_mode = 0 に変更してから、INSERT IGNOREを使う。
    とか?

    (参考)InnoDBでのINSERT IGNOREとAUTO_INCREMENT | mutter

    InnoDBでINSERT IGNOREを繰り返してたら、レコード数は増えてないのに、AUTO_INCREMENTだけがガンガン増えててびっくり。おかげでidの値が飛んでる。

    なんなんだろうと思ったらこれ、MySQL 5.1.22以降の仕様なんですね。



    現在あるテーブルでAUTO_INCREMENTを無駄に増やさないようにしたい場合には、以下の変更を行う必要があります。

    MySQL :: MySQL 5.1 リファレンスマニュアル (オンラインヘルプ) :: 9.4.3.2 設定可能な InnoDB 自動インクリメントロック
    InnoDB は実際に挿入が試みられる前に自動インクリメント値を割り当てるため、挿入する値が既存の値と重複しているかどうかを知ることができず、したがって自身が生成する自動インクリメント値が新しい行で使用されるかどうかを知ることができません。したがって、ステートメントベースのレプリケーションを使用する場合には、INSERT ... ON DUPLICATE KEY UPDATE を使用しないようにするか、あるいは innodb_autoinc_lock_mode = 0 (「従来」 ロックモード) を使用する必要があります。



    「従来」 ロックモードを利用する方法は次の内のどちらか。
    ・ 「--innodb_autoinc_lock_mode=0」オプションを付けて起動
    ・ my.cnfのmysqldディレクティブに「innodb_autoinc_lock_mode=0」と記述



    なるほど、MySQLの仕様と。

    プログラムで連番を振り直す場合は、トランザクション処理で、書き換え中は、新たなデータが追加されないようにしておく必要があるでしょう。

    テーブルが単体で使われている場合は、欠番が生じても、見た目が美しくないだけで、実質的な問題はないかもしれないけど、
    他のテーブルとリレーションがある場合は、連番じゃないと不都合な場合もあるかな?



    CodeIgniter徹底入門
    河合 勝彦
    翔泳社
    2008-06-10
    3990円
    関連記事

    コメント

    コメントの投稿


    管理者にだけ表示を許可する

    トラックバック

    トラックバックURL:
    http://hamamuratakuo.blog61.fc2.com/tb.php/962-a5f86ec3

    FC2Ad