52

MySQLバージョン5.5.24には次の表があります

DROP TABLE IF EXISTS `momento_distribution`;

CREATE TABLE IF NOT EXISTS `momento_distribution`
  (
     `momento_id`       INT(11) NOT NULL,
     `momento_idmember` INT(11) NOT NULL,
     `created_at`       DATETIME DEFAULT NULL,
     `updated_at`       DATETIME DEFAULT NULL,
     `unread`           TINYINT(1) DEFAULT '1',
     `accepted`         VARCHAR(10) NOT NULL DEFAULT 'pending',
     `ext_member`       VARCHAR(255) DEFAULT NULL,
     PRIMARY KEY (`momento_id`, `momento_idmember`),
     KEY `momento_distribution_FI_2` (`momento_idmember`),
     KEY `accepted` (`accepted`, `ext_member`)
  )
ENGINE=InnoDB
DEFAULT CHARSET=latin1;

とを使用して他の2つのテーブルと多対1の関係を持つ大量のデータがありondelete=restrictますonupdate=restrict

次に、既存の関係とデータを維持したまま、構造を変更し、テーブルに個別の主キーを導入する必要があります。そのために、次のクエリを実行しました。

ALTER TABLE  `momento_distribution` ADD  `id` INT( 11 ) NOT NULL FIRST;
ALTER TABLE  `momento_distribution` DROP PRIMARY KEY , ADD PRIMARY KEY (  `id` );

残念ながら、2番目のクエリは次のエラーで失敗しました。

1062-キー「PRIMARY」のエントリ「0」が重複しています

誰かが問題を指摘できますか?問題は既存のリレーションにあると思いますが、数千行ある既存のリレーションやデータを失いたくありません。データを失うことなくこれを行う方法はありますか?

編集: データを表示すると、新しく作成された列に値「0」が含まれていることがわかりました。おそらくこれは、(新しい主キーの)レコードが重複しているために主キーを変更することを許可していません

8,000行を超えているため、手動で変更することはできません。rowid新しい主キーに割り当てる方法はありますか?

4

8 に答える 8

66

主キーを自動インクリメントとして指定する必要があります

CREATE TABLE `momento_distribution`
  (
     `momento_id`       INT(11) NOT NULL AUTO_INCREMENT,
     `momento_idmember` INT(11) NOT NULL,
     `created_at`       DATETIME DEFAULT NULL,
     `updated_at`       DATETIME DEFAULT NULL,
     `unread`           TINYINT(1) DEFAULT '1',
     `accepted`         VARCHAR(10) NOT NULL DEFAULT 'pending',
     `ext_member`       VARCHAR(255) DEFAULT NULL,
     PRIMARY KEY (`momento_id`, `momento_idmember`),
     KEY `momento_distribution_FI_2` (`momento_idmember`),
     KEY `accepted` (`accepted`, `ext_member`)
  )
ENGINE=InnoDB
DEFAULT CHARSET=latin1$$

以下のコメントに関しては、どうですか。

ALTER TABLE `momento_distribution`
  CHANGE COLUMN `id` `id` INT(11) NOT NULL AUTO_INCREMENT,
  DROP PRIMARY KEY,
  ADD PRIMARY KEY (`id`);

PRIMARY KEYは一意のインデックスであるため、重複が含まれている場合、その列を一意のインデックスに割り当てることはできません。そのため、新しい列をまとめて作成する必要がある場合があります。

于 2012-08-29T14:04:21.467 に答える
25

mysqlコンソールで次のクエリを実行します。

SHOW CREATE TABLE momento_distribution

次のような行を確認してください

CONSTRAINT `momento_distribution_FK_1` FOREIGN KEY (`momento_id`) REFERENCES `momento` (`id`)

それは違うかもしれません、私はそれが何であるかについて推測します。'momento_id'と'momento_idmember'の両方に外部キーがある場合、2つの外部キー名を取得します。次のステップは、外部キーを削除することです。次のクエリを実行します。

ALTER TABLE momento_distribution DROP FOREIGN KEY momento_distribution_FK_1
ALTER TABLE momento_distribution DROP FOREIGN KEY momento_distribution_FK_2

CREATE TABLE外部キー名は、必ずクエリから取得した名前に変更してください。これで外部キーがなくなったので、主キーを簡単に削除できます。次のことを試してください。

ALTER TABLE  `momento_distribution` DROP PRIMARY KEY

次のように必要な列を追加します。

ALTER TABLE  `momento_distribution` ADD  `id` INT( 11 ) NOT NULL  PRIMARY KEY AUTO_INCREMENT FIRST

このクエリは数値も追加するため、@rowidに依存する必要はありません。次に、外部キーを前の列に追加し直す必要があります。そのためには、最初にこれらのインデックスを作成します。

ALTER TABLE  `momento_distribution` ADD INDEX (  `momento_id` )
ALTER TABLE  `momento_distribution` ADD INDEX (  `momento_idmember` )

次に、外部キーを追加します。必要に応じて参照テーブル/列を変更します。

ALTER TABLE  `momento_distribution` ADD FOREIGN KEY ( `momento_id`) REFERENCES  `momento` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT 
ALTER TABLE  `momento_distribution` ADD FOREIGN KEY ( `momento_idmember`) REFERENCES  `member` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT 

お役に立てば幸いです。エラーが発生した場合は、参照テーブルの構造と取得したエラーコードを使用して質問を編集してください。

于 2012-08-30T04:23:31.490 に答える
14

主キーのあるフィールドが自動インクリメントに設定されているかどうかを確認します

于 2016-01-05T20:14:06.747 に答える
8

このステップは私にとって完璧に機能します..あなたはそれを試すことができます

  1. インデックスを追加する
  2. 自動インクリメントを追加
  3. 主キーを追加する

それがあなたにも役立つことを願っています。幸運を

于 2017-11-27T09:14:58.997 に答える
6

PRIMARYKEYをAUTO_INCREMENTとして設定します。

于 2018-11-09T03:23:29.053 に答える
1

私の場合、プライマリフィールドにAUTO_INCREMENTを追加するのを忘れ、IDなしでデータを挿入しました。

于 2019-09-25T11:15:18.633 に答える
0

AUTO_INCREMENTPRIMARYKEYに設定します

于 2019-09-26T08:33:26.240 に答える
0

私はこのエラーに直面しました、使用されたtypeorm移行Api、上記のこのエラーはidが自動インクリメントされていない結果であるため、typeormのApi移行を使用して移行を書き込む場合、id列を書き込むときにこれを使用してid列を設定します。 { name: "id", type: "int auto_increment", isPrimary: true }

于 2021-09-03T08:56:58.480 に答える