È possibile modificare gli elenchi ENUM ()?


19

Non ero sicuro che cambiare l'elenco ENUM () non fosse possibile, quindi ho fatto un test. In MySQL v5.1.58 ho realizzato una tabella di test InnoDB che contiene un campo chiamato 'bool' di tipo ENUM ('yes', 'no').

Poi ho eseguito ...

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

... e ha funzionato.

Ho fatto qualcosa di sbagliato? Dipende dal motore db?
Perché tutti dicono che non è possibile modificare un elenco ENUM ()? per esempio. qui http://komlenic.com/244/8-reasons-why-mysqls-enum-data-type-is-evil/


3
L'articolo che hai citato non dice che è impossibile; dice che cambiare l'elenco dei membri è costoso perché il motore esegue la scansione completa della tabella.
a1ex07,

In ottobre ho menzionato il tuo link sugli ENUM ( dba.stackexchange.com/a/6966/877 ). Inoltre, ho pubblicato un riferimento su come eseguire questa operazione in MyISAM ( dba.stackexchange.com/a/6548/877 ). InnoDB è fuori discussione in questo caso.
RolandoMySQLDBA

Risposte:


14

Finché la tabella è vuota, non ci sono problemi. Finché vengono aggiunti nuovi valori per ENUM e non rinominati in base a una tabella popolata, di nuovo nessun problema.

L'ENUM che hai ridefinito nella tua domanda in realtà ha mantenuto i valori interni originali per yes e no come la tabella di test ha ricordato l'ultima volta.

Quanto segue si applica alle tabelle popolate:

Che dire di questo?

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

Ora hai un problema. I valori ENUM in una tabella completamente popolata avrebbero i loro valori interni invertiti in modo che sì sia ora no e no ora sia sì.

Che dire di questo?

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

Grande problema. In una tabella popolata, sì ora è forse. Le nuove righe inserite con yes vengono disconnesse dalle precedenti righe yes perché ora significano forse.

SOMMARIO

In MyISAM ci sono tecniche ad alto rischio, esca e scambia per farlo molto rapidamente . Consiglio vivamente di non farlo in InnoDB a causa della sua interazione con id del tablespace con ibdata1.


Quindi internamente quelli vengono archiviati come int in base all'ordine in ENUM (). Ad esempio, ENUM ('yes', 'no', 'maybe') memorizza internamente 0 per 'yes', 1 per 'no', 2 per 'forse'. Immagino che i metadati della tabella siano come ENUM ('sì', 'no', 'forse') invece di ENUM ('sì' => 0, 'no' => 1, 'forse' => 2). È vero?
Aalex Gabi,

Gli ENUM sono stringhe non numeri interi: dev.mysql.com/doc/refman/5.0/en/enum.html
RolandoMySQLDBA

Sono d'accordo che gli ENUM sono stringhe ma internamente non sono né archiviati come stringhe, no?
Aalex Gabi,

1
Hai ragione in questo. Nel link che ho fornito, c'è una mappatura della stringa in numero intero come metadati. Cerca questa frase: 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.e la mappa valore / indice è concettualizzata. Pertanto, ci sarebbe un valore ENUM in una tabella associata al numero di indice interno. Riorganizzare le stringhe riorganizzerà l'indicizzazione dei metadati. Questo non è di buon auspicio per una tabella popolata quando si ridefinisce un ENUM.
RolandoMySQLDBA

2
Almeno per MariaDB / InnoDB, posso dire che questo non è più valido. Cambiando la metà di ENUM, fintanto che non ci sono record con i valori che vengono rimossi / modificati, gli altri valori dovrebbero rimanere così come sono. L'unico vantaggio è che deve ricostruire la tabella.
Nuno,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.