2016-03-24 17 views
0

Ich habe eine Anwendung mit dem Laravel-Framework gebaut. Eine seiner Eigenschaften ist die Fähigkeit, polymorphe Beziehungen zwischen Tabellen zu erstellen. Dies geschieht durch Speichern der ID der verknüpften Tabelle und des vollständig qualifizierten Klassennamens des Modells der zugehörigen Tabelle. Wie Sie sich vorstellen können, können einige der Einträge abhängig von den Namespaces und dem Klassennamen des Modells ziemlich lang sein.MySQL Varchar Index Speicher

In meinem Szenario habe ich 4 Tabellen. Basistabelle A, die polymorph ist. Tabellen B, C und die nicht sind.

Die Klassennamen für die nicht polymorphe Tischmodelle wie folgt aus:

LongNamespace\SubNamespace\Something\B 
LongNamespace\SubNamespace\Something\C 
LongNamespace\SubNamespace\Something\D 

Ergebnisse aus Tabelle A aussehen würde:

id | relation_id | relation_type 
-------------------------------- 
1 | 1   | LongNamespace\SubNamespace\Something\B 
2 | 2   | LongNamespace\SubNamespace\Something\C 
3 | 5   | LongNamespace\SubNamespace\Something\D 
4 | 12   | LongNamespace\SubNamespace\Something\D 
5 | 3   | LongNamespace\SubNamespace\Something\B 
6 | 6   | LongNamespace\SubNamespace\Something\C 

... etc (around 50,000 rows) ... 

mit 38 Bytes pro Datensatz hinzugefügt, von denen die meisten wiederholt Daten, meine Frage ist, würde einen Index auf die relation_type Spalte speichern jeden einzelnen relation_type Datensatz einzeln im Speicher (was ich nehme, was passiert mit Indizes) oder wird es gruppieren sie wie ein ENUM so der Gesamtspeicher wäre die 3 eindeutigen Einträge in relation_type, die dann intern durch eine Hash-Tabelle irgendeiner Art verbunden werden, ergo spart n * 38 Bytes Speicherplatz.

Antwort

0

Ein Index enthält den gesamten Text aller indizierten Spalten plus (im Fall von InnoDB) den gesamten Text aller PRIMARY KEY Spalten. Also, 38 * n Bytes sind "verschwendet".

Wenn Sie erklärt relation_type

ENUM(`LongNamespace\SubNamespace\Something\B`, 
    `LongNamespace\SubNamespace\Something\C`, 
    `LongNamespace\SubNamespace\Something\D`, 
    ...) 

dann sei es auch nur 1 oder 2 Bytes dauern würde, aber sehr viel handeln, wie diese 39-Byte-Strings.

Es ist natürlich, Wartung Probleme, wenn Sie eine andere Tabelle, etc. hinzufügen

Auf der anderen Seite, 38 * 50K = ~ 2MB „klein“ ist, und nicht wirklich eine große Sache.

Nein, ein Index wird nicht im RAM gespeichert. Es wird jedoch Block für Block im RAM "zwischengespeichert". Wenn also der Index (oder die Tabelle) wirklich groß wäre, würde es aufgrund von Dingen, die nicht im Cache (RAM) bleiben, zusätzliche E/A geben. Aber es würde immer noch "funktionieren", wenn auch langsam.