Ukládání nastavení do databáze
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().
9.6.2006 05:24:27
Peters:
Co ale v pripade, ze pridam novy sloupec a musim navazne n to upravit vsechny INSERT a UPDATE prikazy? Je to efektivni pristup?
9.6.2006 11:52:14
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.
9.6.2006 22:04:31
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ší.
9.6.2006 12:23:14
WhiteHat:
Ale někam musim uložit proměnné, které mám pro přístup k databázi. Kam s nimi?
9.6.2006 13:10:18
Q:
A neni lepsi mit vse pohromade v jednom XML souboru?
9.6.2006 13:45:36
um.Trip:
Souhlasím konfigurace pomocí xml mi také přijde jednodušší(tedy alespoň v ASP.NET).
9.6.2006 14:55:14
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).
9.6.2006 15:25:06
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.
9.6.2006 18:01:08
uzivatel:
naco je v php funkcia parse_ini_file
na rozsiahle konfiguracne subory to je najkrajsia vec. vsetko pekne automaticky pouklada do pola
14.6.2006 04:10:37
Ne, není (máš-li jiný názor, napiš proč myslíš že to je lepší).
9.6.2006 22:06:05
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
10.6.2006 03:49:56
Martin:
Jak myslite to pouziti "serialize"?
9.6.2006 17:55:00
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ý :)
9.6.2006 19:42:13
@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...)
9.6.2006 17:57:29
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
9.6.2006 23:15:29
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.
13.6.2006 13:29:53
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.
13.6.2006 22:49:12
peta:
Resp takto, psali tam o typu BLOB a TEXT, ze se jim vyhybat. VARCHAR asi pouzit lze.
13.6.2006 22:51:16
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 :)
2.2.2007 02:06:56
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
3.8.2007 20:13:48
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í.
5.8.2007 00:35:19
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.
5.8.2007 03:11:14
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é.
5.8.2007 11:53:06