先建两个表,文章表(articles)和评论表(comments)。它们之间的关系是一对多,即一篇文章有多条评论。

1
2
3
4
5
6
7
8
9
CREATE TABLE `articles` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL DEFAULT '',
`author` varchar(255) NOT NULL DEFAULT '',
`content` text NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

1
2
3
4
5
6
7
8
9
10
CREATE TABLE `comments` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`art_id` int(11) unsigned NOT NULL,
`content` varchar(255) NOT NULL DEFAULT '',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `art_id` (`art_id`),
CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`art_id`) REFERENCES `articles` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

通过对比这两张表发现都是使用InnoDB引擎,因为MyISAM不支持外键。我们给comments表设置了外键art_id,对应articles表的主键,这两个字段类型必须保持一致,即都是int(11) unsigned

接下来分别插入数据

1
2
3
INSERT INTO `articles` (`id`, `title`, `author`, `content`, `created_at`, `updated_at`)
VALUES
(9, '第一章', 'jack', 'A long long time ago...', '2018-04-27 20:27:15', '2018-04-27 20:56:32');

1
2
3
INSERT INTO `comments` (`id`, `art_id`, `content`, `created_at`, `updated_at`)
VALUES
(1, 9, 'And then?', '2018-04-27 20:56:20', '2018-04-27 20:56:20');

可以看到此时评论表的art_id和文章表的id都是9。

然后我们试着更新一下文章表的主键

1
update articles set id = 1 where id = 9;

执行成功后,评论表里的art_id就变成1了。这就是外键,更多应用在级联约束的场景中,省去代码操作,MySQL直接解决了关联问题。