2 rétegű alkalmazásból 3 rétegű

2 rétegű alkalmazásból 3 rétegű
2008-09-13T10:10:44+02:00
2008-09-19T01:35:42+02:00
2022-10-29T10:15:42+02:00
  • csuri: Nem szeretném az egyébként értelmes és érdekes párbeszédet a flame szintjére süllyeszteni, ezért nem reagálok részletesen most az általad elmondottakra. Szeretném elmondani, hogy nem tartom jónak előre rossz jelzővel minősíteni mások véleményét és később is csak kulturált körülmények között vagyok hajlandó értekezni bármiről. Mindezt ne vedd sértésnek, de remélem világos, hogy véleményemmel nem támadtalak, és eztán sem célom. Kérlek eszerint állj hozzá te is az enyémhez! Ha így teszel, megköszönöm!

    s720: Ha sikerült átgondolni az alapján, amit Csuri javasolt, megkérhetlek, hogy megoszd velünk?
    Mutasd a teljes hozzászólást!
  • Sziasztok,

    Köszönöm a hozzászólásokat.

    A dinamikus SQL ötlet az nagyon jó, erre nem gondoltam, hogy így adjak át mátrix típusú paramétert.

    Ezzel, és az ideiglenes táblákkal egymást hívó tárolt eljárásokkal tulajdonképpen meg lehet oldani.

    Ha az átállás csak a már említett okok miatt kéne, akkor el is fogadom ezt és ebbe az irányba lépek. Azonban a rendszert tovább is kell fejleszteni. Éppen ma beszéltem erről a társammal. Az elképzelését úgy lehet megoldani, hogy egy új mezőt veszek föl az adatbázison lévő néhány táblába, mely egy 60 (3*20) karakteres kódból állna ezt 3 karakterenként értelmezni kell, egy olyan adathalmazzal ami a felhasználótól érkezik majd egy 3 szintes feltételsorozat után kiderülne, hogy mely értékekkel kell elvégezni a műveleteket. Ezt is meg lehet oldani Firebird-ön, de valahol tényleg külön szeretném választani az adatkezelést az értelmezési, számítási feladatoktól. Később (akár a mostani fejlesztésnél) úgy érzem több problémám lesz a 2 rétegben, tárolt eljárásokban, mintha most megtenném az átalakítást.
    Ha van egy középső réteg, akkor a kommunikációs lehetőségek is megnőnek, és könnyebben tudok hozzá alkalmazkodni.

    Captain Crash kérésére
    Mint írtam a DataSnap-pal próbálkozom, ezen belül a SocketConnectionnal. Az ügyfél alkalmazásból így a DataSet-tek átkerültek a középső rétegre, illetve az ügyfélnél lévő számítások is átkerültek. Tehát maradt a felhasználói felület, annak kezelhetősége és 3 ClientDataSet. A Firebird-ön a tárolt eljárásokban csak a lekérdezéseket és minimális számítási feladatokat hagytam. Például olyat, hogyha a beérkező adathalmazban a devizanem nem egyezik a lekérdezett adathalmazban a devizanemmel, akkor azt a deviza táblában szerepelő árfolyamon átváltja. (Persze itt is figyelni kell, hogy mikor számoljak deviza, és mikor pedig valuta árfolyamon, de ez is benne van a beérkező adathalmazban).
    Csuri dinamikus SQL javaslatára viszont újragondolom a Firebird és a középső réteg közti megosztást.
    Mutasd a teljes hozzászólást!
  • Jön a Flame, jön a Flame...

    Nézd, a kérdező egy gyorsan megvalósítható és lehetőleg egyszerű megoldást keresett, én mondtam egyet.
    Nem hinném, hogy egy kis programnál ami ráadásul meg van valósítva 2 rétegben, egyetlen funkció miatt érdemes az egészet átrakni 3 rétegre, ráadásul mindenzt Delphiben.
    Szép és jó a Delphi, jómagam is szeretem, de ha körbenézel a neten, nem nagyon találsz nagy 3 rétegű projekteket benne.

    Abban igazad van, hogy 2 rétegnél nincsenek meg azok az előnyök, amelyek 3 rétegnél megvannak (pl.: cache-elés), de egy kisebb projektnél ezek nem jelentős dolgok, ráadásul ezeket mind meg kell valósítani, nincs olyan keretrendszer készen, mint pl. egy J2EE alkalmazásszerverben. Ennyi többletmunka egy egyszemélyes projektnél SZVSZ kidobott erőforrás.

    Amúgy meg a tárolt eljárás még 3 réteg esetén is elfogadható abban az esetben, ha egy jól körülírt, pontosan specifikált, a fő funkcióktól jól elkülönülő funkció megvalósítására használod. (A leírás szerint ez ilyen.) Ugyanis ha portolni kell a programot egy másik adatbázis szerverre, akkor nincs más dolgod, mint megírni az SP-t az új szerveren.
    Amúgy sem hinném, hogy jó gondolkodás az, hogy egy ritkán előforduló, a projektek többségénél soha szóba nem kerülő dolog miatt (új db szerver típusra átállás) komoly erőforrás felhasználás növekedést (hálózati overhead, az alkalmazás szervert terheljük mindennel ahelyett, hogy elosztanánk a feladatokat, stb.) érdemes bevállalni.
    Mutasd a teljes hozzászólást!
  • s720: Előre szeretném leszögezni, hogy nem értek a Delphi-hez ilyen szinten, sem a FireBird adta lehetőségekhez. Ennek fényében gyakorlati megvalósítást nem tudok javasolni, csak a meglátásomat írnám le. Remélem azért ez is segít.

    Általában a "2 rétegű alkalmazásból 3 rétegű alkalmazás" megvalósítási célként jobban hangzik, mint egy olyan ahol a tárolt eljárásba kerül az üzleti logika. Nem látom át, hogy pontosan milyen adatmozgásokra lenne szükség, de abból kiindulva, ami az elején elhangzott, vagyis, hogy "a felhasználók adatokat nem módosítanak" logikusnak tűnik egy közbenső réteg alkalmazása.

    A tárolt eljárás mellesleg alkalmazható, de nem abba helyezném az üzleti logikát, minthogy ez is a több réteg kialakításának egyik célja, hogy lehetőleg minél jobban függetlenítse az adattártól az üzleti logikát. A több réteg mellesleg további olyan lehetőségeket rejt magában, mint például a cache-elés lehetősége.

    Nem tudom milyen megoldásra sikerül jutni a végén, de remélem megosztod velem, velünk.

    u.i.: És bocsi csuri, hogy a te hozzászólásodra nyomtam rá, hogy válaszoljak. :)
    Mutasd a teljes hozzászólást!
  • A Firebird képes dinamikus SQL utasítás futtatására tárolt eljárásban, vagyis megteheted, hogy egy String-be összerakod az SQL utasítást és azt futtatod.
    Ezen kívül tud táblázatot visszaadni a kimeneten. A SUSPEND parancs menti a kimeneti változók aktuális értékét és utána továbbfut a tárolt eljárás.

    Pl.:
    Ez a tárolt eljárás egy a bemeneten megadott táblából legyűjti az összes sorból a két értéket, majd - poénból - betesz még egy sort, hogy lásd, hogy ilyet is lehet csinálni.
    A kimeneten meg fog jelenni az összes érték, mintha egy tábla lenne - és úgy is tudod kezelni.
    CREATE PROCEDURE TESZT(TABLANEV VARCHAR(30)) RETURNS(ERTEK1 VARCHAR(30), ERTEK2 VARCHAR(30)) AS DECLARE VARIABLE query VARCHAR(1000); BEGIN query = 'select ERTEK1, ERTEK2 from ' || TABLANEV; FOR EXECUTE STATEMENT :query INTO :ERTEK1, ERTEK2 DO BEGIN --Itt kiíródik a kimenetre egy sor. SUSPEND; END --Ezt csak azért csinálom, hogy lásd, hogy ez az SP-ben bárhol használható. ERTEK1 = 'Vége a táblának!'; ERTEK2 = 'Király!!!'; SUSPEND; END
    A szépsége a dolgonak, hogy a kimeneten megjelenő rekord halmaz úgy viselkedik, mint egy tábla, vagyis a programból - vagy másik tárolt eljárásból - így kell meghívni:
    select * from TESZT('LekerdezendoTabla')
    És természetesen lehet rá minden lekérdező utasítást végrehajtani rá:
    select ERTEK1 from TESZT('LekerdezendoTabla') where ERTEK2 = 'A'
    Mutasd a teljes hozzászólást!
  • Szia,

    Egy hasonló megoldással próbálkoztam de nem azt produkálta amit én szerettem volna. Most már látom is hogy miért
    Én a for select-be raktam a sajáttáblát és a do utáni selectbe a segédtáblát.

    Azonban még így is többször kell ehhez a tárolt eljáráshoz fordulni, az ügyféltől hogy a végeredményt megkapjam. Ezért gondoltam, hogy a középső rétegen gyűjtök össze mindent ami a Firebird-del azonos gépen lenne, és csak egy fogadás és egy küldés lenne a kliens felé.

    A segédtábla azonosítói így néznek ki:
    A1; A1; A1; A2; A2; B1; B2; B2

    Annak is jelentősége van, hogy A-val vagy B-vel kezdődik, mert az határozza meg melyik saját táblához kell fordulni.

    Azért most elgondolkodtam azon, hogy lehet-e olyan tárolt eljárást írni ami a segédtáblából egy FOR SELECT DISTINCT-tel lekéri az AZON-t majd ezeken egyesével végigmegy és meghívja az általad írt eljárást.

    Ez azt jelenti, hogy kell egy segédtábla a beérkezett paramétereknek, kell egy segédtábla az elküldendő eredmény tárolására. Ebben az esetben azt kéne megoldani, hogy ezt hogyan juttatom vissza a klienshez? DataSnap esetén ezt a DataSetProvider aktiválásával oldanám meg.

    Talán még ez is megoldható, ha egy OK visszatérési értékkel jelzem, hogy befejeződött a tárolt eljárás, és le lehet szedni az eredményttáblát.

    Ez járható ha egy Linuxos Apache szerveren keresztűl kéne elérni a Firebird-öt, ami egy Windows szerveren fut?
    Mutasd a teljes hozzászólást!
  • Én még nem láttam olyan adatműveletet, amit nem lehet megvalósítani SQL szerveren, szerintem jobban jársz ha inkább ott próbálkozol.
    A kulcsszó: tárolt eljárás(stored procedure).
    Minden adatbázisszervernek van egy saját programnyelve - nem kell megijedni, ez a nyelv nagyon egyszerű -, ahol meg lehet oldani a komolyabb dolgokat is. Ilyen lehetőség van a Firebirdben is.
    Előnye, hogy minden művelet az SQL szerverben hajtódik végre, vagyis mindenféle hálózati forgalom nélkül, a lehető leggyorsabban megtörténik.

    A paraméterátadás is megoldható pl. így:
    Csinálsz egy segédtáblát, amibe a program lerakja a paramétereket egy egyedi azonosítóval, majd a program meghívja a tárolt eljárást, aminek átadja az egyedi azonosítót, innentől a tárolt eljárás végig tud gyalogolni a paramétereken.
    Egy kis példa FireBird tárolt eljárás, ami kb. tartalmazza, ami neked kell:
    CREATE PROCEDURE TESZT( AZON INTEGER, RETURNS ( OK BOOLEAN, EGYEBVISSZA INTEGER AS BEGIN :OK = false; --Itt bármilyen SQL utasítás kiadható FOR Select PARAMETER FROM segedtabla WHERE azon=:AZON INTO :valtozo DO BEGIN --Itt tudsz egyesével dolgozni a paraméterekkel SELECT ertek FROM sajattabla WHERE azon=:valtozo INTO :egyebvissza; END DELETE FROM segedtabla WHERE azon=:AZON; :OK = true; END
    Mutasd a teljes hozzászólást!
  • Szia,

    Sajnos csak a Delphi tudás az ami adott, így ebbe kell gondolkodnom.

    Delphi.NET azthiszem felejtős. Ha majd .NET-es alkalmazásokat kell létrehoznom akkor kénytelen leszek megismerkedni a C#-pal. Vagy ki tudja mit hoz a jövő
    Mutasd a teljes hozzászólást!
  • Szia,

    Köszi a linkeket, melyek tulajdonképpen arról szólnak, hogy a DataSnap megoldás választásával a probléma megoldásában jó irányban haladok Azt persze nem állítom, hogy a lehetőségeim közül ez a legjobb...

    Az XML bennem is felmerült, hiszen a DataSnap-pal is egy adathalmazt küldök át, majd egy adathalmazt fogadok. Erre lehet hogy későbbiekben át fogok térni, de mivel még nem használtam, első körben ha nem muszáj nem próbálkoznék vele. Eddig olyan jól megvoltam a ClientDataSet-tel

    Főiskolás éveimben a Delphi mellett döntöttem így az abban szerzett tudás az adott... Más eszközzel lehet hogy jobban meg lehet oldani, de ez nem csak eszköztől hanem tudástól is függ. Kevés tudással egy jobb eszközzel is rosszabb alkalmazás készül.

    A CGI féle megoldás is benne volt az elképzeléseimben. Ezt az Indy idHTTP komponensével gonsoltam az általad is említett GET, POST-tal.Pesze az Indy-ben vannak más lehetőségek is, csak nem akartam ezzel a véleményeket befolyásolni.
    Mutasd a teljes hozzászólást!
  • Szia!

    Én a Delphis középső réteget nem eröltetném, hacsak nem szorít az idő.

    Inkább .NET-es webservice-t készítenék, és azt hívnám meg a delphis kliensből.

    Azt nem tudom, hogy a Delphi alapú .NET-es eszközöknek van-e ingyenes verziója, de a VB.NET, ill. C# alapú MS eszközöknek van (Visual Studio Express Edition-ök, és a Web Developer Express).


    üdv
    ex rem ember
    Mutasd a teljes hozzászólást!
  • Hello!

    Annó én megprobáltam még Delphi 3, majd 5 alatt, de akkor még túl bonyolult volt (ó, azok a főiskolás évek ...

    Pár jó oldal, talán segít (angol)

    Hogyan gyorsítsuk:
    Success

    A 3. réteget, mikor, mivel:
    http://dn.codegear.com/article/27860

    Ez egy jó leriás, igaz DB2-re, de az mindegy:
    IBM Db2 – Data Management Software

    Én személy szerint XML-ben csinálnám, mert az hordozható és nem biztos, hogy Delphiben. Ha Delphi, akkor lehet, hogy egyszerűbb lenne egy CGI-t csinálni, ami POST-al megkapná az adatokat, majd XML (CSV -ben visszaküldené. Elég egyszerű és fájdalom mentes.

    Remélem vmit azért segít rajtad.



    Mutasd a teljes hozzászólást!
  • Tessék rendesen megírni azt a programot


    Ehhez kértem segítséget.
    Mutasd a teljes hozzászólást!
  • Szia,

    Helyi hálózatról Internetes átalakítás miatt kell. Vagyis csak részben emiatt, mert zavart az, hogy az ügyfél gépére rákerülnek olyan adatok, amelyekkel csak számolni kell.

    Ha az megoldaható lenne, hogy Firebird-ön mindent meg lehet oldani akkor maradhatna, de sajnos nem így működik, mivel nem lehet (vagy nem tudok róla hogy lehet) mátrix típusú paramétereket átadni, és a számolások mindegyikét se tudtam ott megoldani, csak a kliensen.

    Tehát nem az a kérdés, hogy 2 vagy 3 réteg legyen, mert az számomra már nyílvánvaló, hogy akár a későbbi továbbfejlesztés miatt csak az jöhet szóba, hogy a kliensről elküldök egy adathalmazt, a középső réteg ezen adathalmaz alapján elvégzi a szükséges lekérdezéseket, ideiglenes táblákba, majd ezekkel a táblákkal és a klienstől kapott adathalmazzal számol (Delphiben már megírt és tesztelt algoritmusokkal), majd az eredményt visszaküldi.

    Jelenleg a DataSnap mellett tettem le a voksom és azzal próbálkozom, de egyáltalán nem vagyok benne biztos, hogy ez a jobb megoldás.
    Lehet, hogy egy Linuxos Apache szerveren keresztül történne a középső réteg elérése, és akkor valószínüleg az Indy lenne a jobb megoldás.
    Mutasd a teljes hozzászólást!
  • Építő hozzászólás volt.

    Köszönjük...
    Mutasd a teljes hozzászólást!
  • Ha helyi hálóról beszélünk, akkor nem éri meg a munkát. Hasznájl Gbites switchet, és kész


    Ezen fajta hozzáállás miatt állunk ma ott, hogy a Windows Vista akad a 4800+ -os Athlon64X2 2GB RAM, Gef880GTS gépemen...
    Ugyan ezen hozzáállás miatt kell ma már néhány játéknak 2 db dupla rétegű DVD a telepítéshez.
    Lassan már a 4-8 magos gépek sem jók semmire.

    Arról nem is beszélve, hogy nem kéne az ügyfelet hülyének nézni, és rátukmálni, hogy álljon át gigabites hálózatra (lecserélve evvel a switcheket, gépek hálókártyáit, stb.), mikor egy 100mbiten lógó otthoni "szerver" egyszerre kiszolgál 3 db médialejátszót, amik 1080p fullhd filmet játszanak le...
    Ha rám akarna egy fejlesztő/cég rámsózni olyan ügyviteli programot, amhez gigabites háló kell, elküldeném a halál f.a.sz.á.ra, hogy ne szórakozzon már velem.
    Tessék rendesen megírni azt a programot, és nem átrángatni a teljes adatbázis minden egyes lekérdezéshez!
    Mutasd a teljes hozzászólást!
  • Hello!

    10-100 lekérdezés egy adatbáziskezelőnek nem lehet gond. 1000-1000 már kicsit nyűgösebb.

    Ha minden egyes lekérdezés normális, index alapu, akkor 0.01 sec max. egy lekérdezés. 100 db max 1 sec...

    Sőt, mivel egyszerre adnál át egy rakás dolgot, ezért még gyorsabb is lenne.

    A kérdés itt az, hogy megéri-e? Ha helyi hálóról beszélünk, akkor nem éri meg a munkát. Hasznájl Gbites switchet, és kész

    Igazából ez csak interneten át (lassú kapcsolat) érné meg a befektett munkát.
    Mutasd a teljes hozzászólást!
  • Szia,

    Ezzel próbálkoztam idáig. Az egyik problémám az, hogy a Firebird (legjobb tudomásom szerint) nem tud mátrix típusú paramétereket kezelni. Így egy 10 sorból álló paraméterhalmazzal 10 lekérdezést kell csinálni, és mindegyik lekérdezéssel számítások sorozatát kell végrehajtani, majd ha ez kész azt kell visszajuttatni a felhasználóhoz egy eredménytáblában. A 10 sor abszurd esetben akár 800-1000 sor is lehet.
    Ha valahogy mégis meg lehet oldani az adatbázis szerveren akkor is tartok tőle, hogy meg fog feküdni.

    Odáig már eljutottam, hogy a 3 réteg lenne az üdvözítő megoldás, és jelenleg a DataSnap-os megoldással kísérletezgetem, csak azt nem tudom, hogy tényleg ez e jobb megoldás vagy inkább az Indy.

    s720
    Mutasd a teljes hozzászólást!
  • Hello!

    Biztos nem lehet ez simán végrehajtani az adatbáziskezelőben?

    pld. ideiglenes táblákat csinálni "SELECT * INTO TABLE ..." szerűvel...

    Igazából csak így tudnád lecsökkenteni a forgalmat.

    Az igazi 3 réteg meg ugye az lenne, ha a középső réteg futna egy szerveren, és azon keresztül mozgatnál csak adatot...

    üdv,
    Mutasd a teljes hozzászólást!
  • Sziasztok,

    Delphi7 + Firebird

    Van egy 2 rétegű alkalmazás, ahol az ügyfél bejelöl magának bizonyos szempontokat, és így létrehoz egy 1 táblás adathalmazt. A tábla minden egyes rekordjával végrehajt egy lekérdezést, majd az így kapott eredménytáblákkal bizonyos műveleteket hajt végre, melyek végeredménye egy táblázat azonosítókkal és néhány számított mezővel. A felhasználók adatokat nem módosítanak így adatmódosítási ütközésre nem kell figyelni.

    Ez szépen és jól működik, de rengeteg fölösleges adatmozgással jár, és nem szeretném, ha minden adat eljutna a kliensre. Próbáltam a Firebird-ön megoldani, de korlátokba ütköztem és azért egy adatbázis szerver nem erre való A következő megoldásokban gondolkodtam:

    1)DataSnap. Eddig még nem használtam. Jó benne, hogy nem kall bajlódni a távoli adatmodul egyedi létrehozásával, mert a kapcsolódáskor automatikusan létrejön. Viszont nem tudom, hogyan lehet benne megoldani az adathalmaz fogadását, illetve, hogy az adatmodulban az adatok visszaküldése előtti műveleteket.
    2)Indy. Keveset használtam, és nem ilyen jellegű feladatra. Adathalmaz fogadása és küldése megoldható. A szerveren a műveletek ütközésétől tartok. Esetleg minden ügyfél kapcsolódásakor külön szál lehet a megoldás.
    3)XML. Szimpatikus megoldásnak tűnik, de mivel sose használtam csak akkor kezdenék bele, ha Indy-vel vagy DataSnap-pal nem oldható meg.
    4)IntraWeb. Ez nagyon tetszik, bár nem a Delphi7-ben gyárilag lévő 5-ös verzióval. Előnye, hogy valószínűleg erre tudnám a legkönnyebben átalakítani, de hátránya, hogy böngészőn keresztül nagyon körülményes lenne a kezelése

    Szerintetek, melyik megoldás felé induljak el? Ha lehet ne csak egy sorszámot írjatok, hanem hogy miért és lehet valami támpontot is, hogy az adott variáción belül hogyan

    s720
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd