Adatbázis dinamikusan bővülő mezőkkel

Keresés
Hírlevél
 
ASPC#C++CSSDelphiFlashJavaJavaScriptPascalPerlPHPPythonuniPaaSVisual BasicVisual C++  »    
nyitotta: DJ_Tacee, idő: 2012.06.10., moderátor: netangel
  Értesítés változás esetén Felvétel kedvencekhez Küldés emailben
Sorrend:
Időzóna:
Blokkméret:
Oszd meg!
  • E-mail
Sziasztok! Részben elméleti lesz a kérdésem de ha valaki konkrét megoldással jön ami tetszik akkor máris pontra menő a dolog, így kezdeményezem a tudástárba áthelyezését.

Tegyük fel van egy táblánk, ebben legyenek alapadatok, mondjuk egy személy adatai. Egyik mező itt legyen pl. a neme, férfi / nő / egyéb (ma már nem lehet tudni ugye...). Ezek legyenek számok, de jelen esetben ez részletkérdés.

Attól függően hogy mi a neme az illetőnek más-más adatokat szeretnék tárolni. Ezen..
Azt is gondold át, hogy ha fizikailag dinamikusan tárolod az attribútumokat, annak önmagában semmilyen előnye nincs: akkor van előnye, ha valóban úgy tekintesz ezekre az attribútumokra, hogy azok a program működése során változhatnak. Ha viszont változhatnak, akkor az üzleti logikádban nem hivatkozhatsz rájuk. Ez sok esetben képtelenség, sok mindent nem lehet ezen az absztrakciós szinten kezelni. Ekkor azt teszed, hogy mégiscsak feltételezed, hogy van egy dinamikus felhasználó tábla és annak van username és password dinamikus mezője: csak éppen a dinamizmus miatt kényelmetlenebbek és lassabbak lesznek a lekérdezések és adatmanipulációk. előzmény
A 'dinamikus attribútumok' hátránya az, hogy bizonyos konkrét lekérdezések lassabbak és komplikáltabbak lesznek. (pl. normál oszlopokra indexeket készíthetsz, dinamikus oszlopokra nem...)

Általában is igaz, hogy az absztrakció és a performancia között tradeoff van, illetve a túlabsztrahálás már nem egyszerűsíti, hanem bonyolítja a kódot.

Ugyanígy a dinamizmus és a performancia között is tradeoff van, iiletve a túlzott dinamizálás addig nem tapasztalt hibalehetőségeket rejt (pl. dinamikus oszlopoknál nem lehetnek józan hibaellenőrző constraintjeid, vagy ha lehetnek is, azok is komplikáltabbak)

Szal' tradeoff: csak akkorj használj dinamikus attribútumokat, ha valóban szükség van rá, és ennek előnyei nagyobbak mint a hátrányai. előzmény
Egy viszonylag nagyobb rendszeren kezdtem el dolgozni, és én is fogok alkalmazni dinamikusan változtatható mezőket. Az merült fel bennem kérdésként, hogy mi lehet a hátulütője egy ilyennek. Mi az akadálya(akár elvi, akár gyakorlati), hogy egy entitás összes attribútuma dinamikus legyen. Sőt, továbbgondolva az is lehetne, hogy az entitások nem kapnak külön táblát, hanem lesz 4 táblánk, az elsőbe felsoroljuk a használni kívánt entitásokat, a másikba beszórjuk az összes objektumot(és odabiggyesszük mindegyik mellé a típusát), dinamikusan hozzájuk rendelünk attribútumokat(a maradék 2 tábla megfelel erre), írunk valami jó wrappert, hogy kódból viszonylag kényelmesen lehessen ezt az egészet kezelni, és megvagyunk. Miért érzem ezt olyan furának? A dinamikus attribútumok praktikusak, de hol a határ?
Látom, hogy sokan sok okos ötletet mondtak. Sztem a rendelkezésre álló információk alapján nem lehet optimális megoldást javasolni a problémára.
Bennem a következő kérdések merültek fel, amelyek a javasolt megoldást befolyásolhatják:
1. A mezők körének bővítését a felhasználó is végezheti vagy a rendszer+DB programozott módosítására van szükség?
2. Csak bővítés lehetséges?
3. Az adatok validációját (típus, hossz, meg van-e adva, stb.) DB szinten vagy pedig business logic szinten végzed?
4. Milyen módszerrel történik az adatbázis elérése (direkt SQL kapcsolat, ORM rendszer?)
5. Mennyire lesz gyakori ez a bővítés/sémamódosítás?
6. Az extra mezők alapján akarsz lekérdezéseket írni (azaz szükség lehet esetleg indexre, pl) vagy elég őket by Id elérni?
7. Mennyire lesznek kitöltve adatokkal ezek az un. metaadat mezők? Lehet, hogy a fele NULL lesz?
8. Ez a dinamikus séma benn vagy a budgetben vagy pedig jobb lenne CRként/supportként eladni a sémamódosítást?
előzmény
Szerintem se kell ennyire bonyolítani. Igazán csak elrettentésnek szántam, hogy ilyen AI feelinges adatbázisba belemenni roppant nagy munka lenne, amit egyébként előre definiáltan sík egyszerű lenne megoldani.

Egyébként nekem az jött le, ha agyon normalizál, akkor hogy lehet benne keresni? Pont ez az egyik lényege. Nem kell minden táblában, csak DJ_Tacee által kulcs-értéknek nevezett táblában. előzmény
én egyetlen táblában szoktam tárolni a választható tulajdonságokat, és azon belül csoportokra bontom az értékeket.

kód    | megnevezés | csoport| megjegyzés |
___________________________________________
f      | Férfi      | nem    |            |
n      | Nő         | nem    |            |
szoke  | Szőke      | haj    |            |
barna  | Barna      | haj    |            |
kopasz | Kopasz     | haj    |            |

ha valamit keresek, akkor a szűrési feltételben megadom, a csoportot, és máris megkapom a keresett listát.
nagyon nagy előnye, hogy egy adott kódcsoport létrehozásához, nem kell sok szerkesztési idő, hiszen csak egy új csoportot kell létrehozni egy már meglévő táblában, majd arra hivatkozni a későbbiekben.

a különböző tulajdonságokat tartalmazó listákat pedig külön táblázatban kell tárolni, amennyiben a várható rekordok száma meghalad egy bizonyos értéket.
nyilván ezt neked kell előre látnod, hogy hány rekord felvitele várható. ha kevés, akkor mehet a férfi és női adat is egy táblába, ha ez megkönnyíti a fejlesztést.
amennyiben sok rekordot rögzítesz, célszerű szétválogatni az adatokat, hogy ne növeld feleslegesen az adatbázis méretét. előzmény
Ilyesmit csináltam én is, annyira nem kell elbonyolítani.

Fel lehet venni új tulajdonság nevet egy kódtáblába és megadni, hogy ehhez a tulajdonsághoz milyen vizsgálati szabály (hossz, típus, értéktartomány) tartozik.

A partner formhoz a fix adatokon kívül alól egy táblázat tartozik két oszloppal. Az elsőben egy legördülő menüvel tulajdonságnév választható, a másodikban egy érték adható meg.

Mindez nem probléma, ha keményen külön rétegbe vesszük az adatbázist (SQL parancsok), a memória objektumokat, amik kiadják a partner adatainak view-át és a megjelenítést.

Gondolom a kérdező sem akar ennél nagyobb 'mélységekbe' leszállni
előzmény
Egy multidimenzionális adatbázis is más aspektusba helyezné az egész problémát

Egyébként programozás szempontból nem túl nehéz megoldani, hogy típusos adatmezőket hozzunk létre. Bekéred az adatot aztán lefuttatsz pár elágazást, ha szám akkor integer, ha character akkor... megszámolhatod a karakterek számát is... stb.

Azt is meg lehetne csinálni a példánál maradva, hogy egy létező tulajdonság táblához előre nem látható új mezőket generálunk. Mondjuk bekéred a személyek szemszínét. Az egyik beírja kék, oké ilyen már van a táblában igen/nem, a másik beírja zöld, oké ilyen is van már igen/nem, a harmadik beírja türkizkék, hoppá! nincs ilyen mező, most akkor kék vagy zöld? Jó legyen a kékben is egy igen/nem és a zöldben is. Csakhogy ez nem azt jelenti, hogy türkizkék szeme van, hanem azt, hogy az egyik szeme kék a másik meg zöld (van ilyen én ismerek is ilyen embert). Na jó akkor generáljunk új mezőt türkizkék logikai értékkel. Hurrá! Türkizkék szemszín igen/nem. A probléma ezzel csak az, hogy mi van akkor, ha 1 millió esetből ez kétszer fordul elő? Lesz egy oszlopunk, ahol csak kétszer lesz a többségtől eltérő logikai érték. Már nem is éri meg. Namost ezt előre is el lehet dönteni, hogy mennyire éri meg. Csinálni kell egy táblát ami a relatív gyakoriságot tárolja el és ha elér egy "küszöbértéket", az adott mezőt illetően, csak akkor generál hozzá mezőt, máskülönben az egyéb vagy kivétel kategóriába kerül. Ezt meg lehet oldani küszöbfüggvénnyel is, de mint említettem ez már AI téma kőkeményen.

Őszintén szólva nem tudom pontosan mit szeretne DJ_Tacee. Az a gond, hogy nem tud még normalizálni (nem feltételezem, csak hipotetikus a kérdés), vagy az a gond, hogy előre nem látható bejövő adatokkal akar dolgozni?
Ez utóbbi kifejezetten bonyolult tud lenni adatbázis normalizálási szempontjából. Például mi dönti el, hogy egy eldöntendő kérdés elég fontos-e ahhoz, hogy tulajdonság táblát is létrehozzunk hozzá. Az is probléma, ha nem tudjuk az eldöntendő kérdést előre, akkor honnan tudjuk mi tartozik, majd a tulajdonság táblába. Addig egyszerű hogy szemszíneknek csinálunk egy tulajdonság táblát. Abban csak színek fordulnak elő. De ha nem tudjuk hogy lesz ilyen szemszín mező egyáltalán, akkor...?
Ezt AI nélkül előre kell definiálni:
Ha ember, akkor van-e feje, ha van feje, akkor van-e szeme, ha van szeme, akkor van szemszíne. Ezután lehet csak arról beszélni, hogy hozzunk-e létre a tulajdonság táblát a szemnek, aminek egyik tulajdonsága a szín. És ezen belül is lényeges, hogy mely tulajdonságok milyen fontosak? Itt is bejön a relatív gyakoriság.

Tehát tegyük fel, hogy csak annyit tudunk hogy ember. Kiteszünk egy formra adatbekérőt. Írjon be valamit a user. Beírhat kismillió dolgot. Semmi mást nem kérdezünk csak adj meg egy tulajdonságot az emberről. Férfi/nő, hajas/kopasz, magas/alacsony, gyerek/felnőtt/öreg, kék szemű/barna szemű/...
Lesz egy csomó eltérő válaszunk mondjuk 1 millió. Megnézzük melyik a leggyakoribb válasz. Például a férfi/nő kettős. Akkor az egy elég fontos tulajdonság lesz. Persze mi van akkor, ha a 'nő' torony magasan vezet a 'férfi'-val szemben? Közben ott van a magasság, szemszín stb... a 'férfi' előtt. Ezt például hogyan állapítjuk meg, hogy a 'nő' tulajdonságnak a 'férfi' komplementere, nem mondjuk a magasság? Előre definiáljuk a komplementereket? Ekkor még a rokonértelmű kifejezésekre rá sem tértünk. (Biztos lesz olyan 1 millió közül, aki a 'nő' helyett azt írja 'buksza'. Elég csak feljönni a prog.hu-ra máris is lesz egy raklap ilyen válaszoló)
Ezzel még mindig csak egy emberi tulajdonságnál tartunk
Izgis, mi? előzmény
Nem, volt szó róla, milyen adatbázist használsz.

Ma már léteznek XML mezők, amikbe "akármit" is lehet tenni
Ennél rugalmasabb megoldás nincs (ha nem is igazán hatékony dolog, hagyományos relációs db/SQL szemszögből).

Várj! Lehet, hogy tanulni képes adatbázist akar előzmény
Az, ha minden új tulajdonságra új mezőt veszel fel, az nemcsak, hogy ronda, de nagyon amatőr megoldás is szerintem, a táblád túlnyomórészt üres mezőket fog tartalmazni.

A megoldás egyértelműen több új tábla szerintem, egy a tulajdonság leírására (id, név, egyéb), egy másik a tulajdonság típusának (szöveg, szám, link, stb)(tulajdonság_id, típus_id), egy harmadik a típusok leírásának (tipus_id, típus neve), és végül a tényleges tábla a tulajdonság leírásának (tulajdonság_szülőjének_id-je, tulajdonság_id, érték)
Ezt lehet megfejelni egy combo értékek táblával (id, tulajdonsag_id, szoveges_leiras), ahol ezen tábla tartalmával töltöd fel a combot, amiből ki lehet választani a tulajdonság értékét.

Mi ezt így csináltuk, ez alapján teljesen fel lehet építeni egy formot a bekéréshez, és a kiíratáshoz is, akár automatikusan is. előzmény
Typo: kimaradt pár szöveg az elejéről, közepéről és végéről is. Nem tudom hogy?!?

Nem férne bele egy postba? előzmény
Az első megoldásnak az a hátránya, hogy lehet benne sok kitöltetlen mező, mert mondjuk számos esetben nem értelmezhető.
Lehet triviális a példa és lehet ilyen konkrétan nem is szerepel benne Tehát például: nézed a személyeknél, hogy van-e haja. Ha ugyanebben a táblában akarod mezőben tárolni azt is, hogy használ-e hajfestéket, vagy jár-e fodrászhoz, az a kopaszok esetében értelmezhetetlen. Ilyenformán előállhat egy tábla, aminek nagy része nem használt mezőket fed.
Az előnyét meg leírtad.

A második verziónál, könnyebb lenne megérteni a problémát, ha a kulcs-érték tábla mellé bevezetnéd a "személy-konfigurációs" táblát. A kulcs-érték táblát én eredménytáblának szoktam nevezni, de ez most mindegy.
Tehát, ha van egy ilyen táblád amiben a kulcsmező és az index egyben a személy ID-je és a többi mező is valamilyen tulajdonság ID, ami egyben kulcsa is egy-egy további tulajdonság táblának, akkor a végén lesz egy olyan táblád, ami csak a személyek adatainak hivatkozásait tartalmazza. Keresned csak ebben kell, nem?
Például lenne egy személy táblád, ahol tábla mezőket úgy határozod meg, hogy eldöntendő kérdésekre legyenek válaszok. Így nem azt tárolod el, hogy férfi-nő szavak vagy kopasz-hajas szavak, szóval nem 2 mező a 'nem' és a 'frizura', hanem 4 mező (ebben a példában) 'férfi' 'nő' és 'hajas' 'kopasz'. Eltárolni csak egy logikai értéket kell igen/nem. Azokat a mezőket kell így felvenni, amikkel kapcsolatban tárolni akarsz adatokat.
Ebből adódhatnak olyan tulajdonság táblák, amiket csak akkor használsz egy rekordnál, ha szükség van rá. Ha felmerülnek új tulajdonságok, csak hozzá kell fűzni a megfelelő tulajdonságtáblához. Ha esetleg egy teljesen új "szempont" is felmerülne, akkor kulcs-érték táblához kell felvenni egy mezőt. Ez persze szükségképpen tulajdonság táblá(ka)t is eredményez.
Ha ily módon csak 2 szintre bontod; kulcs-érték tábla szint és tulajdonság tábla szint, akkor a tulajdonság táblád csak logikai értékeket tartalmaz a tulajdonság tábla pedig varchar/integer értékeket. Lehet persze tovább is normalizálni, hogy még kevesebb adatot tárolj el. Például a tulajdonság táblákhoz csinálhatsz 3. szintként egy színkód táblát is, amiket felhasználhatsz szemszínhez, hajszínhez, egyéb fizikai tulajdonság táblához. Ha ilyet is csinálsz, akkor a tulajdonság tábláid is kisebbek lehetnek. A szemszínnél például csak barna, kék, zöld, esetleg piros albínónál vagy ezek kombinációja fordul elő. Komolyabban: barna, kék, zöld és egyéb. Ez csak 1,2,3,4 értéket jelent. Tehát ha személy, ha van szeme, akkor van szemszíne is és akkor tartozhat hozzá szemszín tábla is barna, kék, zöld és egyéb mezőkkel, amikben igen/nem logikai értékek tárolják a színeket. Mellesleg ez a mód megoldja a szemszínek kombinációinak kérdését is, hiszen ha valakinek az egyik szeme kék, a másik barna, akkor 2 mezőbe is igen logikai érték kerülhet. A grafikus szerkesztő alkalmazások is hasonló módon határozzák meg a színkódokat. Nem tárolják el a 16,7 millió színt, csak mondjuk az RGB komponenseket (CMYK, stb...).

Kérdésedre válaszolva: ha ezt automatikusan akarod generálni, az merőben AI kérdés. Ha csak új tulajdonság mezőket akarnál hozzáfűzni, akkor okafogyott lesz, ha jól normalizálod az adatbázisod. Annyira minimálisra csökkenthető az újonnan bejövő tulajdonságok száma, amit már kézzel is bevihetsz időnként, vagy ha annyira ritkán fordul elő, hogy nem érdemes vele foglalkozni, akkor egyéb mezőt vihetsz be a végére.

Lényegében én úgy szoktam megoldani, hogy van egy config-táblám sok mezővel, melyek mindegyike logikai értéket tartalmaz. Van egy csomó tulajdonság táblám, amik akkor lépnek be, ha megnéztük az alaptábla értékeit (Kulcsmezői a config-tábla kulcsmezője). Ez utóbbiakhoz kiegészítő táblákat is szoktam rendelni színkódok, irányítószámok, stb... amik egyébként lényegében fix adatok (nem sűrűn változnak).
Ezt egyesítem az eredmény táblában ami "dinamikusan él" (Most hirtelen nem jut más megfogalmazás eszembe.) Az eredmény tábla csak az ID kulcsot és config-tábla alapján összehozott tulajdonságtáblák kulcsait tartalmazza. előzmény
Dokumenum orientált adatbázist szeretnél, akkor használj olyat vagy pl alkalmazz json-t

előzmény
Nekem is van egy verzióm. Mi lenne, ha minden típushoz tartozna egy tábla: lenne integer, varchar stb táblák. A dinamikus mappelt típusok runtime keletkeznének. Én már csináltam ilyet a lekérdezési/insert stb performanciával nem volt gond. Ez azért jó, mert olyan területre dolgozom, ahol akár verziónként is eltérő lehet 1-1 típus megfeleltetés, ahogy változnak a jogszabályok, vagy esetleg jogosultság szerint is változhat ez. Konkrétan archetype-ra keress rá, ha érdekel ez a megoldás.
Sziasztok! Részben elméleti lesz a kérdésem de ha valaki konkrét megoldással jön ami tetszik akkor máris pontra menő a dolog, így kezdeményezem a tudástárba áthelyezését.

Tegyük fel van egy táblánk, ebben legyenek alapadatok, mondjuk egy személy adatai. Egyik mező itt legyen pl. a neme, férfi / nő / egyéb (ma már nem lehet tudni ugye...). Ezek legyenek számok, de jelen esetben ez részletkérdés.

Attól függően hogy mi a neme az illetőnek más-más adatokat szeretnék tárolni. Ezen adatok dinamikusan változnának, bővíteni szeretném később úgy, hogy az alap adatokat tartalmazó táblához ne kelljen nyúlnom.

Első megoldásnak az lenne célszerű, hogy minden nemhez tartozna egy másik tábla amiben a szükséges mezők szerepelnének, elsődleges kulcsa a személy ID-je, így egy sima JOIN-al a plusz adatok lekérhetőek és kereshetőek, lennének. Úgy gondolom performancia tekintetében ez lenne a nyerő.

Második verzió hogy készítenék egy kulcs-érték táblát, amiben szerepelne: személy-ID, tulajdonság-ID, tulajdonság-érték. Plusz lenne egy tulajdonság-ID, tulajdonság-név, tulajdonság-típus tábla amiben tárolnám hogy az egyes nemekhez milyen adatokat kell letárolni. Utóbbinál így az űrlap dinamikusan generálható lenne, "csak" az adatbázisban lenne kicsit áttekinthetetlen a dolog. Pontosabban hogy oldjam meg a keresést, illetve az olyan jellegű szelektálást hogy az eredményhalmaz az első megoldáshoz hasonló legyen? Tehát ami a tulajdonság táblában egy sor, az itt egy oszlop legyen. Ugyanitt felmerül a performancia kérdése, hogy ha keresnem kell akkor hogyan keresek? Jó, hozzájoinolom a kapcsolótáblát a megfelelő tulajdonság-azonosítóval, és a tulajdonság-értékre már tudok keresni. De itt a típusok, stb miatt lesznek gondjaim szerintem.

Hogy oldanátok ezt meg? Maradjak az elsőnél és kézzel vegyem fel mindig az új mezőket?
Oszd meg!
  • E-mail