SQL typ ENUM

Školení, která pořádám

Pro sloupce, které mohou mít hodnotu jen z povolené množiny, je v MySQL k dispozici typ ENUM. Osobně se tomuto typu nebráním a ve vhodných situacích ho používám. Určitě je přehlednější stav ENUM('na skladě', 'vyprodáno', 'předobjednávka') než stav CHAR(1) s možnými hodnotami S, V a P.

<?php
// nejasná data v databází a nepřehledný kód
$result = mysql_query("SELECT nazev, stav FROM vyrobky");
while ($row = mysql_fetch_assoc($result)) {
    echo "<li>$row[nazev] - ";
    switch ($row["stav"]) {
        case "S": echo "na skladě"; break;
        case "V": echo "vyprodáno"; break;
        case "P": echo "předobjednávka"; break;
    }
    echo "</li>\n";
}
mysql_free_result($result);

// využití typu ENUM
$result = mysql_query("SELECT nazev, stav FROM vyrobky");
while ($row = mysql_fetch_assoc($result)) {
    echo "<li>$row[nazev] - $row[stav]</li>\n";
}
mysql_free_result($result);
?>

Pokud se možné hodnoty sloupce mohou rozšiřovat nebo pokud se k nim mohou vztahovat další informace, je lepší pro ně vytvořit speciální tabulku (někdy se jí říká číselník). Místo skupina ENUM('Televize', 'Videa', 'Rádia') je tedy určitě lepší vytvořit tabulku skupiny(id INT, nazev VARCHAR(50)) a odkazovat se na ni přes skupina INT.

<?php
$result = mysql_query("
    SELECT vyrobky.nazev, skupiny.nazev AS skupiny_nazev
    FROM vyrobky
    INNER JOIN skupiny ON vyrobky.skupina = skupiny.id
");
while ($row = mysql_fetch_assoc($result)) {
    echo "<li>$row[nazev] - $row[skupiny_nazev]</li>\n";
}
mysql_free_result($result);
?>

Podle sloupce typu ENUM se v MySQL bohužel nedá spolehlivě třídit. Vyřešit se to dá myslím používáním kódu ORDER BY 1*typ, ale bohužel to nemohu ověřit, protože se mi chybu již nedaří reprodukovat. Pokud se ENUM použije v kontextu čísla (tedy např. ono 1*typ), použije se jeho číselná hodnota – 1 pro první hodnotu, 2 pro druhou a tak dále. Do každého sloupce typu ENUM lze uložit prázdný řetězec, kterému odpovídá číslo 0. Ten se použije také při pokusu o uložení neplatné hodnoty.

Přijďte si o tomto tématu popovídat na školení Návrh a používání MySQL databáze.

Jakub Vrána, Výuka, 6.7.2005, diskuse: 6 (nové: 0)

Diskuse

T3RMiX:

Malé rejpnutí, možná by bylo dobré se také zmínít ve spojitosti s  typem ENUM o typu SET.

ikona llook:

Taky bych uvítal článek o SET, hlavně o tom, jestli se dá nějak smysluplně využít. Chvíli jsem si s tím hrál a došel jsem k názoru, že jediná výhoda oproti INT je přehlednější INSERT dotaz.

T3RMiX:

No maličký popis je v jinak skvělém seriálu na Linux Software: http://www.linuxsoft.cz/article.php?id_article=784
A já například využívám SET jak zmiňuje autor - taky na ukládání oprávnění uživatele, pak se s tim docela pěkně pracuje.

ikona llook:

Právě na podobné věci používám INT. V tom co teď píšu může každý uživatel patřit do několika skupin (M:N) a uživatelova práva se získávají logickým součtem práv všech jeho skupin.
A když použiju BIT_OR na sloupec typu SET, tak dostanu integer a tak jako tak musím v PHP kouzlit s bitovými operátory.

Tak jsem si napsal třídu pro práci s bitovými poli a do DB už ukládám jenom INT, připadá mi to tak jednodušší.

ikona Jakub Vrána OpenID:

A není čistší na takovou strukturu použít číselník práv a spojovací tabulku (id_uzivatel, id_pravo)?

ViX612:

já jsem používal práva tak, že uživatelé byli organizováni v hierarchii a hotovo. Každý uživatel převzal práva od naduživatele, která byla relativní k jeho úrovni, příp. naduživatel přiděloval specifická práva.

Diskuse je zrušena z důvodu spamu.

avatar © 2005-2024 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.