- PR -

外部キーの設定について。

1
投稿者投稿内容
未記入
ベテラン
会議室デビュー日: 2004/08/18
投稿数: 80
投稿日時: 2005-12-26 12:39
こんにちわ。fuuです。

外部キーの設定について質問があります。
MySQL サーバ 3.23.44 以降では、CASCADE、ON DELETE、および ON UPDATE を含む外部キー制約のチェックが InnoDB テーブルでサポートされています。
とあったので、テーブルをInnoDBにして

alter table tb add foreign key フィールド references tb フィールド on delete restrict on update set null;
として試みたのですが、失敗しました。

Webページによっては、
外部キーを使用しない理由として、INSERT と UPDATE ステートメントへの速度の影響はものすごく、そしてこの場合、ほとんど全ての FOREIGN KEY チェックは役に立ちません。通常は、正しいテーブルに正しい順でレコードを挿入するためです。
とあり、役に立たないかもしれないと思いつつも、やってみたいと思ってしまいました。
どなたかご存知の方がいらっしゃったら、ご教授お願いいたします。
今川 美保(夏椰)
ぬし
会議室デビュー日: 2004/06/10
投稿数: 363
お住まい・勤務地: 神奈川県茅ヶ崎市
投稿日時: 2005-12-26 12:49
「失敗しました」と書かれていますが、
失敗した内容(エラーメッセージなど)として何が出力されたのか
書かれていないので、
まずエラー内容を書いてみてはいかがでしょう?
未記入
ベテラン
会議室デビュー日: 2004/08/18
投稿数: 80
投稿日時: 2005-12-27 16:21
返信ありがとうございます。

エラー内容は以下です。
ERROR 1064: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'references tb フィールド on delete restrict on update set nul

というのが出てきたのです。
ミソジマエ
常連さん
会議室デビュー日: 2005/09/25
投稿数: 43
投稿日時: 2005-12-27 16:32
引用:

fuuさんの書き込み (2005-12-27 16:21) より:
返信ありがとうございます。

エラー内容は以下です。
ERROR 1064: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'references tb フィールド on delete restrict on update set nul

というのが出てきたのです。



'references tb フィールド on delete restrict on update set nul
付近で構文エラーになってるからマニュアル確認してください。
ってことですから、もう一度マニュアルと見比べておかしい所がないか
確認しないとダメですね。
今川 美保(夏椰)
ぬし
会議室デビュー日: 2004/06/10
投稿数: 363
お住まい・勤務地: 神奈川県茅ヶ崎市
投稿日時: 2005-12-27 18:05
コード:

ALTER TABLE `test`.`test2` ADD CONSTRAINT `FK_test2_3` FOREIGN KEY `FK_test2_3` (`col1`)
REFERENCES `test1` (`col1`)
ON DELETE RESTRICT
ON UPDATE RESTRICT
, COMMENT = 'InnoDB free: 4096 kB; ("col1") REFER "test/test2"("col1") ON UPDATE CASCADE; ("c';



の様に、列名に「`」をつけても駄目でしょうか?

#MySQL5.0.17ではこの様なSQLで実行を確認しました。


[ メッセージ編集済み 編集者: 夏椰(冒 険 者) 編集日時 2005-12-27 18:07 ]
未記入
ベテラン
会議室デビュー日: 2004/08/18
投稿数: 80
投稿日時: 2006-01-16 10:32
返信ありがとうございます。

ミソジマエさんや夏椰(冒 険 者)さんの助言を参考にして、自分なりにさまざまな書き方で挑戦してみたのですが、
ERROR 1005: Can't create table '.\データベース名\#sql-1dc_1.frm' (errno: 150)
というエラーがでてしまい、外部キーの設定はできませんでした。



ミソジマエ
常連さん
会議室デビュー日: 2005/09/25
投稿数: 43
投稿日時: 2006-01-16 18:40
MySQLは使ったことが無いので先に言い訳をしといて。

googleで error 1005 mysql で検索すると下記のサイトに当たりました。
http://www.hostgeekz.com/docs/mysql/japanese/manual.ja_Table_types.html

サイト内を 1005 で検索するとそれらしい記述がありますねえ。
以下抜粋
引用:

どちらのテーブルも InnoDB 型でなければなりません。テーブル内には、外部キーカラムが最初のカラムとして同じ順序で列挙されているインデックスが必要です。また、参照テーブル内には、参照カラムが最初のカラムとして同じ順序で列挙されているインデックスが必要です。InnoDB は、外部キーまたは参照キーに対して自動的にインデックスを作成しません。したがって、ユーザが明示的にインデックスを作成する必要があります。外部キーのチェックを高速化し、テーブルスキャンを不要にするには、インデックスが必要です。

外部キーと参照キーの対応するカラムは、型を変換しなくても比較できるように、InnoDB 内部で同じデータ型にする必要があります。 整数型については、サイズと符号の有無が同じでなければなりません。文字列型の長さは同じでなくてもかまいません。 SET NULL アクションを指定する場合は、子テーブル内のカラムを NOT NULL と宣言していないことを確認してください。

MySQL が CREATE TABLE ステートメントでエラー番号 1005 を返し、エラーメッセージ文字列に errno 150 が示されている場合は、外部キー制約が正しく作成されなかったためにテーブルの作成が失敗しています。同様に、ALTER TABLE が失敗して errno 150 が示された場合は、変更されたテーブルに対して外部キー定義が誤って作成されています。バージョン 4.0.13 より、SHOW INNODB STATUS を使用して、サーバで最後に発生した InnoDB 外部キーエラーの詳細な説明を参照できるようになりました。



引用:

バージョン 3.23.50 より、InnoDB では次のステートメントによって新しい外部キー制約をテーブルに追加できるようになりました。

ALTER TABLE yourtablename
ADD [CONSTRAINT [symbol]] FOREIGN KEY (...) REFERENCES anothertablename(...)
[on_delete_and_on_update_actions]

ただし、必要なインデックスを先に作成することを忘れないでください。

バージョン 4.0.13 より、InnoDB が次のステートメントをサポートするようになりました。

ALTER TABLE yourtablename DROP FOREIGN KEY internally_generated_foreign_key_id

外部キーを破棄する場合は、SHOW CREATE TABLE を使って、内部で生成された外部キー ID を確認する必要があります。 InnoDB が 3.23.50 より前のバージョンである場合は、外部キー制約を持つテーブルまたは外部キー制約で参照されるテーブルに関連して ALTER TABLE または CREATE INDEX を使用しないでください。ALTER TABLE を実行すると、テーブルに定義されているすべての外部キー制約が削除されます。ALTER TABLE は、参照テーブルにも使用しないでください。ただし、スキーマを変更する場合は DROP TABLE および CREATE TABLE を使用します。MySQL は、ALTER TABLE を実行するときに内部的に RENAME TABLE を使用する場合があります。この場合、テーブルを参照する外部キー制約で混乱が生じます。 CREATE INDEX ステートメントは、MySQL では ALTER TABLE として処理されるため、このステートメントにもこれらの制約が適用されます。

InnoDB は、外部キーチェックを実行する際に、参照する子レコードまたは親レコードに対して共有行レベルロックを設定します。 InnoDB は、外部キー制約を即座にチェックします。チェックがトランザクションコミットまで延期されることはありません。

外部キー制約を、たとえば LOAD DATA 処理の間だけ無視する場合は、SET FOREIGN_KEY_CHECKS=0 を実行します。

InnoDB では、外部キー制約によって参照されているテーブルでも破棄できます。この場合、その制約が壊れることになります。テーブルを破棄すると、その作成ステートメントで定義された制約も破棄されます。

破棄されたテーブルを再作成する場合は、そのテーブルを参照する外部キー制約に沿った定義をテーブル内に設定する必要があります。すでに説明したように、このテーブルには、正しい名前と型を持つカラム、および参照キー上のインデックスが必要です。これらの条件が満たされていないと、MySQL からエラー番号 1005 が返され、エラーメッセージ文字列に errno 150 が示されます。

未記入
ベテラン
会議室デビュー日: 2004/08/18
投稿数: 80
投稿日時: 2006-01-17 11:21
返信ありがとうございます。
ミソジマエさんの助言を参考にしながら、引き続き外部キーの設定に挑戦してみます。
1

スキルアップ/キャリアアップ(JOB@IT)