web-dev-qa-db-ja.com

重複エントリがないにもかかわらず、MySQLの重複エントリエラー

MySQL 5.1.56、MyISAMを使用しています。私のテーブルは次のようになります。

CREATE TABLE IF NOT EXISTS `my_table` (
  `number` int(11) NOT NULL,
  `name` varchar(50) NOT NULL,
  `money` int(11) NOT NULL,
  PRIMARY KEY (`number`,`name`)
) ENGINE=MyISAM;

次の2つの行が含まれます。

INSERT INTO `my_table` (`number`, `name`, `money`) VALUES
(1, 'S. Name', 150), (2, 'Another Name', 284);

今、私は別の行を挿入しようとしています:

INSERT INTO `my_table` (`number`, `name`, `money`) VALUES
(2, 'S. Name', 240);

そして、MySQLはこれを私に言っている間は挿入しません。

#1062 - Duplicate entry '2-S. Name' for key 'PRIMARY'

私は本当に理解していません。主キーは最初の2列(両方)にあるため、挿入しようとしている行には一意の主キーがありますよね?

テーブルを修復しようとしましたが、テーブルを最適化しようとしましたが、まったく役に立ちませんでした。また、MyISAMからInnoDBに変更できないことに注意してください。

私は何かを見逃していますか、これはMySQLまたはMyISAMのバグですか?ありがとう。

問題があると思われる箇所を要約して指摘するには:テーブルには2つの列に主キーがあります。これら2つの列に値の新しい組み合わせを含む行を挿入しようとしていますが、列1の値はすでにある行にあり、列2の値はすでに別の行にあります。しかし、それらはどこにも結合されていないため、これは機能するはずであり、機能しないことを理解するのは非常に混乱しています。

21
user1763581

コードとスキーマは問題ありません。おそらく以前のバージョンのテーブルで試してみました。

http://sqlfiddle.com/#!2/9dc64/1/

テーブルにはUNIQUEがないため、そのテーブルではエラーは発生しません。

そのテーブルからデータをバックアップし、ドロップして再作成します。

たぶん、あなたはそれを実行しようとしましたCREATE TABLE IF NOT EXIST。作成されていません。古いバージョンがありますが、IF NOT EXISTによるエラーはありませんでした。

次のようなSQLを実行して、現在のテーブル構造を確認できます。

DESCRIBE my_table;

編集-後で追加:

これを実行してみてください:

DROP TABLE `my_table`; --make backup - it deletes table

CREATE TABLE `my_table` (
  `number` int(11) NOT NULL,
  `name` varchar(50) NOT NULL,
  `money` int(11) NOT NULL,
  PRIMARY KEY (`number`,`name`),
  UNIQUE (`number`, `name`) --added unique on 2 rows
) ENGINE=MyISAM;
18
Kamil

この場合、これが問題ではないことはわかっていますが、複合主キーを作成するときに「エントリの重複」という同様の問題がありました。

ALTER TABLE table ADD PRIMARY KEY(fieldA,fieldB); 

エラーは次のようなものでした:

#1062 Duplicate entry 'valueA-valueB' for key 'PRIMARY'

だから私は検索しました:

select * from table where fieldA='valueA' and fieldB='valueB'

出力には1行しか表示されず、重複はありませんでした!

しばらくして、これらのフィールドにNULL値がある場合、これらのエラーを受け取ることがわかりました。最終的に、エラーメッセージは私を誤解させるようなものでした。

8
carla

私の場合、エラーは古いスキーマが原因で、1つの列は元々varchar(50)でしたが、インポートしようとしたダンプはvarchar(70)を持つスキーマの修正バージョンから作成されましたその列(および50文字以上を使用するフィールドのエントリの一部)。

インポート中に一部のキーが切り捨てられ、切り捨てられたバージョンは一意ではなくなりました。それを理解するのにしばらく時間がかかりましたが、私は「しかし、このおそらく複製されたキーは存在しません!」のようでした。

1
flagg19

あまり一般的ではありませんが、DOC https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-limitations .html

オンラインALTER TABLE操作を実行すると、ALTER TABLE操作を実行するスレッドは、他の接続スレッドから同じテーブルで同時に実行されたDML操作の「オンラインログ」を適用します。 DML操作が適用されると、重複エントリが一時的なものであり、「オンラインログ」の以降のエントリによって元に戻される場合でも、重複キーエントリエラー(ERROR 1062(23000):Duplicate entry)が発生する可能性があります。これは、トランザクション中に制約を保持する必要があるInnoDBの外部キー制約チェックの考え方に似ています。

1
Xeoncross

これがOP以外の人に役立つ場合、InnoDBを使用して同様の問題が発生しました。

私にとって、本当に起こっていたのは外部キー制約の失敗でした。存在しない外部キーを参照していました。

つまり、エラーは完全にオフでした。主キーは問題なく、外部キーを挿入することで最初に問題が修正されました。 MySQLが突然これを間違った理由はわかりません。

0
Timo

この問題は、多くの場合、列を追加するとき、または既存の列を主キーとして使用するときに発生します。実際には作成されなかった主キーが存在するため、またはテーブルの損傷のために作成されません。

エラーが実際に示すのは、保留中のキー値が空白であることです。

解決策は、列に一意の値を入力してから、主キーの作成を再試行することです。 空白、null、または重複する値が存在しない場合、この誤解を招くエラーが表示されます。

0
Robert Mauro

自動インクリメントで試してください:

CREATE TABLE IF NOT EXISTS `my_table` (
   `number` int(11) NOT NULL AUTO_INCREMENT,
   `name` varchar(50) NOT NULL,
   `money` int(11) NOT NULL,
    PRIMARY KEY (`number`,`name`)
) ENGINE=MyISAM;
0
grai

あなたのコードはこのデモでうまく機能しています:

http://sqlfiddle.com/#!8/87e10/1/

2回目のクエリ(挿入...)を2回行っていると思います。試して

select * from my_table

新しい行を挿入する前に、データがすでに存在するかどうかがわかります。

0
Habibillah

他の誰かが私の問題でこのスレッドを見つけた場合-MySQLで「整数」列タイプを使用していました。挿入しようとした行には、整数で許可されているよりも大きい値を持つ主キーがありました。 「bigint」に切り替えると問題が修正されました。

0
Ben Wilson

私の場合、エラーは非常に誤解を招くものでした。問題は、PHPMyAdminが「ALTER IGNORE TABLE」ではなく「make unique」ボタンをクリックしたときに「ALTER TABLE」を使用するため、次のように手動で行う必要があったことです。

ALTER TABLE mytbl ADD UNIQUE (columnName);
0

私はちょうど試しましたが、データとテーブルの再作成がうまくいかない場合は、テーブルをInnoDBに変更してもう一度試してください、それは問題を修正します

0
Janos Szabo

同様の問題がありましたが、私の場合、大文字と小文字を区別しない照合-utf8_general_ciを使用していました。

したがって、大文字と小文字を区別する比較では異なるが、大文字と小文字を区別しない比較では同じである2つの文字列を挿入しようとすると、MySQLがエラーを起動し、大文字と小文字を区別するので問題を理解できませんでしたサーチ。

解決策は、テーブルの照合順序を変更することです。大文字と小文字を区別するutf8_binを使用しました(またはutf8_general_csも適切なものでなければなりません)。

0
RussCoder

コードによると、「番号」と「名前」はプライマリキーであり、競合するように両方の行にS.NAMEを挿入しています。完全なデータにアクセスするためにプライマリキーを使用しています。ここでは、プライマリキー「名前」を使用してデータにアクセスすることはできません。

私は初心者であり、私はそれがエラーかもしれないと思う。

0
Megamind