3

mySQL でテーブルを作成しようとすると、エラー 150 が発生します。私は無駄にフォーラムを精査しました。ステートメントは外部キー制約を使用します。両方のテーブルが InnoDB であり、関連するすべての列が同じデータ型を持ち、両方のテーブルが同じ文字セットと照合順序を持ちます。参照されているテーブルの CREATE TABLE と元の CREATE TABLE ステートメントを次に示します。何か案は?

新しいテーブル:

CREATE TABLE `approval` (
  `rev_id` int(10) UNSIGNED NOT NULL,
  `rev_page` int(10) UNSIGNED NOT NULL,
  `user_id` int(10) UNSIGNED NOT NULL,
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY  (`rev_id`,`rev_page`,`user_id`),
  KEY `FK_approval_user` (`user_id`),
  CONSTRAINT `FK_approval_revision` FOREIGN KEY (`rev_id`, `rev_page`) REFERENCES `revision` (`rev_id`, `rev_page`),
  CONSTRAINT `FK_approval_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

参照表:

CREATE TABLE `revision` (
  `rev_id` int(10) unsigned NOT NULL auto_increment,
  `rev_page` int(10) unsigned NOT NULL,
  `rev_text_id` int(10) unsigned NOT NULL,
  `rev_comment` tinyblob NOT NULL,
  `rev_user` int(10) unsigned NOT NULL default '0',
  `rev_user_text` varbinary(255) NOT NULL default '',
  `rev_timestamp` binary(14) NOT NULL default '\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
  `rev_minor_edit` tinyint(3) unsigned NOT NULL default '0',
  `rev_deleted` tinyint(3) unsigned NOT NULL default '0',
  `rev_len` int(10) unsigned default NULL,
  `rev_parent_id` int(10) unsigned default NULL,
  PRIMARY KEY  (`rev_id`),
  UNIQUE KEY `rev_page_id` (`rev_page`,`rev_id`),
  KEY `rev_timestamp` (`rev_timestamp`),
  KEY `page_timestamp` (`rev_page`,`rev_timestamp`),
  KEY `user_timestamp` (`rev_user`,`rev_timestamp`),
  KEY `usertext_timestamp` (`rev_user_text`,`rev_timestamp`)
) ENGINE=InnoDB AUTO_INCREMENT=4904 DEFAULT CHARSET=binary MAX_ROWS=10000000 AVG_ROW_LENGTH=1024;
4

4 に答える 4

4

このエラーは通常、外部キーの制限に関連しています。LATEST FOREIGN KEY ERRORセクションを実行show innodb statusして探し、より具体的な説明を取得します。

これは、2 番目のテーブルを作成したときに得られるものです。

テーブル テスト/承認の外部キー制約のエラー: FOREIGN KEY ( rev_id, rev_page) REFERENCES revision( rev_id, rev_page),
CONSTRAINT FK_approval_userFOREIGN KEY ( user_id) REFERENCES user ( user_id) ) ENGINE=InnoDB DEFAULT CHARSET=latin1: 参照列が存在する参照テーブルにインデックスが見つかりませんが最初の列として表示されるか、テーブルと参照されるテーブルの列の型が制約に一致しません。

于 2010-06-03T15:10:44.860 に答える
2

更新: 私は盲目だったに違いない:

テーブルの作成が失敗する理由は、「rev_page_id」キーの順序が間違っているためです (innodb では、キーが外部キーと同じ順序である必要があります。

CREATE TABLE `revision` (
  `rev_id` int(10) unsigned NOT NULL auto_increment,
  ....
  `rev_parent_id` int(10) unsigned default NULL,
  PRIMARY KEY  (`rev_id`),
  -- wrong:
  -- UNIQUE KEY `rev_page_id` (`rev_page`,`rev_id`), 
  -- better:
  UNIQUE KEY `rev_page_id` (`rev_id`, `rev_page`),
  ....

以下の提案は無視してください。


試す

SHOW ENGINE INNODB STATUS

smth を探します。「LAST INNODB FOREIGN KEY ERROR」のように残念ながら、ほとんどの場合、エラー メッセージはあまり直感的ではありません。あなたはタイプがすべて同じだと言ったので、次のエラーである可能性があると思います:

  • FK 名は既に存在します (FK 名はデータベース全体で一意である必要があります)。実際には、mysql インスタンス全体で一意である必要がありますが、内部的に innodb はデータベース名を外部キー名に追加します (FK_approval_user は内部的に yourdbname#FK_approval_user と呼ばれます)。

アップデート:

「FK_approval_revision」のキーが不足しているようです

次のようになります。

CREATE TABLE `approval` (
  `rev_id` int(10) UNSIGNED NOT NULL,
  `rev_page` int(10) UNSIGNED NOT NULL,
  `user_id` int(10) UNSIGNED NOT NULL,
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY  (`rev_id`,`rev_page`,`user_id`),
  KEY `FK_approval_user` (`user_id`),
  KEY `FK_approval_revision` (`rev_id`, `rev_page`),
  CONSTRAINT `FK_approval_revision` FOREIGN KEY (`rev_id`, `rev_page`) REFERENCES `revision` (`rev_id`, `rev_page`),
  CONSTRAINT `FK_approval_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
于 2010-06-03T15:09:52.950 に答える
1

制約定義で列の順序を変更すると機能します。

FOREIGN KEY (`rev_page`,`rev_id`) REFERENCES `revision` (`rev_page`,`rev_id`)

フィールドの順序は一意のインデックスと同じでなければならないため、元のクエリは機能しません。ただし、制約に rev_page 列を追加するのは不要です (revision.rev_id 自体が一意であるため、revision.rev_id + Revision.rev_page は一意の制約なしで 100% 一意です)。したがって、一意のキーをオンにする必要はありません (revision.rev_id + revision.rev_page)。制約を次のように変更すると、はるかに優れたものになります。

FOREIGN KEY (`rev_id`) REFERENCES `revision` (`rev_id`)
于 2010-06-03T15:12:18.290 に答える
0

innodb ステータスを表示

このコマンドは大いに役立ちます

于 2011-09-16T11:01:15.300 に答える