Indizes auf primary und foreign keys
Ich habe eine Datenbank erstellt mit einem GUI-tool und ich habe bemerkt, was scheint, eine inkonsistente Verwendung von KEY
(aka INDEX
) Definitionen:
CREATE TABLE `foo_bar` (
`foo_id` int(10) unsigned NOT NULL,
`bar_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`foo_id`, `bar_id`),
KEY `foo_bar_fk2` (`bar_id`), -- <== ???
CONSTRAINT `foo_bar_fk1` FOREIGN KEY (`foo_id`) REFERENCES `foo` (`foo_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `foo_bar_fk2` FOREIGN KEY (`bar_id`) REFERENCES `bar` (`bar_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci COMMENT='Links between Foo and Bar';
Habe ich die folgenden Fragen zu Indizes:
- Ist es notwendig, explizit zu definieren, die Indizes für primär-und Fremdschlüssel?
- Wenn es nicht, tun Sie tatsächlich bekommen zwei Indizes (und weniger Leistung)?
- Ist es anders in InnoDB-und MyISAM - (foreign keys abgesehen)?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Habe ich einige Experimente an, was Sie mir erzählt und ich dachte, dass ich teilen würde, es als Antwort.
Ersten ich einige test-Tabellen:
Bisher keine Indizes vorhanden:
Hinzufügen Primärschlüssel erzeugt einen index:
Wenn ich einen foreign key auf
foo_id
es nutzt die primary key-index seit dieser Spalte ist die erste in den index:Wenn ich einen foreign key auf
bar_id
es erstellt einen index, da keine vorhandene index wiederverwendet werden können:Einer unserer ausländischen Tasten ist mit Hilfe der primary key-index. Das bedeutet, dass wir nicht zu entfernen, wie index!
Es sei denn, wir erstellen einen index für den Fremdschlüssel oder ziehen wir die Schlüssel selbst:
Die Schlussfolgerung ist, dass MySQL erstellt Indizes automatisch, wenn Sie verpflichtet sind, die für eine Funktionalität (aber nur, wenn Sie absolut notwendig sind).
Den foreign key Indizes werden verwendet, um referenzielle Einschränkungen.
Ermöglichen Sie Ihnen, zu definieren, die cascade-delete-Klauseln, so dass das löschen einer Zeile aus der übergeordneten Tabelle werden Zeilen löschen von child-Tabellen. Es kann auch verwendet werden, um sicherzustellen, dass wenn Sie versuchen, erstellen Sie eine Zeile in der untergeordneten Tabelle verknüpft werden können, um einem Elternteil (also der
Childrow.ParentId
gültig ist)Edit: Ah sorry, habe ich missverstanden. InnoDB erstellt automatisch Indizes für Fremdschlüssel. Sehen nicht-mysql-index-foreign-key-Spalten-automatisch
KEY foo_bar_fk2 (bar_id)
Teil, d.h., der index-definition. Der Zweck der primär-und Fremdschlüssel ist klar.1) Primärschlüssel werden automatisch indexiert, in mysql.
2) Siehe oben, nicht notwendig, es zu tun
3) MyISAM unterstützt keine Einschränkungen. (Ich glaube, Sie haben gesagt, dass implizit, so ist dies mehr für andere zum Lesen drüber). Einige grafische tools wie MySQL Workbench verursachen keine Warnungen, wenn Sie versuchen, verwenden Sie die Fremdschlüssel mit MyISAM, aber offensichtlich nicht erstellen.
Btw: Welche GUI benutzt du (auf dem OS)?
Gut zu Lesen: data-warehousing-whitepaper (enthält einen Vergleich der MyISAM-und InnoDB-Tabellen)