3

そもそも行が存在するかどうかに基づいて、更新または挿入を照会する簡単な方法を探しています。現在、Python の MySQLdb を使用しようとしています。これがクエリの実行方法です。

self.cursor.execute("""UPDATE `inventory`
                          SET `quantity` = `quantity`+{1}
                        WHERE `item_number` = {0}
                    """.format(item_number,quantity));

これを達成するための 4 つの方法を見てきました。

  1. 重複キー。残念ながら、主キーはすでに一意の ID として使用されているため、これを使用することはできません。

  2. 交換。上記と同じように、適切に機能するには主キーに依存していると思います。

  3. mysql_affected_rows(). 通常、行を更新した後にこれを使用して、影響があったかどうかを確認できます。Python の MySQLdb がこの機能をサポートしているとは思えません。

  4. もちろん、最後の努力: SELECT クエリを作成し、fetchall を実行してから、結果に基づいて更新または挿入します。基本的に、クエリを最小限に抑えようとしているだけなので、1 つではなく 2 つのクエリは今のところ理想的ではありません。

基本的に、オプション 4 を使用する前に、これを達成する他の方法を見逃していないかどうか疑問に思っています。お時間をいただきありがとうございます。

4

1 に答える 1

2

Mysqlは一意のインデックスを持つことができ、INSERT ... ON DUPLICATE UPDATEは、PKだけでなく、一意のインデックスに重複がある場合に更新を実行します。

しかし、私はおそらく「2つのクエリ」アプローチを採用するでしょう。あなたはトランザクションでこれをやっていますよね?

  1. 更新を行う
  2. 影響を受ける行を確認し、0の場合は、挿入を実行します

また

  1. 挿入を試みます
  2. 一意のインデックス違反が原因で失敗した場合は、更新を実行します(注:エラーコードをチェックして、他の理由で失敗しなかったことを確認する必要があります)

前者は、行が通常すでに存在する場合は適切ですが、トランザクションの外部で実行したり、分離モードが十分に高くない場合は、競合(またはデッドロック)状態を引き起こす可能性があります。

在庫テーブルのitem_numberに一意のインデックスを作成することは、私には良い考えのように思えます。なぜなら、(スキーマの詳細を知らなくても)1つのアイテムの在庫レベルは1つだけであると想像しているからです(システムで複数の在庫が許可されていない場合)。場所など)。

于 2009-11-26T08:01:02.850 に答える