在复合主键中使用时未创建 MySQL 外键

标签 mysql foreign-keys primary-key

CREATE TABLE test
(
  user_id int unsigned not null,
  post_id int unsigned not null,
  primary key (user_id, post_id),
  foreign key test_user_id (user_id) references user (id),
  foreign key test_post_id (post_id) references post (id)
);

show index from test;

+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name     | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test  |          0 | PRIMARY      |            1 | user_id     | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| test  |          0 | PRIMARY      |            2 | post_id     | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| test  |          1 | test_post_id |            1 | post_id     | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

添加 id 列作为主键会产生:

show index from test;

+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name     | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test  |          0 | PRIMARY      |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| test  |          1 | test_user_id |            1 | user_id     | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| test  |          1 | test_post_id |            1 | post_id     | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

使用由外键约束中使用的列组成的复合主键时,似乎未创建索引 test_user_id。应该是这样吗?有办法克服这个问题吗? (MySQL 5.7)

最佳答案

当您创建 FOREIGN KEY 约束时,必须有一个索引。如果有必要,创建 FOREIGN KEY 将自动创建一个新索引(至少从某些旧版本的 MySQL 如 4.0 或其他版本开始,但有一次,即使版本也不会自动创建 FK 索引 IIRC )。

但是如果合适的索引已经存在,MySQL不需要创建新索引。 InnoDB 至少是那么智能。

任何包含 FK 列作为索引最左侧子集的索引都将满足要求。 PRIMARY KEY 索引(即表的聚集索引)工作正常。

关于在复合主键中使用时未创建 MySQL 外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48121116/

相关文章:

sql - 复合主键是否也为每一列单独创建索引?

java - MySQL 查询限制子句中包含 Java 变量

PHP PDO 和 MySQL AGAINST() 函数

mysql - 主键附近的 SQL 语法错误

php - 识别关系相对于非识别关系的优缺点,反之亦然

c# - 主键错误陷阱

java - 由于基础异常 : 'java.lang.NumberFormatException: For input string: "localhost:330 6"' ,无法加载连接类

laravel - 在 laravel 中插入带有迁移的外键值 laravel

mysql - 使用组合键中的一列作为外键

kotlin - 使用Room Persistence库,我可以设置自己的主键并自己管理它的 “uniqueness”吗?