3

単一の SQL ステートメントでブログ投稿にタグを追加したいと思います。

私のテーブルは次のようになります。

tags
+-------+-----------+
| tagid | tag       |
+-------+-----------+
|     1 | news      | 
|     2 | top-story | 
+-------+-----------+

tag2post
+----+--------+-------+
| id | postid | tagid |     
+----+--------+-------+
|  0 |    322 |     1 |
+----+--------+-------+

私が解決したい問題は、新しいタグを挿入し、そのIDを取得してから、この新しい ID を単一の SQL ステートメントでリレーション テーブルに挿入することです。

INSERT INTO tag2post (postid, tagid)
VALUES
(
    332, # the post
    IF (
        (SELECT tagid FROM tags WHERE tag = 'new_tag'),
        (SELECT tagid FROM tags WHERE tag = 'new_tag'),
         # here is where i'd like to insert 
         # the new_tag and return it's id
        'i am lost here'
    )
)
4

5 に答える 5

5

挿入はアトミックであるため、これを単一の挿入として実行することはできません。つまり、ID はステートメントが完了するまで決定されません。

両方のステートメントをトランザクションでラップすると、ID と原子性が得られます。

于 2009-01-26T15:06:52.613 に答える
1

私はあなたがそれを壊さなければならないと思います。UNIQUEこれを行う1つの方法は、制約を追加しtagて次のように進めることです。

INSERT IGNORE INTO tags (tag) VALUE ('new_tag')

その後

INSERT INTO tag2post (postid, tagid)
VALUES
(
    332, # the post
    (SELECT tagid FROM tags WHERE tag = 'new_tag')
)

INSERT IGNOREただし、スケーリングがうまくいかない場合があります。したがって、別の方法としてSELECT、IDがない場合は、INSERT別のスレッド/プロセス/サービスがあなたSELECTと現在の間のテーブルを変更した場合は、必ずここで例外をキャッチしてください。あなたがし、彼がINSERTあなたLAST_INSERT_ID()を捕まえると、最初のSELECT..を繰り返します。

素晴らしいことではありませんが、並行性が必要な場合は、これを行う必要があります。トランザクションによって問題が軽減されるわけではなく、にUNIQUE制約がない場合はtag、が重複する可能性がありますINSERT

于 2011-11-22T19:57:06.393 に答える
1

自動インクリメントID列を使用する代わりに、GUID列を使用してください。次に、ステートメントを実行する前にGUIDを生成し、すべてを一度に実行できます。

Jeff Atwoodでさえこのアプローチが好きで、整数の代わりに32文字の文字列を使用しても速度が大幅に低下することはありません。

また、タグの重複を防ぐために、タグ名のMD5合計をタグIDとして使用する必要があります。

于 2009-01-26T15:13:41.883 に答える
0

これを試して、選択できない場合は効果的に挿入を実行し、挿入された行からLAST_INSERT_ID()を取得することもできますが、うまくいくかどうかは非常に疑わしいです。

INSERT INTO tag2post (postid, tagid)
VALUES
(
    332, # the post
    IF (
        (SELECT tagid FROM tags WHERE tag = 'new_tag'),
        (SELECT tagid FROM tags WHERE tag = 'new_tag'),
        IF (
            (INSERT INTO tags (tag) VALUES ('new_tag')),
            LAST_INSERT_ID(),
            LAST_INSERT_ID()
        )
    )
)
于 2009-01-26T15:13:29.730 に答える
0

非自動増分フィールドを使用して独自の増分計算を行う場合は、フィールドを挿入する前にIDを決定し、新しいIDを手動で指定できます。

次に、; sで区切られたこれらのIDを使用して、tag2postエントリごとにステートメントの文字列を作成し、それをmsyqlに送信して実行できます。

于 2009-01-26T15:14:05.643 に答える