ugrás a tartalomhoz

Adatbázis tervezés

s_volenszki · 2009. Feb. 18. (Sze), 17.46
Bizonyára egy könyv, adott tudománnyal kapcsolatban azért mutat be tervezési mintát, mert az eredményezi a legoptimálisabb gyakorlati alkalmazását az elméletnek.

Azaz, ha történetesen adatbázis tervezésről és egy adatbázis tervezési mintát bemutató könyvről van szó, akkor sokkal inkább az a fontos, hogy a könyvben leírtaknak megfelelő struktúrájú adatbázist hozzunk létre, mint az, hogy a jelenlegi tudásunkkal képesek leszünk-e kinyerni majd az adatokat?

Teljesen világossá vált számomra, hogy az adatbázisban nem a megjelenítés logikája szerint tároljuk az adatokat, ez viszont lényegesen bonyolultabbá teszi az adatok megjelenítését.

Ha figyelembe veszem a tervezési folyamat követelményeit, akkor minden olyan mező, ami ezidáig többértékű volt, egyértékű lesz, majd a következő lépésben minden egyértékű mező feloldásra kerül, így az adatok fizikailag elválnak a megjelenés logikájától.

Ezek az esetek klasszikusan olyankor következnek be, mikor egy mező több adatot is tárolhat.

Az én esetemben ha termékek nyilvántartásához adatbázist tervezek, akkor minden olyan adat külön táblába kerül, ami nem kizárólag egy termékre jellemző. Gondolok itt például a gyártóra, a termék árára, a beszerzési forrásra és még sorolhatnám.

Ez idáig rendben van, tökéletesen értem és valóban egy jól átlátható adatbázis keletkezik.

A gondom csak az, hogy nem bírok értelmes lekérdezéseket készíteni. Ezen elmélkedve (na meg több további adatbázis tervezéssel foglalkozó könyvet átolvasva) jutottam el odáig, hogy nézet táblát kell készítenem.

Úgy értelmezem, hogy a nézet tábla lesz az, amiben szinte olyan struktúrában jelenik majd meg az adat, ami alkalmas az egyszerű megjelenítésre, de nem hatékony az adatok kezelésében. Azt a könyv teljesen logikusan adatmegjelenítő nézetnek hívja.

Találtam még olyat, hogy összesítő nézet, ahol vannak számított mezők is. Ez is logikus, hiszen ha a termékeknek van különböző allokációjuk, akkor egy készlet kimutatás ezen allokációk összesítését jelenti.

Amiben viszont bizonytalan vagyok, az az, hogy mennyire lehet "elvetemült" egy nézet táblát létrehozó rutin?

Ez ugye logikus, hogy nézet táblát azért hozunk létre, hogy megkönnyítsük az adatgyűjtést. Azonban áldozhatunk erőforrást cserében ezért?

Néhány esetben (nem állítom, hogy nem a tudásom hiányossága miatt) nem tudok olyan lekérdezéseket csinálni, amelyek úgy hoznának létre adatmegjelenítő nézeteket, ahogyan azt a megjelenítés logikája elvárná.

Mi az etalon? Nézet táblához az adatokat kizárólag SQL-el kell létrehozni, vagy több lekérdezés eredményéből php-vel ALTER-elhető egy nézet tábla?

Egyáltalán arra való a nézet tábla amit én feltételezek róla?

Kérlek titeket, mondjátok el mit gondoltok!

s_volenszki
 
1

Elvetemült nézet tábla

Poetro · 2009. Feb. 18. (Sze), 18.26
Mivel magukat a nézet táblákat is kb. élőben generálja az SQL (általában azért valamennyit cachel rajta) semmiképpen se szabad nagyon elvetemült lekérdezésekből nézetet csinálni, mert nagyon rossz lehet a teljesítménye. Amennyiben ésszerűbb, és gyorsabb (kisebb load) az SQL szempontjából kliens oldalon megoldani (pl. PHP) az adatok összerántását, akkor szvsz. érdemesebb ezt a feladatot egy erre alkalmasabb céleszközzel kivitelezni, mint a kisebb képességű adatbázismotort terhelni, főleg ha ez teljesítmény szempontjából jóval optimálisabb.
2

Logikus-e?

s_volenszki · 2009. Feb. 18. (Sze), 22.02
Logikus-e valamilyen elmélet szerint csak azért nézettáblákat készíteni, hogy egy adat megjelenítés lekérdezése ne 10-12 LEFT JOIN-olásból álljon, csak 2-3-ból?

Ha követem az adatbázis tervezésre vonatkozó irányelveket, akkor egy egyszerű termék és készlet nyilvántartás könnyedén állhat akár 15-20 olyan adattáblából, amelyek jelentős részét pásztázni kell, mikor egy terméklistát akarok készíteni.

Gondolok itt arra, hogy ha felismerem a többértékű mezőket, egyértékűvé teszem, majd feloldom, akkor a termékre vonatkozó önálló adatokon kívül, különálló táblákban lesz rögzítve az allokációnként megtalálható készlet, a különböző ár (beszerzési, nagyker, kisker), a termék forgalmazója, a termék gyártója, a termék fotói, a termék "gyermek" termékei, a termékhez ajánlott termékek és ez a lista még nem is teljes, mégis a termékekkel együtt 8 tábláról beszélünk és még egy szó sem esett azokról a "leíró" táblákról, amelyek az árakat, az allokációkat, a gyártókat stb. jellemzik.

Ha nézetekre bontom, nagyjából 2 táblára lehetne csökkenteni a kapcsolatban álló táblák száma.

Az első nézet tálba tartalmazhatja a termék összes önálló (nem ismétlődő, egyedülálló) adatát, a beszállító szükséges adatait, áfakört, mennyiség egységi adatokat, súlyt, a gyártó szükséges adatait és az allokációkból összesített készletet.

Egy következő nézet tábla tartalmazhatja az árakat, a termék fotókat (fájlok neveit), a termék gyermektermékeit (azok azonosítóit), az aftersale termékek azonosítóit. Ez a nézet tábla szinte minden mezőben többértékű adatot tartalmazna, mert ide kerülnek azok az adatok, amiből mindig több van egy termékhez mint egy. Ezek a mezők a különböző igények szerint GROUP_CONCAT-olt lekérdezések végeredményeit tartalmazzák (szinte biztos, hogy nem generálható egy lekérdezéssel php segítsége nélkül).

Persze ehhez az is hozzá tartozik, hogy alkalmazás szinten folyamatosan felügyelni kell a változást és adott időben újra kell generálni a nézeteket.

Vagy nem logikus és minden egyes terméklista nézetének elkészítése során gyűjtsek ciklusonként adatot:

1. Megszerzem a termékek közül azokat, amelyekre szükség van (mondjuk 500 rekordot)
2. majd ciklusban megszerzem egyesével a termék azonosítókat és
3. egy lekérdezéssel megszerzem a további termék adatokat
4. egy másikkal megszerzem a készletet
5. aztán az árakat
6. és a képeket
7. végül a kapcsolt adatokat (aftersales)

Lehet, hogy ez egy kicsit sarkos, és az a 7 lekérdezés összesen csak 4, azonban az akkor is 3500 lekérdezés.

Klasszikusan egy termék adatbázist jelentősen többször olvasunk mint írunk, azaz kevesebbszer fordul elő, hogy új nézeteket kell generálni, mint a 3500 darabos lekérdezés ciklus.

Van itt józan érv, vagy mérni és értékelni?
8

EAV

Hodicska Gergely · 2009. Feb. 18. (Sze), 23.45
Logikus-e valamilyen elmélet szerint csak azért nézettáblákat készíteni, hogy egy adat megjelenítés lekérdezése ne 10-12 LEFT JOIN-olásból álljon, csak 2-3-ból?
Nem logikus a kérdés ;), legalábbis pl. MysQL esetén. A nézet csak egy behelyettesítés, ugyanúgy 10-12 joinod lesz, ráadásul MySQL estén még rosszabb végrehajtási tervet is okozhat a nézet használata. Szóval úgy érzem, hogy ezt a nézet tábla kérdést kicsit félreértetted.

Viszont ha kellően sokrétű termékekkel kell dolgoznod, akkor bár elvileg anti-pattern, de mégis megfontolandó lehet EAV (Entity Attribute Value) használata, elvileg ha jól van kitalálva, akkor elég jól használható rendszer hozható ki belőle. Egyik php|architect számban volt róla egy jó cikk.
9

Nagyon érdekes...

s_volenszki · 2009. Feb. 19. (Cs), 22.40
Nagyon érdekes, bár még egy párszor át kell olvasnom, hogy pontosan megértsem az előnyeit a szabvány relációs modellhez képest, azt viszont már most tisztán látom, hogy milyen alapvető igény keltette életre ezt a felépítést.

Nagyon köszönöm!
3

nézet tábla

Makesz · 2009. Feb. 18. (Sze), 22.11
Amennyire tanulmányaimra emlékszem, nézet táblát a következő célokkal használunk:
- áttekinthetőség, optimalizálás (összetett lekérdezés felbontása)

- adatvédelem(oszlopok, sorok korlátozása): pl egy db usernek létrehozol egy táblából egy szűkebb view táblát, és csak ahhoz adsz neki SELECT jogot, így nem fér hozzá olyan attribútumokhoz ami esetleg titkos, és ehhez nem kell új táblát létrehozni, amit még ráadásul szinkronizálni is kéne

- ellenőrzött adatbevitel: ha pl a view létrehozását kombinálod a WITH CHECK OPTION kapcsolóval, akkor az eredeti táblába való beszúrás SQL szinten lesz ellenőrizve a megadottak alapján.

Nem tudom miért akarsz minden áron nézet táblát használni, azt tudom tanácsolni, hogy ha nem tudod mire való, akkor inkább ne használd. Az biztos, hogy az adatbázis motorját terheli, az pedig, hogy érdemes-e ez az erőforrás áldozás, az attól függ, mire optimalizálsz. Ha pl a PHP motor terhelését akarod csökkenteni azzal hogy már kiszámolt és összeszedett adatokat kérsz le, akkor mindenképp hasznos.
5

Azt hiszem kezdem érteni.

s_volenszki · 2009. Feb. 18. (Sze), 22.24
Azt hiszem kezdem érteni. Valójában nem tudom, hogy akarok-e nézet táblákat használni, illetve most már egyre jobban úgy érzem, hogy nem akarok.

Amit írsz az teljesen egyértelműen meghatározza egy nézet tábla célját.

Köszönöm.
10

Struktura elfedése

zila · 2009. Feb. 20. (P), 12.00
Arra is jó a nézet-tábla, hogy az alkalmazás elől elfedd a táblák valódi strukturáját, így anélkül lehet változtatni egy (vagy több) tábla strukturát, hogy az alkalmazáshoz hozzá kelljen nyúlni. Ezen kívül pl. Oracle ismeri a materialized view-kat, amik már jelentős performancia növelést eredményezhetnek, a nézet valódi táblaként viselkedik, a háttérben szinkronizálódik az adattartalma a nézet alapjául szolgáló táblákból. Így az ezen futtatott lekérdezések gyorsabbak lesznek mint egy sima view esetében.
4

Nézet tábla vagy kód

Mac08 · 2009. Feb. 18. (Sze), 22.22
Ebbe a problémába magam is többször belefutottam :-(
De az elejétől kezdve: sajnos arra jutottam - több év adatbázis programozás, oktatás, stb. után -, hogy a könyvekben leírt adatbázis elméletek sokszor távol állnak a gyakorlati megvalósíthatóságtól. Általában az igények (megrendelői, felhasználói) nem teszik lehetővé a tankönyvi megvalósíthatóságot.
Személy szerint én a feladattól függően az alábbi "elveket" követem:
Első körben: Megpróbálom a tervezés folyamatában a klasszikus adatbázis elméletet betartani.
Második körben: Eltérek az egyestől és kódból oldom meg a trükközést, amennyiben az elviselhető terhelést jelent a program futása során - indok: megmarad a klasszikus adatbázis struktúra. Ez általában futásidőben generált ideiglenes táblákkal történik.
Harmadik körben: Nézetekkel, segédtáblákkal oldom meg a problémát.
Negyedik körben: A második és harmadik megoldási módszer ötvözetével próbálok meg megoldást találni, a legoptimálisabb teljesítmény érdekében. Bár legtöbbször ezt alkalmazom, a veszélye, hogy nagyon alapos dokumentálást igényel, mind adatbázis struktúra, mind algoritmusok tekintetében.
Ötödik körben: Keresek egy tőlem okosabb adatbázis buherátort (feltételezve, hogy a projekt költségvetésébe belefér :-) ).

A probléma itt még abban áll, ha az elején nem tudom felmérni, hogy melyik szintre van szükségem, akkor az átlépés egy következő módszerre boríthat sok mindent. Azaz: ha a második szintel kezdem, de rájövök, hogy a harmadikra is szükségem van, akkor gyakorlatilag a negyediknél tartok, de a második szinten történt algoritmus, nem biztos, hogy az utólag bevont segédtáblák, nézetek tekintetében a legoptimálisabb.
Ezért szoktam a véglegesítés előtt teszteket, illetve teljesítmény méréseket végezni.
6

Nagyon jó a megközelítés...

s_volenszki · 2009. Feb. 18. (Sze), 22.36
Tetszik a megközelítés :)

Az a helyzet, hogy a teszten sikeresen túl vagyok, mert a rendszer előző verziója már közel másfél éve kifogástalanul kiszolgálja az igényeinket, ráadásul úgy, hogy teljes egészében a kódra helyeztem a terhelést.

Fejlesztésre kerül a sor és mérlegelek. Azt gondolom, hogy az előzőekhez képest csak jobb lehet a helyzet, hiszen megszűnik egy csomó logikátlan adatismétlés, többértékű mező, viszont foglalkoztat a kérdés, hogy hogyan lehet minden ideális.

Már értem, hogy például az én esetemben kelleni fog nézet tábla, csak nem arra amire én gondoltam. Például a különböző allokációk készleteit tárolhatom egy összesítő nézet táblában, amit mindig csak készlet változáskor kell újragenerálni, mindaddig pedig több tízezer lekérdezést takarít meg az adatok megjelenítésénél!

Tökéletesen azonosulni tudok azzal a stratégiával amit leírtál. A feladat csak az, hogy az induláshoz szülessen meg a helyes döntés!

:)
7

Programozási nyelv

Mac08 · 2009. Feb. 18. (Sze), 23.42
Azzal még kiegészíteném, hogy figyelembe szoktam venni a fejlesztő nyelvet és az üzemeltetési környezetet is. Mint kiderült nálad ez PHP. Ebben az esetben kérdés, hogy dedikált szerver szolgál -e ki és az adatbázis ugyanazon a szerveren van, vagy külön gépen.
Amennyiben e tekintetben el vagy látva kapacitással, én azt javasolnám - az eddigi információk alapján -, hogy több feladatot hagyj a kódnak. A PHP adatbázis és tömb kezelése alkalmas rá, hogy kódon belül trükközz.
Egy extrém példa: az adatbázis tervezéskor egy projektnél, szinte teljesen el kellett térnem a klasszikus relációs elvtől - a miértet most hagyjuk. Viszont felhasználó által megadott paraméterek alapján dinamikusan kellett lekérdezéseket generálnom (több mint 350 paraméter is szóba jöhetett). Mivel az adatbázis struktúra sem a szokásos volt és dinamikusak voltak a lekérdezések, így nézet tábla szóba sem kerülhetett. A megoldás az volt, hogy maga a PHP generálta le több rekurziós ciklussal magát az SQL utasítást, amely temp táblákba tolta az adatokat és előállított egy "szabványosan" lekérdezhető adattábla halmazt és innen kapta meg a delikvens a végeredményt. Bár elég sokat dolgoztam a rekurziók optimalizálásán, de elfogadható válaszidőt sikerült elérni (PHP, MySQL volt).
11

Normalizálás/denormalizálás

zila · 2009. Feb. 20. (P), 12.04
Az is benne van némelyik könyvben, hogy a tervezéskor a cél a normalizált formában történő adatbázis kialakítás. Amikor ez készen van akkor a fejlesztés során a performancia tuning fázisban jön a mészárlás és denormalizálni kell(het) azokat a strukturákat amelyek miatt nem megfelelő a szép, normalizált megoldás. Így optimális és szép is lesz a db, legalábbis az életciklus elején :)