web-dev-qa-db-ja.com

複数のUNIQUEフィールドに対するONDUPLICATE KEYUPDATEのMySQLの動作

MySQL 4.1.0以降では、ON DUPLICATE KEY UPDATEステートメントを追加して、挿入された値(INSERTまたはSETまたはVALUESを含む)がすでに存在する場合の動作を指定できます。宛先テーブルwrt PRIMARY KEYまたはいくつかのUNIQUEフィールド。 PRIMARY KEYまたはいくつかのUNIQUEフィールドの値がすでにテーブルにある場合、INSERTUPDATEに置き換えられます。

  • テーブルに複数のUNIQUEフィールドがある場合、ON DUPLICATE KEY UPDATEはどのように動作しますか?

  • いずれかのUNIQUEフィールドが一致する場合、更新を1つだけ行うことはできますか?

  • 両方のUNIQUEフィールドが同時に一致する場合にのみ更新を行うことはできますか?

18
kiriloff

検討する

INSERT INTO table (a,b,c) VALUES (1,2,3)
    -> ON DUPLICATE KEY UPDATE c=c+1;

aとbがUNIQUEフィールドの場合、UPDATEa = 1 OR b = 2で発生します。また、条件a = 1 OR b = 2が2つ以上のエントリで満たされている場合、更新は1回だけ行われます。

IdとNameUNIQUEフィールドを持つここのテーブルテーブルの例

Id     Name     Value 
1      P        2 
2      C        3 
3      D        29 
4      A        6

クエリが

INSERT INTO table (Id, Name, Value)
VALUES (1, C, 7)

その後、

Id     Name     Value 
1      P        2 
2      C        3 
3      D        29 
4      A        6
1      C        7

これはIDと名前の一意性に違反します。今と

INSERT INTO table (Id, Name, Value)
VALUES (1, C, 7)
ON DUPLICATE KEY UPDATE Value = 7

我々が得る

Id     Name     Value 
1      P        7 
2      C        7 
3      D        29 
4      A        6

複数のキーでの動作は次のとおりです

ON DUPLICATE KEY UPDATEUPDATEは、UNIQUEフィールドの1つが挿入される値と等しい場合に実行されます。ここで、UPDATEId = 1 OR Name = Cで実行されます。と同等です

UPDATE table 
SET Value = 7
WHERE Id = 1 OR Name = C

いずれかのキーに対して1つの更新のみが必要な場合はどうなりますか

UPDATEステートメントをLIMITキーワードとともに使用できます

UPDATE table 
SET Value = 7
WHERE Id = 1 OR Name = C
LIMIT 1;

これは

Id     Name     Value 
1      P        7 
2      C        3 
3      D        29 
4      A        6

両方のキーの値が一致する場合にのみ1つの更新が必要な場合はどうなりますか

1つの解決策は、ALTER TABLEを実行し、PRIMARY KEY(または一意性)を両方のフィールドで機能させることです。

ALTER TABLE table 
DROP PRIMARY KEY
ADD PRIMARY KEY (Id, Name);

INSERT INTO table (Id, Name, Value)
VALUES (1, C, 7)
ON DUPLICATE KEY UPDATE Value = 7

我々が得る

Id     Name     Value 
1      P        2 
2      C        3 
3      D        29 
4      A        6
1      C        7

(両方のキーで)重複が見つからないため。

24
kiriloff
  1. mySQLはどのように動作しますか...期待どおりに動作します。つまり、ON DUPLICATEKEY句を実行します。

  2. どちらかを更新することはできますか...実際には、ON DUPLICATE KEY句は1つしかないため、どの制約が関係しているかを区別するためにコードを配置する必要があります。フォーチュナテリー、それは可能です。知っておくべき唯一のことは、割り当ての順序が重要であり、複数回割り当てることができます。 aとbに一意性制約があり、一意性が関係する場合にのみcを更新するとします。..KEY UPDATE c = IF(a = VALUES(a)and b <> VALUES(b)、VALUES( c)、c)、b = VALUES(b)

    ただし、割り当ての順序を変更すると、if内の2番目の条件は常にfalseになります。

  3. 2を参照してください。

0
newtover