Ukládání nastavení do databáze
Školení, která pořádám
Pokud chceme uložit globální nastavení aplikace do databáze, máme v zásadě dvě možnosti. První je vytvořit tabulku settings (name, value)
, kde name
je identifikátor a value
hodnota. Jaký ale hodnotě určit typ? Některá nastavení jsou číselná, jiná textová, další může být třeba datum a pokud se všemi budeme pracovat jako s textem, může to být někdy problém.
Proto jsem spíše příznivce přístupu, kdy se vytvoří jednořádková tabulka settings (promena_1, promena_2, …)
, ve které má každé nastavení svůj sloupec se správným typem. Výhodu vidím také v tom, že i při smazání dat z tabulky je patrné, jaké proměnné aplikace využívá. Pokud chceme na začátku aplikace všechna nastavení získat, je to otázka jednoho řádku, byť se správnou funkcí to samozřejmě není problém ani u prvního přístupu.
Výhoda ukládání nastavení do databáze je zřejmá – snadno lze vytvořit rozhraní pro jejich modifikaci a při použití správných datových typů se můžeme spolehnout na jejich platnost.
Diskuse
Borek:
Docela pěkné řešení jsou dva sloupce spolu s funkcí serialize().
Peters:
Co ale v pripade, ze pridam novy sloupec a musim navazne n to upravit vsechny INSERT a UPDATE prikazy? Je to efektivni pristup?
Pokud jsem to správně pochopil, tak celé nastavení aplikace je na jednom jediném řádku tabulky. Takže žádné inserty se nekonají. A pokud jde o updaty, tak si vždy updatuješ jen tu hodnotu co chceš, třeba UPDATE `settings` SET `nazev_sloupce`=123;
Je to efektivní přístup.
Andrew:
Dokážu představit "správnou funkci", kdy bude INSERT (potažmo UPDATE) fungovat také bez problémů (ad Peters), ale nepřijde mi to jako zas tak skvělé řešení.
Výhodu vidím v práci se správnými typy. Jako přínos už ale rozhodně nevidím názvy sloupců, jako proměnných. Od toho jsou třeba komentáře, abych se někde poznačil, s jakými proměnnými to pracuji. To je věc, kterou bych nemíchal do kódu. To první řešení považuji za více univerzálnější a adaptabilnější.
WhiteHat:
Ale někam musim uložit proměnné, které mám pro přístup k databázi. Kam s nimi?
Q:
A neni lepsi mit vse pohromade v jednom XML souboru?
um.Trip:
Souhlasím konfigurace pomocí xml mi také přijde jednodušší(tedy alespoň v ASP.NET).
Borek:
V ASP.NET je XML přirozenou cestou, v PHP by to však vyžadovalo napsání nějakého vlastního malého konfiguračního frameworku. Jelikož jsem si to na vlastní kůži zkusil, doporučuji ukládání konfigurace do databáze (i když se mi opravdu o dost víc líbí name-value tabulka spolu s funkcemi serialize a unserialize - pak lze bez problémů uložit třeba objekt nebo pole a není potřeba trápit se s mnoha sloupci).
Petr:
Souhlasím s užítím pře serialize, ale pak se ztrácí možnost efektivně měnit hodnoty jinak než PHPčkem, tedy např. přímým vstupem do databáze pře nějaký frontend.
uzivatel:
naco je v php funkcia parse_ini_file
na rozsiahle konfiguracne subory to je najkrajsia vec. vsetko pekne automaticky pouklada do pola
Ne, není (máš-li jiný názor, napiš proč myslíš že to je lepší).
Lukas:
Ty jsi to s temi argumenty taky neprehnal.
a) Pokud je nastaveni ulozene v souboru na disku, tak vsechno, co potrebujete, je textovy editor. Zatimco u databaze si musite bud napsat skript na editaci nastaveni (pokud se to nastaveni tyka jen veci, se kterymi dela programator, tak nema moc smysl k tomu uzivatelsky rozhrani delat) nebo nainstalovat phpMyAdmin - jedno horsi nez druhe
b) Uz ze same podstaty nastaveni vyplyva, ze jednotlive hodnoty jsou jednak ruzneho typu (coz se tady neobratne resi) a ze maji stromovy charakter (coz se proste v tabulce dela dost ztuha) a navic je vhodne tam implementovat dedeni defaultnich hodnot ("kdyz neni vyplnena mailova adresa na zasilani automatickeho hlaseni chyb, tak se pouzije adresa webmastera"), XML odpovida tomuhle ucelu naprosto jednoznacne
Martin:
Jak myslite to pouziti "serialize"?
Hever:
Podívej se na
http://php.net/serialize a mělo by ti to být jasné.
Serialize používám (a to na dost bestiální pole proměnných a objektů) a jsem s ním spokojený :)
@ss@ssIn:
Dost velka bacovina je settings ( name, value, type) :) [neefektivne na DB, ale je jasne aky to je typ]
Ale povedal by som, ze vsetko zalezi od poctu a typov premennych...
Dalo by sa to riesit kludne aj jednou tabulkou pre kazdy typ a v hodnoty ziskavat pomocou funkcie
<?php
Constructor(){ // inicializacia hodnot
$result = mysql_query( "SELECT * FROM int_settings;");
while( $row = mysql_fetch_assoc( $result)){
$this->int[ $row['name']] = $row['value'];
}
}
GetValue( $name, $default){ // ziskanie hodnoty
if( is_numeric( $default) && isset( $this->vars['int'][$name])){
return $this->int[$name];
}
// ...
php?>
takto by sa dali pomerne lahko pridavat hodnoty a bola by osetrena aj 'neznalost' hodnoty. Myslim, ze tych tabuliek nebude vela. Vecsinou sa asi aj tak pouzivaju int, text a mozno par varchar (datatime, binary, enum by sa tak ci tak prehlasovali za text...)
FantomX1:
Rad by som vedel ako by sa takto riesila viacjazycna stranka, aby sa dali jazyky ulozene v databaze editovat cez webove rozhranie. Totiz niektore texty mozu byt kratsie a preto nie je myslim rozumne pre ne pouzit typ stlpca TEXT ako sa to teda uklada do pamete? ten text sa nejak oseka alebo sa to ulozi aj s dodatocnymi znakmi?
kdesi som si totiz cital, ze ked dam stlpec typu CHAR(40), tak je jedno ze string bude dlhy 20 znakov, ostatne znaky do db proste doplni aby to malo prave 40 znakov, to ake to budu neviem, ale mozno znak null.
Diky za rady
Typ char se takto skutečně podle normy chová (v MySQL jen za určitých podmínek), typ varchar ale zabere vždy jen tolik, kolik je potřeba.
peta:
Ja jsem zas cetl neco v tom smyslu, ze je lepsi pevna delka promenne, ze to SQL nejak rychleji zpracovava.
Literatura PHP a MySQL, vytvarime webove aplikace, O'Reily. Silne nedoporucuji, ma to 500 stran a v dnesnim MySQL se to neda pouzit, ale zrovna s touto vetou o pevne delce promenne bych souhlasil.
peta:
Resp takto, psali tam o typu BLOB a TEXT, ze se jim vyhybat. VARCHAR asi pouzit lze.
fisT:
Ja som tiez rozmysall o ulozeni nastaveni do DB a prisiel som na jednu vec ze by bolo dobre vytvorit si DB so stlcami name, type a pre kazdy type jeden dalsi stlpec. No a ked sa astavenia nacitavju tak sa zisti type a z jednotliveho stlpca sa hodnota vyberie :)
No vidíš, a mně osobně zase přijde lepší právě ono:
CREATE TABLE config (
param VARCHAR(30) NOT NULL COLLATE ascii_bin,
value VARCHAR(255),
PRIMARY KEY(param)
)
Proč? Sice jednu dobu jsem taky tíhnul k jednořádkovému konfiguračnímu záznamu, jenže ona tahle struktura zrovna dvakrát neodpovídá filosofii databází - a já rád, když se technologie neznásilňují na něco, na co nejsou určené. Považuju to za čuňárnu podobného ražení, jako vytvářet tabulku práv pro každého uživatele zvlášť. IMHO
Základní problém této struktury je ten, že dovoluje ukládat jen VARCHAR(255). Když chceš uložit třeba datum nebo číslo, musíš ho převést na řetězec, což především je proti filozofii databází.
Mnohasloupcové uspořádání bych shrnul takhle:
výhody:
- možnost zvolit datový typ pro každou hodnotu
- i v prázdné tabulce jsou vidět názvy konfiguračních parametrů
- načtení všech dat jedním voláním mysql_fetch_*
nevýhody:
- většinou dost neohrabané zobrazení při procházení tabulky (hodnoty vedle sebe)
- při přidání konfiguračního parametru je nutné upravit strukturu tabulky
- nutné zajistit vždy právě jeden záznam. Na to je zase lepší ona dvousloupcová metoda, kde se nad sloupcem "param" vytvoří unikátní index, a potom jenom vesele REPLACE INTO...
Obě metody mají svá pro a proti.
Z praktického pohledu to tak je, hodnoty vedle sebe se dají v konzoli vyřešit použitím \G místo ;. Z teoretického pohledu je ale ukládání hodnot do sloupců špatného datového typu prostě nepřípustné.
Diskuse je zrušena z důvodu spamu.