运行以下SQL语句之后,您会看到,在第一个ALTER TABLE
语句已运行后,MySQL自动为tag_id
列创建了非唯一索引question_tag_tag_id_tag_id
。MySQL忘记了为外键自动创建索引?
但第二ALTER TABLE
语句运行后,我觉得MySQL也应该自动对我question_id
列上创建一个非唯一索引question_tag_question_id_question_id
。
但是,从SHOW INDEXES
语句输出中可以看到,它不在那里。
为什么MySQL忘记第二个ALTER TABLE
声明?
顺便说一句,因为我已经创建由都question_id
和tag_id
列使用的唯一索引question_id_tag_id_idx
。为每个人创建一个单独的索引是多余的?
mysql> DROP DATABASE mydatabase;
Query OK, 1 row affected (0.00 sec)
mysql> CREATE DATABASE mydatabase;
Query OK, 1 row affected (0.00 sec)
mysql> USE mydatabase;
Database changed
mysql> CREATE TABLE question (id BIGINT AUTO_INCREMENT, html TEXT, PRIMARY KEY(id)) ENGINE = INNODB;
Query OK, 0 rows affected (0.05 sec)
mysql> CREATE TABLE tag (id BIGINT AUTO_INCREMENT, name VARCHAR(10) NOT NULL, UNIQUE INDEX name_idx (name), PRIMARY KEY(id)) ENGINE = INNODB;
Query OK, 0 rows affected (0.05 sec)
mysql> CREATE TABLE question_tag (question_id BIGINT, tag_id BIGINT, UNIQUE INDEX question_id_tag_id_idx (question_id, tag_id), PRIMARY KEY(question_id, tag_id)) ENGINE = INNODB;
Query OK, 0 rows affected (0.00 sec)
mysql> ALTER TABLE question_tag ADD CONSTRAINT question_tag_tag_id_tag_id FOREIGN KEY (tag_id) REFERENCES tag(id);
Query OK, 0 rows affected (0.10 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE question_tag ADD CONSTRAINT question_tag_question_id_question_id FOREIGN KEY (question_id) REFERENCES question(id);
Query OK, 0 rows affected (0.13 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW INDEXES FROM question_tag;
+--------------+------------+----------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+--------------+------------+----------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| question_tag | 0 | PRIMARY | 1 | question_id | A | 0 | NULL | NULL | | BTREE | |
| question_tag | 0 | PRIMARY | 2 | tag_id | A | 0 | NULL | NULL | | BTREE | |
| question_tag | 0 | question_id_tag_id_idx | 1 | question_id | A | 0 | NULL | NULL | | BTREE | |
| question_tag | 0 | question_id_tag_id_idx | 2 | tag_id | A | 0 | NULL | NULL | | BTREE | |
| question_tag | 1 | question_tag_tag_id_tag_id | 1 | tag_id | A | 0 | NULL | NULL | | BTREE | |
+--------------+------------+----------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
5 rows in set (0.01 sec)
mysql>
我明白了,这意味着我不必创建'question_id_tag_id_idx'索引,因为'question_id'列是聚簇索引中最左边的前缀模式之一,它已经可以用来查找' question_tag'表格由一个问题ID快速。但'tag_id'列没有,这就是为什么它需要一个单独的索引来快速查找'question_tag'表中的标签ID。它是否正确? – bobo 2010-03-12 01:48:45
@bobo'question_id_tag_id_idx'不需要,因为它只是重复主键。 'tag_id'需要单独的索引,因为它不会出现在'question_id_tag_id_idx'索引或主键的开头。 – 2010-03-12 10:04:49