質問
ここ数週間、SQLをゆっくり学習しています。リレーショナル代数のすべてと、リレーショナルデータベースの動作の基本を取り上げました。私が今やろうとしているのは、それがどのように実装されているかを学ぶことです。
これに出くわした障害は、MySQLの外部キーです。 InnoDB ストレージスキーマに存在するもの以外は、ほとんど見つけることができないようです。 MySQLは持っています。
MySQLに実装された外部キーの簡単な例は何ですか?
ここに、私が書いたスキーマの一部を示します。実際の例を示すよりも私の欠陥を指摘したい場合は、機能していないようです。
CREATE TABLE `posts` (
`pID` bigint(20) NOT NULL auto_increment,
`content` text NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`uID` bigint(20) NOT NULL,
`wikiptr` bigint(20) default NULL,
`cID` bigint(20) NOT NULL,
PRIMARY KEY (`pID`),
Foreign Key(`cID`) references categories,
Foreign Key(`uID`) references users
) ENGINE=InnoDB;
解決
カテゴリとユーザーテーブルが既に存在し、それぞれcIDとuIDが主キーとして含まれていると仮定すると、これは機能するはずです:
CREATE TABLE `posts` (
`pID` bigint(20) NOT NULL auto_increment,
`content` text NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`uID` bigint(20) NOT NULL,
`wikiptr` bigint(20) default NULL,
`cID` bigint(20) NOT NULL,
PRIMARY KEY (`pID`),
Foreign Key(`cID`) references categories(`cID`),
Foreign Key(`uID`) references users(`uID`)
) ENGINE=InnoDB;
references
句には列名が必要です。
他のヒント
編集済み: RobertとVinkoは、外部キー制約で参照される列の名前を宣言する必要があると述べています。 InnoDBではこれが必要ですが、標準SQLでは、親テーブルと同じ名前の場合、参照される列名を省略することができます。
MySQLで私が遭遇した特異性の1つは、いくつかの状況で外部キー宣言がサイレントに失敗することです:
- MySQLインストールにはinnodbエンジンが含まれていません
- MySQL構成ファイルはinnodbエンジンを有効にしません
- ENGINE = InnoDBテーブル修飾子でテーブルを宣言しません
- 外部キー列は、参照先テーブルの主キー列とまったく同じデータ型ではありません
残念ながら、MySQLは外部キー制約の作成に失敗したというメッセージを表示しません。リクエストを単に無視し、外部キーなしでテーブルを作成します(CREATE TABLEの投稿を表示すると、外部キーの宣言が表示されない場合があります)。これは常にMySQLの悪い機能だと思っていました!
ヒント:整数データ型の整数引数(BIGINT(20)など)は必要ありません。記憶域のサイズや列の範囲とは関係ありません。 BIGINTは、指定した引数に関係なく、常に同じサイズです。数字は、ZEROFILL列修飾子を使用した場合にMySQLが列に埋め込む桁数を示します。
これにはいくつかあります外部キーを自分で作成する方法を示すコード、およびCREATE TABLEで。
これからの簡単な例の1つを次に示します。
CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE child (
id INT,
parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id) REFERENCES parent(id)
ON DELETE CASCADE
) ENGINE=INNODB;
ロバートに同意します。 references句に列の名前がありません(エラー150が表示されるはずです)。以下を使用して、実際にテーブルが作成された方法を確認できることを追加します。
SHOW CREATE TABLE posts;
前の回答では、外部キーの制約を扱っていました。外部キー制約は参照整合性を維持するために間違いなく有用ですが、「外部キー」の概念は制約を使用するかどうかに関係なく、それ自体がデータのリレーショナルモデルの基本です。
equijoin を実行するたびに、何かへの外部キー、通常はそれが参照するキー。例:
select *
from
Students
inner join
StudentCourses
on Students.StudentId = StudentCourses.StudentId
StudentCourses.StudentIdは、Students.StudentIdを参照する外部キーです。