Struktura databáze pro tabulku s různými sloupci

Honza

Struktura databáze pro tabulku s různými sloupci
« kdy: 30. 03. 2013, 11:38:12 »
Zdravím,

potřeboval bych radu. Snažím se vytvořit strukturu databáze pro na první pohled jednoduchou tabulku. Tabulku se pokusím ilustrovat na příkladu:

pásmo/rok  2000  2001  2002  2003
1. pásmo    5       8       2       1
2. pásmo    6       7       5       3
3. pásmo    1       9       3       2
...

Problém je, že potřebuji, aby uživatel mohl všechna data v tabulce upravovat a takovýchto tabulek vytvořit víc v jedné db. V praxi to znamená, že uživatel si vytvoří takovouto tabulku, ve které nic nebude. Přidá do ní roky (libovolný počet) a přidá pásma (taktéž libovolně) a poté tabulku naplní daty. Pak takhle udělá další atd.

Lámu si hlavu s tím, jak tyto tabulky převéct do databáze, abych umožnil takovouto editaci jedné tabulky, aniž by se zasahovalo do ostatních. Myslel jsem že si vytvořím čtyři tabulky: 'tables', 'years', 'zones', 'values' a ty pak propojím přes id, ale takové řešení mi připadá krajně nepřehledné a především bude spousta duplicitních záznamů (především roků, protože můžou být stejné v různých tabulkách, ale i pásem, které se taky mohou shodovat).

Měl by někdo čas a chuť mě nakopnout nějakým nápadem jak to všechno rozchodit?
Ještě dodám že pracuji s db PostgreSQL 8.4 a PHP 5.3, ale nejde mi ani tak o kód jako o samotnou strukturu.

Předem díky!


Karlos

Re:Struktura databáze pro tabulku s různými sloupci
« Odpověď #1 kdy: 30. 03. 2013, 12:38:21 »
Tvoje řešení mi přijde jako optimální. Budeš mít tabulky Tables, Years, Zones se svými ID a čímkoliv dalším a to vše spojíš do jedné tabulky Values referencema. Když chceš, aby jakákoliv hodnota na jakékoliv pozici byla updatovatelná, nemůžeš mluvit o duplicitách. Navíc když bude tabulka Values složená jen  integerů (cizí klíče), budou selecty dost rychlý.

Honza

Re:Struktura databáze pro tabulku s různými sloupci
« Odpověď #2 kdy: 30. 03. 2013, 12:52:27 »
Díky za velmi rychlou odpověď,

pokusím se teda tohle řešení implementovat. Dám vědět jak se zadařilo ;)

Karlos

Re:Struktura databáze pro tabulku s různými sloupci
« Odpověď #3 kdy: 30. 03. 2013, 13:29:11 »
Jo ještě tohle je klasické spojení tabulek 1:n, či spojení dvou tabulek m:n přes další tabulku nebo tak nějak, když tak mě opravte. Prostě chci říct, že se to tak běžně dělá. Zdánlivou složitost při selectech si můžeš velmi zjednodušit vytvořením view. Updaty pak taky nejsou o nic horší, operuješ nad taulkou Values, kde dáš něco jako update value from Values where id_table=... and id_year=... and id_zone=...

alexejkl@seznam.cz

Re:Struktura databáze pro tabulku s různými sloupci
« Odpověď #4 kdy: 30. 03. 2013, 23:43:59 »
Ahoj,
mozna by stacily dve tabulky
1) ID, identifikace uzivatele, identifikace tabulky
2) Identifikace tabulky z 1), rok, pásmo a hodnota
 - myslenka je v tom, ze
   - rok musi byt pro tabulku (asi) unikatni - takze je zbytecne mit tabulku s roky a z ni brat ID - tim nic neusetris (proste rok je misto ID. Pokud bys to hnal pres jeste jednu tabulku, tak je sice pravda, ze se vyhnes duplicitnmim zaznamum roku, ale stejne tam budes mit 'duplicitni zaznamy' ID, takze to vyjde nastejno, ale zjednodusis si vysledny join.
   - to same s pasmy - muzes tam davat hodnoty 1, 2 ... n - je to stejne jako mit nekde 1. pasmo, 2. pásmo apod. - jenom na vystupu pak doplnis 1 => 1. pasmo
   - tak jako tak tam budes mit unikatni klic id z 1) + rok + pasmo

Skus si to navrhnout pro oba pripady a uvidis - to vyzkouseni by nemelo stat moc casu

Alexej


Waseihou

Re:Struktura databáze pro tabulku s různými sloupci
« Odpověď #5 kdy: 31. 03. 2013, 08:56:49 »
Kacířská myšlenka: má opravdu cenu snažit se vždy o nějakou optimalizaci a normalizaci databázového schématu?

Pokud je jediným účelem databáze perzistence objektů doménového modelu, lze zvážit i použití některé z metod mapování doménového module do databáze, tak jak je to pospáno třeba v knize od Fowlera:

Single table inheritance (str. 278)

ftp://ftp.heanet.ie/mirrors/sourceforge/w/we/webtune/Patterns%20of%20Enterprise%20Application%20Architecture.pdf

V tomto případě vytvoříš jednu obrovskou tabulku, která bude obsahovat různé datové typy, se sloupečky pojmenovanými podle členských proměnných, případně dokonce můžeš vytvořit tabulku se sloupečky text1, text2, text3..., date1, value1, value2, value3,... ,date1,date2, date3,...

případně u těch textů mít několik krátkých textových polí a několik dlouhých.

Nejsem si jistý, ale PostgreSQL funguje v některých ohledech podobně jako Oracle, takže nad touto obecnou tabulkou možná půjde vytvořit view které bude obsahovat sloupečky pojmenované podle tvé členských atributů tvé třídy, a přitom nad tímto view půjde dělat CRUD (tedy insert, select, update i delete). Mapování pak provedeš v PHP v nějaké bázové tříde ze které podědíš své objekty, ty budou deklarovat viewčko (a případně membery) do kterého se to bude cpát a možná nějaké metody které se zavolají po načtení objektu z databáze.

Kromě sloupečků z daty by tvá tabulka měla také obsahovat sloupečky ve stylu i_user, i_date, u_user, u_date a e_cnt kde i_user bude uživatel který vložil sloupeček, i_date kdy to vytvářel, u_user je uživatel který to naposledy editoval a u_date je čas editace, e_cnt je pak počítadlo změn pro optimistické zamykání, to bude jako member v bázové třídě a při načtení objektu se uloží. Pokud uživatel bude editovat záznam a změny uloží, tak nejdříve ověří jestli je e_cnt pořád stejné jako jeho member, a pokud ano tak jej při ukládání zvyší o 1. Pokud ale stejné není, někdo ty data změnil a on musí tuto situaci řešit (zahodit změny, udělat nějaký merge,...).

Toto je celkem obecné schéma řešení perzistence, overkill, ale jak se ti bude doménový model aplikace rozrůstat, ušetří ti to spoustu problémů. Jedná se vlastně o základ jedoduchého frameworku, a pak se naskýtá otázka, jestli nějaký nepoužít. Pokud ale nemůžeš a se psaním teprve začneš, zvaž i tuto možnost.

Waseihou

Re:Struktura databáze pro tabulku s různými sloupci
« Odpověď #6 kdy: 31. 03. 2013, 09:13:52 »
Jo a ještě jsem zapoměli na samozřejmé sloupečky ID objektu a jméno jeho třídy, taky nějaký sloupeček/y pro reference mezi objekty. Ano, je to těžce nenormalizované, ale primitivní a snadno použitelné. Pro menší až střední objemy dat to bude dostačovat. Databáze je jenom datové úložiště, netřeba vždy řešit JAK jsou objekty uloženy, při dobrém návrhu (data mapper) to celé půjde v případě potřeby přepsat a přemigrovat na úplně jiný typ úložistě (NoSQL databáze, XML soubor, SAP HANA, ...) aniž by byla nutná změna doménového modelu, tedy hierarchie tříd reperezentující bussiness model.

A sorry za přepklepy... ;)

Waseihou

Re:Struktura databáze pro tabulku s různými sloupci
« Odpověď #7 kdy: 31. 03. 2013, 09:56:16 »
No a jak bude vypadat třída?

Nejprimitivnější samozřejmě bude dát všechno jako membery, tedy:

Kód: [Vybrat]
class Base {
  public $_ID;
  public $_members;
  // composite
  public $_children;
  /* ... */
}

class MyObject extends Base {
  protected $zone;
  protected $year;
  protected $value;

  public function init() {
    $_members = array('zone','year','value');
  }
  /* ... getters and setters, bussiness operations */
}

class DataMapper {
  public function persist(Object &$obj) {
    $obj_class = get_class($obj);
    if ($obj_class == "MyObject") {
       $main_table = 'general';
    } else if (obj_class == 'BigObject') {
       $main_table = 'object_specific_table'
    }
    /* CRUD to $obj_class to $main_table ... */
  }
}
Tabulku lze potom reprezentovat podle návrhového vzoru composite, tedy udělat třeba objekt reprezentující tabulku, ten bude obsahovat pole objektů reprezentujících řádky tabulky a ty budou obsahovat pole se samotnými objekty.

jsf

Re:Struktura databáze pro tabulku s různými sloupci
« Odpověď #8 kdy: 31. 03. 2013, 11:30:27 »
Mimochodem, premyslel jste o noSQL databazi? Podle popisu mi treba cassandra prijde celkem idealni.

andy

A co takhle trochu "normálně"?
« Odpověď #9 kdy: 31. 03. 2013, 12:23:17 »
Citace
Lámu si hlavu s tím, jak tyto tabulky převéct do databáze, abych umožnil takovouto editaci jedné tabulky, aniž by se zasahovalo do ostatních. Myslel jsem že si vytvořím čtyři tabulky: 'tables', 'years', 'zones', 'values' a ty pak propojím přes id, ale takové řešení mi připadá krajně nepřehledné a především bude spousta duplicitních záznamů (především roků, protože můžou být stejné v různých tabulkách, ale i pásem, které se taky mohou shodovat).

Nepropojuj to přes ID, propojuj to přímo přes ten rok, jinak mi to připadá úplně OK. Jinak pokud nechceš držet někde záznam o "prázdných řádkách", tak tabulky "years" a "zones" nepotřebuješ, protože jejich obsah bude identický s nějakým "select distinct year from values".

Re:Struktura databáze pro tabulku s různými sloupci
« Odpověď #10 kdy: 31. 03. 2013, 18:15:10 »
Pokud nechcete duplicitu v rocích a zónách, tak si udělejte spojovací tabulky mezi tabulkami tables years (M:N) a tables zones (M:N).