次の構造のテーブルを更新する必要があります。
CREATE TABLE `eav_entity_attribute` (
`entity_attribute_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Entity Attribute Id',
`entity_type_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Entity Type Id',
`attribute_set_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Attribute Set Id',
`attribute_group_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Attribute Group Id',
`attribute_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Attribute Id',
`sort_order` smallint(6) NOT NULL DEFAULT '0' COMMENT 'Sort Order',
PRIMARY KEY (`entity_attribute_id`),
UNIQUE KEY `UNQ_EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_SET_ID_ATTRIBUTE_ID` (`attribute_set_id`,`attribute_id`),
UNIQUE KEY `UNQ_EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_GROUP_ID_ATTRIBUTE_ID` (`attribute_group_id`,`attribute_id`),
KEY `IDX_EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_SET_ID_SORT_ORDER` (`attribute_set_id`,`sort_order`),
KEY `IDX_EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_ID` (`attribute_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Eav Entity Attributes'
上記の表には、次の 1 つの行が含まれています。
INSERT INTO `eav_entity_attribute`
(`entity_attribute_id`, `entity_type_id`, `attribute_set_id`, `attribute_group_id`, `attribute_id`, `sort_order`)
VALUES
(32758, 4, 224, 3423, 5171, 12)
外部データ ソースを読み取り、このテーブルに書き込む自動インポート手順を実行しています。
このインポートは複数回実行されるため、同じデータが複数回インポートされることがあります。このような場合、新しいデータが古いデータと同じであっても、手順は単純に古いデータを新しいデータで上書きします。同一データが存在する状態は、ON DUPLICATE KEY UPDATE句で処理します。これは、この特定のテーブルを除いて、ほぼ完全に機能します。
このテーブルで、プロシージャーが UPDATE を試行すると、説明できない「重複キー」メッセージが表示されます。コードをデバッグしましたが、これは失敗したクエリです (INSERT..ON DUPLICATE KEY から抽出):
UPDATE eav_entity_attribute
SET
`attribute_group_id` = 3423
,`attribute_id` = 5171
,`attribute_set_id` = 223
,`entity_type_id` = 4
,`sort_order` = 320
WHERE
(`attribute_group_id` = 3423) AND
(`attribute_id` = 5171)
エラーは次のとおりです。
Error Code: 1062. Duplicate entry '3423-5171' for key 'UNQ_EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_GROUP_ID_ATTRIBUTE_ID'
3423-5171 のペアが既に存在することはわかっていますが、UPDATE はこれらの値をそれ自体で置き換え、新しいエントリを作成しません。この問題の原因についてはかなり混乱しています。どんな提案でも大歓迎です。ありがとう。
更新 - 新しい発見
ある種の「インスピレーション」を得て、実験を行いました。on ( attribute_set_id
, attribute_id
)を含む Unique 制約を削除し(注、これはエラーに含まれるものではありません)、INSERT..ON DUPLICATE クエリを実行しました。それは完璧に機能しました。
私は推測ですが、これは私が思うことです: テーブルに書き込もうとしているデータは、2 つの制約と衝突します:
- ユニーク(
attribute_set_id
,attribute_id
) - ユニーク(
attribute_group_id
,attribute_id
)
おそらく、最初の制約によって発生した重複エラーが原因で、INSERT が失敗します。これにより、最初の制約を暗黙の WHERE 句として使用する UPDATE がトリガーされます。私の推測では、そのような場合、最初の制約はどういうわけか無視されますが、UPDATE は 2 番目の制約にトリップします。
これは、何かをそれ自体に置き換えて重複エントリエラーを発生させる UPDATE の正当な理由にはまだ思えませんが、その背後にあるロジックに光を当てる可能性があります。
2 回目の更新
私がテストしていたテーブルには、他のデータのインポートが成功した結果、実際には多くの行が含まれていることがわかりました (フィルター ビューを無効にするのを忘れていました)。ただし、「重複候補」は依然としてセット内で一意です。
コメントに投稿された内容を確認します。テーブルにその行のみが含まれている場合、INSERT..ON DUPLICATE と UPDATE だけが機能します。同じデータで更新される単一の一意の行についてまだ話しているので、テーブルにさらにデータがあるとテーブルがめちゃくちゃになるのはなぜだろうと思っています。
3 回目の更新 - 根本原因を発見
UPDATE が失敗する理由がようやくわかりました。今度は、どうすればそのような状態になるかを調べなければなりません。
手がかりは、最初の更新での私の推測でした。簡単に言えば、2 つの非常によく似た行があります (クリーンなデータベースから開始したため、異なる値を使用していることに注意してください)。
row,entity_attribute_id,entity_type_id,attribute_set_id,attribute_group_id,attribute_id,sort_order
1,16919, 4, 120, 1746, 80, 1
2,16649, 4, 119, 1744, 80, 210
何が起こるかは次のとおりです。
- INSERT は、次の値を持つ行を挿入しようとします:
120, 4, 1744, 80, 54
. 120, 80
フィールドattribute_set_id, attribute_id
(行 1)の値が重複しているため、これにより「重複キー」がトリガーされます。次に、MySQL は UPDATE を試みます。これは次のようになります。
UPDATE テーブル
entity_type_id
= 4 、attribute_group_id
= 1744 、sort_order
= 54 WHERE (attribute_set_id
= 120) AND (attribute_id
= 80)今回は、行 2
1744,80
にあるペアの制約に値が違反しているため、UPDATE は失敗します。attribute_group_id, attribute_id
要約すれば
- 行 1 のキーの値が同じであるため、INSERT は失敗します
attribute_set_id, attribute_id
。 - 行 2 のキーの値が同じであるため、UPDATE は失敗します
attribute_group_id, attribute_id
。
解決
理論的には、そのような重複は発生しないはずなので、インポート手順全体を確認する必要があります。MySQL はうまく機能していますが、複雑なのはデータベースです。
すべての提案をありがとう。