关于创建外键,创建索引的问题

发布于 2022-09-06 05:08:10 字数 4600 浏览 16 评论 0

如下所示的三张表的创建过程, test1test2 分别有一个字段,然后作为各自表的主键,

test3 中有两个字段,分别作为外键引用 test1test2 中的场景,

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_namefield2 的索引,,这是什么原因??

我使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

江挽川 2022-09-13 05:08:10

外键在mysql系统里只是一个逻辑结构定义,为了性能考虑,mysql会自动为每个外键创建一个索引结构段,而你定义了两个外键,其中有一个已经是主键或者某个索引的组成部分,并且满足最左匹配原则,所以只会为你创建另外一个外键的索引

︶葆Ⅱㄣ 2022-09-13 05:08:10
  • 至少在MySQL5.6版本里,MySQL会自动给每个外键添加索引。

  • 如果是我自己,先建了一个联合主键索引(field1, field2),是不会再给最左列(field1)建独立索引的。原因是完全多余。我认为是MySQL机智地去掉了最左列field1的索引。

  • 建议看看MySQL的索引原理,B-tree,最左匹配等等

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文