質問

ここ数週間、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を参照する外部キーです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top