关于创建外键,创建索引的问题
如下所示的三张表的创建过程, test1
和 test2
分别有一个字段,然后作为各自表的主键,
test3
中有两个字段,分别作为外键引用 test1
和 test2
中的场景,
mysql> create table test1(field1 int, primary key(field1));
Query OK, 0 rows affected (0.04 sec)
mysql> create table test2(field2 int, primary key(field2));
Query OK, 0 rows affected (0.00 sec)
mysql> create table test3(field1 int ,field2 int,primary key(field1,field2),foreign key(field1) references test1(field1), foreign key(field2) references test2(field2));
Query OK, 0 rows affected (0.06 sec)
mysql> show index from test3;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test3 | 0 | PRIMARY | 1 | field1 | A | 0 | NULL | NULL | | BTREE | | |
| test3 | 0 | PRIMARY | 2 | field2 | A | 0 | NULL | NULL | | BTREE | | |
| test3 | 1 | field2 | 1 | field2 | A | 0 | NULL | NULL | | BTREE | | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set (0.00 sec)
mysql>
这里在最后使用 show index from test3
时,会出现一个 Key_name
为 field2
的索引,,这是什么原因??
我使用 show create table test3
,查看创建表的语句,MySQL 隐示的给我创建了该索引,感觉很奇怪
CREATE TABLE `test3` (
`field1` int(11) NOT NULL DEFAULT '0',
`field2` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`field1`,`field2`),
KEY `field2` (`field2`),
CONSTRAINT `test3_ibfk_1` FOREIGN KEY (`field1`) REFERENCES `test1` (`field1`),
CONSTRAINT `test3_ibfk_2` FOREIGN KEY (`field2`) REFERENCES `test2` (`field2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
我尝试过很多创建表的操作,修改 primary key(field1, field2)
为 primary key(field2,field1)
,即简单的调换顺序后,这里的索引由 field2
变为 field1
。
例如,我不定义主键,定义两个外键,会有两个索引被创建:
mysql> create table test3(field1 int ,field2 int,foreign key(field1) references test1(field1), foreign key(field2) references test2(field2));
Query OK, 0 rows affected (0.05 sec)
mysql> show index from test3;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test3 | 1 | field1 | 1 | field1 | A | 0 | NULL | NULL | YES | BTREE | | |
| test3 | 1 | field2 | 1 | field2 | A | 0 | NULL | NULL | YES | BTREE | | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set (0.00 sec)
然后,我使用其中的一列作为主键,并且两列都为一个外键,会有一个索引,
mysql> create table test3(field1 int ,field2 int,primary key(field1),foreign key(field1) references test1(field1), foreign key(field2) references test2(field2));
Query OK, 0 rows affected (0.31 sec)
# 查看创建语句如下
CREATE TABLE `test3` (
`field1` int(11) NOT NULL DEFAULT '0',
`field2` int(11) DEFAULT NULL,
PRIMARY KEY (`field1`),
KEY `field2` (`field2`),
CONSTRAINT `test3_ibfk_1` FOREIGN KEY (`field1`) REFERENCES `test1` (`field1`),
CONSTRAINT `test3_ibfk_2` FOREIGN KEY (`field2`) REFERENCES `test2` (`field2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
而在使用两列一起作为主键时,为什么还是会有一个field2
索引呢,
在我的理解中,应该是两个才对,就算,因为主键的原因,那也应该是有既没有 field1
,也没有 field2
,只有一个 PRIMARY
的索引才对。???
原始的场景不是这个样子,不过跟上述的示例能够表达我的疑惑了,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
外键在mysql系统里只是一个逻辑结构定义,为了性能考虑,mysql会自动为每个外键创建一个索引结构段,而你定义了两个外键,其中有一个已经是主键或者某个索引的组成部分,并且满足最左匹配原则,所以只会为你创建另外一个外键的索引
至少在MySQL5.6版本里,MySQL会自动给每个外键添加索引。
如果是我自己,先建了一个联合主键索引(field1, field2),是不会再给最左列(field1)建独立索引的。原因是完全多余。我认为是MySQL机智地去掉了最左列field1的索引。
建议看看MySQL的索引原理,B-tree,最左匹配等等