AB struktúra

Urak,

Az alábbi feladatra szeretnék egy épkézláb adatbázis modelt:
-A rendszer alapvetően modulokból áll (pl felhasználók, események, üzenetek, termékek, stb)
-Egy egy modulon belül az oszlopok száma akár ezres nagyságrendű lehet. (pl. felhasználói adatok: lakcím, anyja neve, kedvenc szín, kedvenc film, stb)
-Egy-egy modulnak az oszlopainak az írási jogosultságának AB szintű meghatározása (ezt csak alkalmazás oldalon fontos az íráskor)
-Modulok összekapcsolásának a lehetősége (Pl 'A' user be van sorolva egy 'B' eseményre)
-Modulok összekapcsolásához kiegészítő oszlopok definiálása (pl 'A' user egy adott 'B' eseményen megjelent, értékelések mentése, stb)
-Felhasználó által összeválogatott nézetek megvalósításának elmentése modulonként: kiválasztott oszloplisták és szűrőfeltételek elmentése az adatbázisba.
-Adatbáziskezelő indexelési képességének kihasználása, modulonként fix számú (nem sok) oszlopra.

Hozzászólások

Biztos vagyok benne hogy létezik az enyémnél kevésbé nyakatekertebb, sokkal elegánsabb megoldás erre, íme az én verzióm:
Egy egy modul alapvetően egy adatbázis táblát kap (pl users, events, emails)
Ezeket a modulokat egy 'gen_modules' táblában felsorolom:
Table 'gen_modules'
-> id (int)
-> db_prefix (char(50))

A modulokban található oszlopokat, azok típus és írási jogosultság leírásukkal egy külön táblában tárolom (az összes modulhoz)
Table 'gen_columns'
-> id (int)
-> module_id (int) //gen_modules tábla id-je
-> t_id (int) //join_rules tábla id-je
-> name (char(50))
-> enabled (bool)
-> deleted (bool)
-> type (enum('text','checkbox','email','telephone','date','timestamp',...)
-> archive (bool)
-> writeable (bool)
-> permission set('Admin','Hr','Trainer','Sales',....)
-> requied (bool)

Minden keletkező adatot eltárolok egy kiegészítő táblában is:
Table 'gen_ext'
-> module_id (int)
-> id (int)
-> cid (int) //gen_columns tábla id-je
-> value (text)

A modolok összekapcsolásának típusát és lehetőségeit egy külön táblában tárolom (melyik modult mihez kapcsolom pl események-felhasználók összekapcsolás.
Table 'join_rules'
-> id (int)
-> name (char(50))
-> module_id1 //gen_modules tábla id-je
-> module_id2 //gen_modules tábla id-je

A modulok tényleges összekapcsolásait egy újabb táblában tárolom (pl user besorolása egy eseményre, vagy egy értékesítés egy termékhez)
Table 'join_table'
-> id (int)
-> t_id (int) //join_rules tábla id-je
-> t1_id (int) //join_rules táblában a t_id-hez kapcsolódó module_id1-moduljában található elem id-je
-> t2_id (int) //join_rules táblában a t_id-hez kapcsolódó module_id2-moduljában található elem id-je

Na és innentől van benne csavar! Biztos vagyok benne hogy ezt sokkal kacifántmentesebb módon is meg lehetne oldani:

Ahhoz, hogy az összekapcsolt mezőkhöz kiegészítő oszlopokat tudjunk rakni (pl egy user az adott eseményen hogy szerepelt), elég felhasználni a meglévő struktúrát:
a 'join_table'-ből csinálunk egy modult, és definiálunk neki kiegészítő oszlopokat. (így egy-egy összekapcsoláshoz hozzá tudunk rendelni bármennyi oszlopot.

A userek által definiált nézetek megoldása: Egy-egy nézet tulajdonképpen egy írható datagrid, persze csak ott írható, ahol az adott usernek arra írási joga van.
Table 'gen_views'
-> id (int)
-> module_id (int) //gen_modules tábla id-je
-> name (char(50))
-> owner_id (int) //userId
-> deleted (bool)

A nézetekhez tartozó oszloplista a 'join_table'-ban van tárolva, miután a megfelelő join_rule-t felvettük:
-module1: gen_views,
-module2: gen_columns

A fenti AB struktúrával egy olyan alkalmazás készült, ami datagridekkel dolgozik, a megrendelőnek többszáz oszlopos táblák kellettek, viszont egy-egy kollega ezek közül csak néhánnyal dolgozik, különböző esetekben, különböző nézetekkel.

A fenti alkalmazást tovább kéne fejleszteni, adott esetben újraírni az egészet, viszont sajnos a fenti funcionalitás eléréséhez nem látok jobb AB megoldást a mostaninál.

Valakinek valami hasznos ötlet/kritika?

Én fizikailag hoznám létre a táblákat. Ettől még metavezérelt, dinamikusan módosítható marad. Sharepoint, Dynamics CRM, és egy saját alkalmazásunk is így működött.

--
joco voltam szevasz

Megkérdezhetem, hogy az miért nem bántja a szemed, ha egy táblába 100+ oszlopot teszel?
Ami hasonló jellegű alkalmazást láttam, az oszlopok helyett rekordokkal (és vagy külön attributum táblákkal) oldotta meg ezt a feladatot (pl. ldap fák).
Őszintén megmondom nekem elkerekedett a szemem a sok oszlopon, mert nagyon drágák az ilyen sok oszlopon végzett insert/update műveletek.. a select se kutya
persze, főleg, ha az utolsó mező kell.. .. szóval a null érték a legkisebb gond.. főleg meg nem esztétikai kérdés.:)

nincsenek az alkalmazásban többszáz oszlopos táblák, sőt, csak azok az oszlopok vannak bent a modul főtáblájában, amikre az alkalmazásban szűrűnk/rendezünk, az indexek miatt.

Sokat gondolkoztunk a fenti stuktúrán, a technikai megvalósítás is megszületett, performance tekintetében teszteltük 5 millió rekordot tartalmazó modulokra, és 80 milliós atribútumtáblákra, 0.1 mp-es futásidejű query-knél akkor sem volt több (sql_no_cache-el sem), szóval performance tekintetében nincs vele gond (ekkora adathalmazra a valós alkalmazásban nem kell majd számítani)

Akkor csak azt mondom, hogy baromi hülyén írtad le a dolgokat..

> Fizikailag annyi lenne a bajom vele, hogy pl a users táblához jelenleg 457 oszlop tartozik
> Egy egy modul alapvetően egy adatbázis táblát kap (pl users, events, emails)

Ezt a legtöbben itt a fórumban (és én is) úgy értelmezték, hogy egy tábla, 457 oszlop, és egyébként is ezt sugallod az összes infóval..

Joco, tudom, hogy reg volt Gajdos vagy KatonaGyulaY, de az oszlopok alapbeallitasban olegge ki tudnak nyirni egy adatbazist, mivel minden rekordot (sort) fizikailag folytonos helyre probal pakolni.

Aztan persze lehet, hogy adott adatbaziskezelokben ezt mar kezzel lehet optimalizalni, de ettol meg ez volt az indok hogy miert ne csinaljunk ilyeneket.

Halassy Béla: Az adatbázistervezés alapjai és titkai