MySQL 5.5.22でDjangoを使用して次の問題が発生しています。列番号、レベルおよびA11として記憶2x2の行列とテーブルを考える複数の列を変更するMySQLの更新は非アトミックですか?
、A12、A21、A22、私はこの行を持っている:
:クエリセット適量与えられるid a11 a12 a21 a22 level
324 3 2 5 3 2
、私は、次の更新を行います
UPDATE `storage`
SET
`a21` = (3 * `storage`.`a11`) + (-1 * `storage`.`a21`),
`a22` = (3 * `storage`.`a12`) + (-1 * `storage`.`a22`),
`level` = `storage`.`level` - -1,
`a11` = (2 * `storage`.`a11`) + (-1 * `storage`.`a21`),
`a12` = (2 * `storage`.`a12`) + (-1 * `storage`.`a22`)
:Djangoは次のクエリを(db.connection.queriesからそれを得た、簡潔にするためにwhere句を削除)生成するために
qs.update(
a11=(b12 * a21 - b11 * a22) * F('a11') + (b11 * a12 - b12 * a11) * F('a21'),
a12=(b12 * a21 - b11 * a22) * F('a12') + (b11 * a12 - b12 * a11) * F('a22'),
a21=(b22 * a21 - b21 * a22) * F('a11') + (b21 * a12 - b22 * a11) * F('a21'),
a22=(b22 * a21 - b21 * a22) * F('a12') + (b21 * a12 - b22 * a11) * F('a22'),
level=(F('level') - 1)
)
a12*a21 - a11*a22 = 1
が真であると想定され、そしてそれに応じて、行をすることになった、任意の行については
id a11 a12 a21 a22 level
324 2 1 4 3 1
:
id a11 a12 a21 a22 level
324 1 1 4 3 1
これは
そして、私の行は、その後、このようになります。 Djangoが同じクエリを生成しているので、SQLiteには何が得られますか?そして、MySQLが何か違うことをしていることを理解するのに多くの時間がかかりました。クエリからは、複数の行を更新するときのように見えますが、MySQLはそれを単一のアトミック操作として扱わず、列が更新されると、それらの値に依存します。私は、これはPythonのプロンプトに次のコードで何が起こるかのようです確認:
>>> a11, a12, a21, a22 = (3, 2, 5, 3)
>>> (2 * a11) + (-1 * a21),\
... (2 * a12) + (-1 * a22),\
... (3 * a11) + (-1 * a21),\
... (3 * a12) + (-1 * a22)
(1, 1, 4, 3)
列は、クエリによって与えられたのと同じ順序で、一度に1つの更新された場合:
>>> a11, a12, a21, a22 = (3, 2, 5, 3)
>>> a21 = (3*a11) + (-1*a21)
>>> a22 = (3*a12) + (-1*a22)
>>> a11 = (2*a11) + (-1*a21)
>>> a12 = (2*a12) + (-1*a22)
>>> (a11, a12, a21, a22)
(2, 1, 4, 3)
これをこれはクロスプラットフォームで使用されることを意図したライブラリなので、実際は怖い動作です。私の質問は次のとおりです:
- どちらが間違っていますか、MySQLまたはSQLite?これはバグと見なすことができますか?
- 他の主要なデータベース(Oracle、PostgreSQL、SQLServer)から期待できることはありますか?
- この動作を正規化するには、Django ORM(未処理クエリなし)で何ができますか?
編集
問題は明らかですが、私はまだ解決策を探しています。すべての値をプルして戻すことは、この特定のアプリケーションでは許容できる解決策ではありません。 MySQL manualで述べたよう
これは興味深い質問です。私は[sqlfiddle](http://sqlfiddle.com/#!2/7f14b/2)でそれを試してみましたが、このように動作するのはMySQLだけです。 – Chad
関連/複製:http://stackoverflow.com/questions/2203202/sql-update-order-of-evaluation – pilcrow
下記の更新された回答を参照してください。 – eggyal