質問するログイン新規登録

回答編集履歴

1

追記

2018/07/02 23:15

投稿

Orlofsky
Orlofsky

スコア16419

answer CHANGED
@@ -1,4 +1,63 @@
1
1
  [ALTER TABLE ... ADD CONSTRAINT ... FOREIGN KEY(参照元カラム名) REFERENCES 参照先テーブル名 (参照先カラム名);
2
2
  ](https://teratail.com/questions/63031)
3
3
 
4
- 参照元カラムと参照先カラムの定義が違っていたりしませんか?
4
+ 参照元カラムと参照先カラムの定義が違っていたりしませんか?
5
+
6
+ 追記
7
+
8
+ 外部キーは親子関係にあるテーブルを指定することで、親に存在しないデータを
9
+ 子テーブルに入れさせないことでイレギュラーなデータを防ぐ機能です。
10
+
11
+ 以下、typoはお許しを
12
+
13
+ 準備
14
+ ```SQL
15
+ CREATE TABLE `parent_table`
16
+ (
17
+ `parent_id` INT NOT NULL,
18
+ , PRIMARY KEY (`parent_id`)
19
+ )
20
+ ENGINE=InnoDB;
21
+
22
+ CREATE TABLE `child_table`
23
+ (
24
+ `child_id` INT NOT NULL
25
+ , `parent_id` INT NOT NULL
26
+ , PRIMARY KEY (`child_id`)
27
+ , INDEX `idx_parent_id` (`parent_id`)
28
+ )
29
+ ENGINE=InnoDB ;
30
+
31
+ -- 初期データ
32
+ INSERT INTO `parent_table`(`parent_id`) VALUES(1) ;
33
+ INSERT INTO `child_table`(`child_id`, `parent_id`) VALUES(1, 1) ;
34
+ INSERT INTO `child_table`(`child_id`, `parent_id`) VALUES(2, 3) ; -- 親テーブルに存在しないデータ
35
+ COMMIT ;
36
+ ```
37
+ 外部キーを追加
38
+ ```SQL
39
+ ALTER TABLE `child_table`
40
+ ADD CONSTRAINT `parent_child_parent_id_fk` FOREIGN KEY `parent_id` REFERENCES `parent_table` (`parent_id`)
41
+ ```
42
+ と、親テーブルに存在しないデータがあるから、エラーになって外部キーを追加できない。
43
+
44
+ 副問合せで親キーが見つからないデータを特定する。
45
+ ```SQL
46
+ SELECT CT.`child_id`, CT.`parent_id`
47
+ FROM `child_table` CT
48
+ WHERE CT.`parent_id` NOT IN
49
+ (
50
+ SELECT PT.`parent_id` FROM parent_table` PT
51
+ )
52
+ ```
53
+ で、親データを追加するか、間違った小データをDELETEする。
54
+ ```SQL
55
+ DELETE FROM `child_table` CT
56
+ WHERE CT.`child_id` = 2 ;
57
+ COMMIT ;
58
+ ```
59
+ 改めて外部キーを追加する。
60
+ ```SQL
61
+ ALTER TABLE `child_table`
62
+ ADD CONSTRAINT `parent_child_parent_id_fk` FOREIGN KEY `parent_id` REFERENCES `parent_table` (`parent_id`)
63
+ ```