Jeg har lavet nogle eksperimenter med det, du fortalte mig, og jeg tænkte, at jeg ville dele det som svar.
Først laver jeg nogle testtabeller:
CREATE TABLE foo (
foo_id int(10) unsigned NOT NULL,
PRIMARY KEY (foo_id)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci;
CREATE TABLE bar (
bar_id int(10) unsigned NOT NULL,
PRIMARY KEY (bar_id)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci;
CREATE TABLE foo_bar (
foo_id int(10) unsigned NOT NULL,
bar_id int(10) unsigned NOT NULL
)
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci;
Indtil videre findes der ingen indekser:
mysql> SHOW INDEXES FROM foo_bar;
Empty set (0.00 sec)
Tilføjelse af en primær nøgle genererer et indeks:
mysql> ALTER TABLE foo_bar
-> ADD PRIMARY KEY (`foo_id`, `bar_id`);
Query OK, 0 rows affected (0.70 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW INDEXES FROM foo_bar;
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| foo_bar | 0 | PRIMARY | 1 | foo_id | A | 0 | NULL | NULL | | BTREE | |
| foo_bar | 0 | PRIMARY | 2 | bar_id | A | 0 | NULL | NULL | | BTREE | |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
2 rows in set (0.02 sec)
Hvis jeg tilføjer en fremmednøgle på foo_id
den genbruger det primære nøgleindeks, da den kolonne er den første i indekset:
mysql> ALTER TABLE foo_bar
-> ADD CONSTRAINT `foo_bar_fk1` FOREIGN KEY (`foo_id`) REFERENCES `foo` (`foo_id`) ON DELETE CASCADE ON UPDATE CASCADE;
Query OK, 0 rows affected (0.27 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW INDEXES FROM foo_bar;
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| foo_bar | 0 | PRIMARY | 1 | foo_id | A | 0 | NULL | NULL | | BTREE | |
| foo_bar | 0 | PRIMARY | 2 | bar_id | A | 0 | NULL | NULL | | BTREE | |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
2 rows in set (0.00 sec)
Hvis jeg tilføjer en fremmednøgle på bar_id
, det opretter et indeks, fordi intet eksisterende indeks kan genbruges:
mysql> ALTER TABLE foo_bar
-> ADD CONSTRAINT `foo_bar_fk2` FOREIGN KEY (`bar_id`) REFERENCES `bar` (`bar_id`) ON DELETE CASCADE ON UPDATE CASCADE;
Query OK, 0 rows affected (0.25 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW INDEXES FROM foo_bar;
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| foo_bar | 0 | PRIMARY | 1 | foo_id | A | 0 | NULL | NULL | | BTREE | |
| foo_bar | 0 | PRIMARY | 2 | bar_id | A | 0 | NULL | NULL | | BTREE | |
| foo_bar | 1 | foo_bar_fk2 | 1 | bar_id | A | 0 | NULL | NULL | | BTREE | |
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
3 rows in set (0.02 sec)
En af vores fremmednøgler bruger det primære nøgleindeks. Det betyder, at vi ikke kan fjerne et sådant indeks!
mysql> ALTER TABLE foo_bar
-> DROP PRIMARY KEY;
ERROR 1025 (HY000): Error on rename of '.\test\#sql-568_c7d' to '.\test\foo_bar' (errno: 150)
Medmindre vi opretter et indeks for fremmednøglen eller vi dropper selve nøglen:
mysql> ALTER TABLE foo_bar
-> DROP FOREIGN KEY `foo_bar_fk1`;
Query OK, 0 rows affected (0.19 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE foo_bar
-> DROP PRIMARY KEY;
Query OK, 0 rows affected (0.23 sec)
Records: 0 Duplicates: 0 Warnings: 0
Konklusionen er, at MySQL opretter indekser automatisk, når de er nødvendige for en funktionalitet (men kun hvis de er strengt nødvendige).