![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
No.4ベストアンサー
- 回答日時:
>御説明が足りずに失礼しました。
てっきり文脈から読み取って頂けるものとばかり思っておりました。いえ、こちらのほうこそ申し訳ないです。データベース周りのことについて、言葉をあまりに知らなさすぎて、回答者が質問者に余計な手間をかけさせてしまっているようでは話になりません。
とりあえず、色々あさっていたところ、
http://www.doctrine-project.org/blog/doctrine2-b …
こちらのエントリの一番したの「UPDATE」の箇所に、サポートしていない旨とその理由が掲載されていました。
Yahoo翻訳で、そこそこ読める翻訳が出来たのでそのまま転記します。
-------------------------------------
まず第一に、この構文は、mysqlとより新しいpostgresql版で支えられるだけです。第2に、AUTO_INCREMENTまたはSERIALとORMを使うことが識別子を物のアイデンティティ管理のために必要とするとき、そのようなマルチ挿入物ですべての発生する識別子をつかむ簡単な方法がありません。最後に、挿入パフォーマンスは、めったにORMのボトルネックでありません。大部分の状況のために十分に速いより、通常の挿入物は多くです、そして、あなたが本当に速い大きさ挿入物をしたいならば、マルチ挿入物はいずれにしろ最高の方法でありません、すなわち、Postgres COPYまたはMysql LOAD DATA INFILEは数桁より速いです。
--------------------------------------
結局ORMは複数のデータベースで実装されているSQL文を抽象化していることを考えると文自体のサポートの幅が少なければ、対応しないような方向のようですね。
Oracleでもマルチテーブルインサートとかあるようですし、SQL Server2008でもマルチインサートの構文がかけるようではありますが。
また、せっかくなので、CakePHPが独自で実装しているORMの、saveAllメソッドも試してみましたが、ログを見ると、複数のInsert文が流れているようでした。
やはり、SQL文を直接叩いて対応するのが近道なのではないかと思います。
MySQL/Postgres/SQL Server2008の間であれば、記法も同じようですし。
詳細な説明を求めておいて、ろくな回答できなくて、本当にすみません。
とんでもありません。丁寧な御回答、本当に感謝しています。
出来ないということが明確にわかっただけで収穫です。ありがとうございました。同時に自分の事前調査不足にも幾分反省しています。
このマニュアルではボトルネックではないと自信をもって断言していますが、1000件程度の同時Insertですらパフォーマンスに大きな差が出ます。また、LOAD DATA INFILE等ではあまりに柔軟性に欠けるので、話になりませんね。この自信はどこから来るのか…
とはいえ、マルチインサートに対応していないDBMSが存在することを考えると、確かに仕方ないのかもしれませんね。現行ORMの限界といったところでしょうか。とりあえずhogehoge78様のおかげでネイティブSQLが叩けることもわかったので、Doctrineのコードを読んで、saveメソッドをフックできるように改変してみたいと思います。
本当にありがとうございました。
No.3
- 回答日時:
となると、複数行Insertとはいったいどういうものをさしているのでしょう。
>配列フィールドを持つオブジェクトを永続化する際
コレについても良くわからないのですが、Array型のフィールドを有するテーブルに対して、Insertを行いたいということでしょうか。
もしそうであれば、MySQLはそもそもArray型をサポートしておりません。(一応Doctrineも見てみましたがArray型は正しくサポートしていないようです)
それとも、「複数行をまとめてInsertしたい」の複数行というのは、何か全然違う解釈のものでしたか?
この回答への補足
御説明が足りずに失礼しました。てっきり文脈から読み取って頂けるものとばかり思っておりました。
複数行Insertとは以下のようなものです。
http://dev.mysql.com/doc/refman/5.1/ja/insert.htmlより
==============================
VALUES 構文を利用する INSERT ステートメントは複数行を挿入する事ができます。これをする為には、それぞれが括弧で囲まれカンマで区切られている、カラム値の複数リストを含んでください。例:
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
==============================
これにより、(1,2,3)と(4,5,6)と(7,8,9)の3行を挿入するのに必要なSQL発行回数が1回で済みます。SQL発行回数の減少はディスクへのランダムアクセス回数の減少に繋がりますので、結果として全体のパフォーマンスが向上します。
>配列フィールドを持つオブジェクトを永続化する際
クラスAの配列をフィールドとして持つクラスBのsave()メソッドを叩いた時、ということです。
この際、大概のORMでは(もしくは適切な設定によって)BのインスタンスのフィールドであるAの配列の永続化も自動的に行われますが、Doctrineの場合ですと要素ごとに1件のSQLが発行されてしまいます。
上記の例で言えば
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3);
INSERT INTO tbl_name (a,b,c) VALUES(4,5,6);
INSERT INTO tbl_name (a,b,c) VALUES(7,8,9);
ということですね。
※「配列の永続化」とは、Array型?を用いた永続化ではなく、外部キーによって結合されているテーブルへの永続化を指しています。
この複数件のSQLを、先程の複数行同時InsertSQLに自動的にパックするような機能や設定方法はないか?もしくはクラスBの特定のフィールドだけ永続化処理をハックできるような方法はないか?というのが本質門の主旨でした。
宜しくお願い致します。
No.2
- 回答日時:
となると、ある程度コストがかかってしまいますが、
<?php
//一回目
$insert = new Hoge();
$insert->name = 'aaa';
$insert->date = time();
$insert->save();
//二回目
$insert = new Hoge(); //ここでインスタンス作り直し
$insert->name = 'bbb';
$insert->date = time();
$insert->save();
?>
と、一行インサートを行うたびにインスタンスを作り直すという作業は必要かもしれませんね。
実際マニュアルでも2回インサート処理をしているコードのサンプルがありましたが、そのようにしていたようです。
No.1
- 回答日時:
Doctrine使ったことないですが、
多少複雑なことを行うのであれば、他のORマッパーでもそうですが、直接SQLを叩いたほうがよさそうですが、いかがでしょうか。
Doctrine_Managerのconnectionメソッドが返すDoctrine_Connectionクラスには、prepareメソッドがありますので、
$stmt = $conn->prepare("INSERT INTO hoge (a, b, c) VALUES (?, ?, ?)");
$stmt->execute(array(1, 2, 3));
といった感じで。
御回答ありがとうございます。
やはりネイティブSQLを叩けるインターフェースがあったんですね。調査不足でした、すみません。
しかしDoctorine_Record::saveメソッドで安直に永続化できないとなると、ORMを使う意味がどんどん薄れていきますね…コレクション周りを工夫すれば割と簡単に実現できそうなものですが。。(自分で実装する気は起きない)
複数行Insertを実現できるPHPのORMをもし御存知でしたら、御教示下さい。
宜しくお願い致します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PostgreSQL SQLでUPSERTを一度に複数行やる方法 3 2022/03/25 15:17
- PHP プログラムコードを入力する場合改行してもいいですか? 2 2022/10/02 16:05
- MySQL #1062 - '0' は索引 'PRIMARY' で重複しています。とでています。 1 2023/01/01 06:13
- MySQL 下の画像はSQLの4大命令の性質をまとめたものであるらしいです UPDATE INSERT DELE 1 2023/06/07 15:36
- MySQL 次の時間帯の勝率の合計を求めるSQL文 1 2023/07/04 17:12
- Visual Basic(VBA) 列 A に同じ日が2つが必要です。 1 2023/03/28 07:25
- PHP php エラー 3 2022/11/18 23:32
- Excel(エクセル) 表に書いてある単語を1つの行に重複させないで書き出したい。 複数の列行にそれぞれ職種が入力されている 6 2022/05/25 04:49
- MySQL mysqlで INSERT と SELECTの用途は 1 2022/04/01 00:45
- Access(アクセス) access,vbaでフォルダ内のファイルをテーブルにインポート、ファイル名もフィールドに追加したい 1 2022/08/31 11:11
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
phpのheader("Location:#pos")...
-
PHPからCSVをアップロード後、m...
-
PHPで入力フォームでデータを確...
-
phpでcookieがうまく保存されない
-
フォームで戻った際に入力済み...
-
[php初心者]サイトを見てデータ...
-
PHP8を使うと、大量のWarningが...
-
ワードプレスサイト PHP8.0.25...
-
プログラミング言語で、使える...
-
phpのクラスメソッドの定義が長...
-
アマゾンのような評価の星を選...
-
ファイルアップロードに関して...
-
掲示板のセキュリティについて...
-
Q&Aサイトを作成していてURLの...
-
アップロード画像数でCSSを分け...
-
PHP一覧表示した項目にリンクを...
-
PHPのセッション有効期限について
-
php 確認表示画面で値をSESSION...
-
php 完了画面の送信メールのコ...
-
PHPで訪問回数を表示するカウン...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
配列をループでたくさん宣言し...
-
$_SESSIONに二次元配列を使える...
-
file_existsでファイル名の部分...
-
String だと「 ByRef引数の型が...
-
foreachのなかで次のキーを参照...
-
配列を回すとき、最後の要素だ...
-
PHPのカッコ[ ]の使い方について
-
PHPのPOSTでの半角スペース
-
セッション配列の取得の仕方
-
PHPにてクラスを配列にすること...
-
配列一致(要素順番は違うが内容...
-
PHP 多次元配列変数のデータ受...
-
漢字のソートについて
-
unset使用時の利点
-
OCI で、SELECT結果行数を取得...
-
postgresql関数をつかったレコ...
-
配列をmysqlに保存
-
あいまい検索
-
チェックボックス複数選択 mys...
-
総当り表
おすすめ情報