MySQL:`SHOW INDEX`显示的不同于`SHOW CREATE TABLE`

时间:2017-01-31 14:47:08

标签: mysql

我试图理解为什么没有像我预期的那样创建索引。我正在调查当我在现有外键上创建HASH索引时发生的事情。

create table users (id int, primary key(id));
create table temp (id int not null, primary key(id), user_id int(11) default null);

目前还没有外键。 show create table temp;输出您期望的内容:

| temp  | CREATE TABLE `temp` (
  `id` int(11) NOT NULL,
  `user_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |

show index from temp

+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| temp  |          0 | PRIMARY  |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

一切都很好。现在让我们添加一个FK:

alter table temp add foreign key key_name (user_id) references users (id);

这向我们展示show create table temp;

| temp  | CREATE TABLE `temp` (
  `id` int(11) NOT NULL,
  `user_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `key_name` (`user_id`),
  CONSTRAINT `temp_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |

show index from temp;

+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| temp  |          0 | PRIMARY  |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| temp  |          1 | key_name |            1 | user_id     | A         |           0 |     NULL | NULL   | YES  | BTREE      |         |               |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

到目前为止一直很好:我们添加了一个外键约束,MySQL自动添加了一个BTREE索引,用于强制执行约束。

现在我希望该索引成为HASH,所以我要添加它:

create index index_name using hash on temp (user_id);

这就是奇怪的地方。按预期KEY (...) USING HASH时,您可以看到show create table temp条目:

| temp  | CREATE TABLE `temp` (
  `id` int(11) NOT NULL,
  `user_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_name` (`user_id`) USING HASH,
  CONSTRAINT `temp_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |

但是当你show index from temp;

+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name   | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| temp  |          0 | PRIMARY    |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| temp  |          1 | index_name |            1 | user_id     | A         |           0 |     NULL | NULL   | YES  | BTREE      |         |               |
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

没有改变!索引仍然是BTREE!。

这里发生了什么?

编辑:有人提请我注意,create index ...可能与alter table add index ...不一样。好吧,我试过了,他们当然也在做同样的事情。 alter table temp add index (user_id) using hash导致

| temp  | CREATE TABLE `temp` (
  `id` int(11) NOT NULL,
  `user_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_name` (`user_id`) USING HASH,
  KEY `user_id` (`user_id`) USING HASH,
  CONSTRAINT `temp_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |



+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name   | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| temp  |          0 | PRIMARY    |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| temp  |          1 | index_name |            1 | user_id     | A         |           0 |     NULL | NULL   | YES  | BTREE      |         |               |
| temp  |          1 | user_id    |            1 | user_id     | A         |           0 |     NULL | NULL   | YES  | BTREE      |         |               |
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

1 个答案:

答案 0 :(得分:3)

InnoDB存储引擎仅支持BTREE索引,而不支持HASH索引。

当您尝试创建HASH索引时,它会将索引静默转换为BTREE