1

ORM 構文で記述したコードがあります。blogsファイルからブログ コメント データを読み取り、commentsテーブルに挿入します。できるだけ多くのクエリを 1 つのクエリに結合する必要があり、この最適化は ORM 言語では簡単ではないため、この ORM コードを mysql に戻したいと考えています。この最適化が必要な理由は、リモート サーバーで作業しているためです。したがって、クエリが少ないほど良いのです。以下のコードは mysql 疑似コードで書きました。

これは、すべてのブログのすべてのコメントを含むコメント ファイルです。from blog urlこのコメントがどのブログに属しているかを教えてくれます。

comment text               from blog url
------------------------------------------
first comment text         first-blog-url
second comment text        first-blog-url
third comment text         first-blog-url
fourth comment text        blog-2-url
fifth comment text         blog-2-url
sixth comment text         3rd-blog-url

これは、ファイルの処理に使用する ORM コードです。(一番下に、テーブルの説明を追加しました)。

//I read a comment from the comments file, `comment text` and `from blog url`

//does a blog exist that has 'link' that matches 'from blog url'
$blog = //SELECT FROM blogs where 'link' has value 'first-blog-url'

//if it doesn't exist, create it
if($blog == null){
    $blog = INSERT INTO blogs a new record and set 'link' to 'first-blog-url'
}

//then read the id of the (existing or just-created) blog row
$blog_id = $blog->getId();

//then use the $blog_id to insert the comment into the 'comments' table.

//does this comment text already exist for this blog id?
$comment = SELECT FROM comments where `commenttext' has value 'whatever comment text' and 'blogid' has value $blog_id

//if it doesn't exist, create it
if($comment == null){
    $comment = INSERT INTO comments a new record and set 'commenttext' to 'the comment text' and 'blogid' to $blog_id.
}

$comment_id = $comment->getId();

だから私の質問: これを単一の mysql クエリで書くことは可能ですか?

私はここで同様の質問を見つけましたが、それは私の問題を完全には解決しません.それが最も効率的な方法であるかどうかはわかりません.

2 つのテーブルはblogsであり、 のcomments各行にはの右側のブログにリンクcommentsするフィールドがあります。したがって、基本的には、各行を多くの行にリンクできる1 対多の関係です。それらは次のようになります。blogidblogsblogcomment

blogs:

id        link                  other fields
--------------------------------------------
1         first-blog-url
2         blog-2-url
3         3rd-blog-url

comments:

id        commenttext     blogid
-----------------------------
1         random          1
2         comment         1
3         goes            1
4         here            2
5         any             2 
6         thing           3
4

1 に答える 1

3

行が存在しない場合は、この手法を使用して行を挿入できます。

INSERT INTO blogs (link)
select 'first-blog-url' 
from dual
where not exists
( select 1
  from blogs
  where  link = 'first-blog-url'
);

ご覧のとおり、select 句は、データベースにまだ存在しない場合にのみ挿入されるデータを含む 1 つの行のみを返します。SQLFIDDLE でテストできます。

テーブルに挿入するにcommentは、同じ手法を使用できます。挿入が予定されている場合は、 LAST_INSERT_ID()Blog idを使用して 2 番目のクエリを取得できます(そうでない場合は、新しいクエリが必要です)。

これは開始点にすぎません。おそらく、4 つのクエリを 3 つに減らすことができます。最終的な解決策を見つけるために、どんなコメントでも大歓迎です。

ご存知のように、MySQL には MERGE ステートメントがありません。その交換はあなたの要求と一致しないと思います。

于 2012-08-25T18:38:11.827 に答える