ENUM () listelerini değiştirmek mümkün müdür?


19

ENUM () listesini değiştirmenin mümkün olmadığından emin değildim, bu yüzden bir test yaptım. MySQL v5.1.58'de ENUM türünde 'bool' adı verilen bir alan içeren bir test InnoDB tablosu yaptım ('evet', 'hayır').

Sonra idam ettim ...

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

... ve işe yaradı.

Yanlış bir şey yaptım mı? DB motoruna bağlı mı?
Neden herkes ENUM () listesinin değiştirilmesinin mümkün olmadığını söylüyor? Örneğin. burada http://komlenic.com/244/8-reasons-why-mysqls-enum-data-type-is-evil/


3
Bahsettiğiniz makale bunun imkansız olduğunu söylemiyor; motor tam masa taraması yaptığı için üye listesini değiştirmenin pahalı olduğunu söylüyor.
a1ex07

Bağlantınızdan Ekim ayında ENUM'lar hakkında bahsettim ( dba.stackexchange.com/a/6966/877 ). Ayrıca, MyISAM'de ( dba.stackexchange.com/a/6548/877 ) bunun nasıl yapılacağı konusunda bir referans yayınladım . Bu örnekte InnoDB söz konusu değildir.
RolandoMySQLDBA

Yanıtlar:


14

Tablo boş olduğu sürece sorun yoktur. ENUM için yeni değerler eklendiği ve doldurulmuş bir tablo verildiğinde yeniden adlandırılmadığı sürece, yine sorun değil.

Sorunuzda yeniden tanımladığınız ENUM, test tablosunun en son hatırladığı gibi aslında evet ve hayır için orijinal dahili değerleri korudu.

Doldurulmuş tablolar için aşağıdakiler geçerlidir:

Peki buna ne dersin?

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

Şimdi bir sorunun var. Tamamen doldurulmuş bir tablodaki ENUM değerleri iç değerlerini tersine çevirir, böylece evet şimdi hayır ve hayır şimdi evet olur.

Peki buna ne dersin?

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

Büyük sorun. Doldurulmuş bir tabloda, evet şimdi olabilir. Evet ile eklenen yeni satırlar, şimdi belki anlamına geldiği için önceki evet satırlarından ayrılır.

ÖZET

MyISAM'de bunu çok hızlı yapmak için çok yüksek riskli, yem ve anahtar teknikleri vardır . Ibdata1 ile tablo alanı kimliği etkileşimi nedeniyle bu InnoDB bunu yapmamanızı şiddetle tavsiye ediyorum.


Böylece dahili olarak ENUM () içindeki sıraya göre int olarak depolanırlar. Örneğin ENUM ('evet', 'hayır', 'belki') dahili olarak 'evet' için 0, 'hayır' için 1, 'belki' için 2 saklar. Tablonun meta verilerinin ENUM ('evet' => 0, 'hayır' => 1, 'belki' => 2) yerine ENUM ('evet', 'hayır', 'belki') gibi olduğunu düşünüyorum. Bu doğru mu?
Aalex Gabi

Enums dizeleri değil tam sayılardır: dev.mysql.com/doc/refman/5.0/en/enum.html
RolandoMySQLDBA

ENUMs dizeleri olduğunu kabul ediyorum ama dahili olarak ne de dizeleri olarak saklanır değil mi?
Aalex Gabi

1
Bunda haklısın. Sağladığım bağlantıda, dizenin meta veri olarak tamsayıya eşlenmesi var. Şu ifadeyi arayın: 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.ve değer / dizin haritası kavramsallaştırılmıştır. Dolayısıyla, dahili indeks numarası ile ilişkili bir tabloda ENUM değeri olacaktır. Dizeleri yeniden düzenlemek, meta veri dizine eklemeyi yeniden düzenler. Bu, bir ENUM öğesini yeniden tanımlarken doldurulmuş bir tablo için iyi sonuç vermez.
RolandoMySQLDBA

2
En azından MariaDB / InnoDB için, bunun artık geçerli olmadığını söyleyebilirim. ENUM'un ortasını değiştirmek, kaldırılan / değiştirilen değerlerle ilgili kayıt olmadığı sürece, diğer değerlerin olduğu gibi kalması gerekir. Tek avantajı masayı yeniden inşa etmesidir.
Nuno
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.