Ist es möglich, ENUM () -Listen zu ändern?

19

Ich war mir nicht sicher, ob das Ändern der ENUM () -Liste nicht möglich ist, also habe ich einen Test durchgeführt. In MySQL v5.1.58 habe ich eine InnoDB-Testtabelle erstellt, die ein Feld namens 'bool' vom Typ ENUM enthält ('yes', 'no').

Dann habe ich ausgeführt ...

ALTER TABLE  `test`
CHANGE  `bool`  `bool` ENUM(  'yes',  'no',  'maybe' )
CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL

...und es hat funktioniert.

Habe ich etwas falsch gemacht? Ist es abhängig von DB Engine?
Warum sagen alle, dass das Ändern einer ENUM () -Liste nicht möglich ist? z.B. hier http://komlenic.com/244/8-reasons-why-mysqls-enum-data-type-is-evil/

Aalex Gabi
quelle
3
Der Artikel, den Sie erwähnt haben, sagt nicht, dass es unmöglich ist; Es heißt, dass das Ändern der Mitgliederliste teuer ist, da die Engine einen vollständigen Tabellenscan durchführt.
a1ex07,
Ich habe Ihren Link bereits im Oktober über ENUMs erwähnt ( dba.stackexchange.com/a/6966/877 ). Darüber hinaus habe ich in MyISAM ( dba.stackexchange.com/a/6548/877 ) einen Verweis dazu veröffentlicht . InnoDB kommt in diesem Fall nicht in Frage.
RolandoMySQLDBA

Antworten:

14

Solange die Tabelle leer ist, gibt es kein Problem. Solange neue Werte für ENUM angehängt und bei einer aufgefüllten Tabelle nicht umbenannt werden, ist dies wiederum kein Problem.

Die ENUM, die Sie in Ihrer Frage neu definiert haben, hat tatsächlich die ursprünglichen internen Werte für yes und no beibehalten, da die Testtabelle diese zuletzt gespeichert hat.

Für ausgefüllte Tabellen gilt Folgendes:

Was ist damit?

ALTER TABLE  `test`
CHANGE  `bool`  `bool` ENUM(  'no',  'yes',  'maybe' )
CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL

Jetzt hast du ein Problem. Bei den ENUM-Werten in einer vollständig ausgefüllten Tabelle würden die internen Werte umgekehrt, sodass yes jetzt no und no jetzt yes ist.

Was ist damit?

ALTER TABLE  `test`
CHANGE  `bool`  `bool` ENUM(  'maybe', 'no',  'yes' )
CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL

Großes Problem. In einer bevölkerten Tabelle steht ja jetzt vielleicht. Neue mit yes eingefügte Zeilen werden von den vorherigen yes-Zeilen getrennt, da sie jetzt möglicherweise bedeuten.

ZUSAMMENFASSUNG

In MyISAM gibt es sehr risikoreiche Köder-und-Wechsel-Techniken, um dies sehr schnell zu tun . Ich würde dringend davon abraten, dies in InnoDB zu tun, da die Tablespace-ID mit ibdata1 interagiert.

RolandoMySQLDBA
quelle
Also werden diese intern als int basierend auf der Reihenfolge in der ENUM () gespeichert. Zum Beispiel speichert ENUM ('yes', 'no', 'maybe') intern 0 für 'yes', 1 für 'no', 2 für 'maybe'. Ich stelle mir vor, dass die Metadaten der Tabelle ENUM ('yes', 'no', 'maybe') anstelle von ENUM ('yes' => 0, 'no' => 1, 'maybe' => 2) lauten. Ist es wahr?
Aalex Gabi
ENUMs sind Zeichenfolgen, keine ganzen Zahlen: dev.mysql.com/doc/refman/5.0/en/enum.html
RolandoMySQLDBA
Ich bin damit einverstanden, dass ENUMs Zeichenfolgen sind, aber intern werden diese weder als Zeichenfolgen gespeichert, nicht wahr?
Aalex Gabi
1
Da hast du recht. In dem Link, den ich bereitgestellt habe, gibt es eine Zuordnung von Zeichenfolge zu Ganzzahl als Metadaten. Suchen Sie nach diesem Ausdruck: For example, a column specified as ENUM('one', 'two', 'three') can have any of the values shown here. The index of each value is also shown.und die Wert- / Indexzuordnung ist konzeptualisiert. Es würde also einen ENUM-Wert in einer Tabelle geben, die der internen Indexnummer zugeordnet ist. Durch Neuanordnen der Zeichenfolgen wird die Metadatenindizierung neu angeordnet. Dies ist kein gutes Zeichen für eine aufgefüllte Tabelle, wenn eine ENUM neu definiert wird.
RolandoMySQLDBA
2
Zumindest für MariaDB / InnoDB kann ich sagen, dass dies nicht mehr gültig ist. Ändern der Mitte von ENUM, solange keine Datensätze mit den zu entfernenden / zu ändernden Werten vorhanden sind, sollten die anderen Werte unverändert bleiben. Der einzige Vorteil ist, dass die Tabelle neu erstellt werden muss.
Nuno