Adatbázis - perzisztenciaréteg készítése (php)
2010-02-23T13:38:46+01:00
2010-02-25T19:57:34+01:00
2022-07-25T06:04:32+02:00
  • Hát ha az ember alapból osztályokkal dolgozik, akkor sokkal jobb, ha példányokat kap vissza. Az hierarchikus adatkezelés megoldása mondjuk elég bonyolult, nekem még az sem tiszta, hogy maga a felület milyen legyen. Pl xpath alapú lekérdezés jól hangzik, csak szerintem iszonyatosan bonyolult a megvalósítása úgy, hogy gyors is legyen.

    Nem szeretem az ORM-eket, legalábbis a hagyományos módon. Mindegyiknél szerintem teljesen feleslegesen meg kell tanulni az ORM nyelv szintaxisát stb.. Sokkal egyszerűbb szerintem egy jól megtervezett felületet kezelni, mint minden feladatra új nyelvet tanulni. Ha jól rémlik a zend framework is valami objecteset használ. Majd megnézem a linkedet, hátha megtetszik. Talán jobb lenne egy már kész rendszerrel foglalkozni, mint sajátot csinálni.
    Mutasd a teljes hozzászólást!
  • Nézd meg ezt a hírt: Cassandra-ra tér át MySQL-ről a Twitter - Hírek - Prog.Hu

    Utána néztem ennek a Cassandra-nak, és a dokumentációban található példakód hogy is mondjam: "kísértetiesen hasonlít" a te megoldásodhoz. Bár ez nem egy SQL-t elfedő réteg, hanem ez maga az adatbáziskezelő. Van PHP példakód is: mjpearson/Pandra

    Érdemes lenne elgondolkodni azon, hogy a jövő tényleg ennyire nem az SQL nyelvű relációs adatbáziskezelőké?
    Mutasd a teljes hozzászólást!
  • Nos összedobtam, hogy kb hogy fog kijönni, amit írtál:
    //mezők: $hozzaszolasID=new IntegerField(); $hozzaszolasID->setName('hozzaszolas_id'); $topikID=new IntegerField(); $topikID->setName('topik_id'); $felhasznaloID=new IntegerField(); $felhasznaloID->setName('felhasznalo_id'); $felhasznaloNev=new TextField(); $felhasznaloNev->setName('felhasznalo_nev'); $hozzaszolasDatum=new DateField(); $hozzaszolasDatum->setName('datum'); $hozzaszolasModeralva=new BooleanField(); $hozzaszolasModeralva->setName('moderalva'); $hozzaszolasSzoveg=new TextField(); $hozzaszolasSzoveg->setName('szoveg'); $elozmenyID=new VirtualField($hozzaszolasID); $elozmenyID->setName('elozmeny_id'); //táblák: $hozzaszolasok=new HierarchicalTable(); $hozzaszolasok->setName('hozzaszolasok'); $felhasznalok=new Table(); $felhasznalok->setName('felhasznalok'); $hozzaszolasID->bindAsKey($hozzaszolasok); //Field -> primaryKey $elozmenyID->bindAsKey($hozzaszolasok); //VirtualField -> hierarchicalParentKey $topikID->bind($hozzaszolasok); $felhasznaloID->bindAsKey($felhasznalok); $felhasznaloID->bind($hozzaszolasok); $felhasznaloNev->bind($felhasznalok); $hozzaszolasDatum->bind($hozzaszolasok); $hozzaszolasModeralva->bind($hozzaszolasok); $hozzaszolasSzoveg->bind($hozzaszolasok); //osztályok class User { public function setId($id){...} public function setName($name){...} //itt ha null-t kap, akkor [megszűnt felhasználó] lesz .... } class Comment { public function setDate($date){...} public function setModerated($moderated){...} public function setContent($content){...} public function setUser(User $user); public function setPremise(Comment $premise); } //mező setter párosítás $userClass=new ClassPointer('User'); $userClass->addSetter('setId',$felhasznaloID); $userClass->addSetter('setName',$felhasznaloNev); $commentClass=new ClassPointer('Comment'); $commentClass->addSetter('setDate',$hozzaszolasDatum); $commentClass->addSetter('setModerated',$hozzaszolasModeralva); $commentClass->addSetter('setContent',$hozzaszolasSzoveg); $commentClass->addSetter('setUser',$userClass); $commentClass->addSetter('setPremise',$commentClass); //ugye a virtualról tudja, hogy az a parentID, itt pedig az azonos osztályból tudja, hogy ide kell betennie.. //kritériumok: $topikParam=new Param(); $adottTopik=new Criteria($topikID,'equals',$topikParam); $condition=new Condition(); $condition->addCriteria($adottTopic); $selection=new Selection(); $selection->addCondition($condition); $selection->requiredClass($commentClass); $selection->setHierarchicalDepth(1); //itt azt lövi be, hogy a setPremise csak egy szintet lépjen vissza (ne legyen rekurzív) //a hierarchikus mezőket nem lőttem be pontosan, szóval ezzel a megoldással lekéri az összes comment-hez tartozó mezőt, meg az user-hez tartozót is... //nyilván ezt is szabályozni kell majd valahogyan $irany=new Param(); $kezdo=new Param(); $hossz=new Param(); $selection->order($irany);//itt számít, hogy melyiket adtuk meg először.. ugye oder limit és limit order nem ugyanazt adja $selection->limit($kezdo,$hossz); $connection=new Connection(); $connection->bindParam($topikParam,123); $connection->bindParam($irany,'ascending'); $connection->bindParam($kezdo,0); $connection->bindParam($hossz,50); $connection->execute($selection);

    Ami biztosan más lesz az a Param megadása, valszeg a Paramokat el fogom nevezni, és a bindParam ezekkel a nevekkel lesz meghívva, mert így lehetséges olyan Template fájlt csinálni az SQL-ről, ami csak a paramétereket várja, és SQL-t ad vissza.

    A selection-ben szabályozni kéne, hogy milyen mezőket setteljen, ez viszont már nehezebb eset, mert attól is függ, hogy éppen milyen mélységben vagyunk... Ugye az előzménynél kevesebb dolgot kérek le, mint a hozzászólásnál. Meg úgy egyébként a Setter sem egyértelmű, mert gyereket ugyanúgy megadhatunk, mint szülőt, szóval jelezni kellene valahogyan az irányt itt:
    $commentClass->addSetter('setPremise',$commentClass);


    Gyakorlatilag a munka nagy része, ugyanúgy, mint az ORM-eknél általában a mezők és táblák szerkezetének bevitele.. A lekérdezés maga csak annyi, amennyi a $selection-ben van, az IF-es részeket meg inkább átpakoltam a setterekbe, mert szerintem ott a helyük. (A hierarchikus szerkezet kezelő nyilván nem settel előzményt, ha nem talál megfelelő id-t...)
    Mutasd a teljes hozzászólást!
  • Egyelőre még biztosan nem tudnék összerakni egy nagyon bonyolult szerkezetet ezzel a módszerrel, mert még vannak dolgok, amik nem teljesen tiszták.

    A lekérésed viszonylag egyszerű. Gyakorlatilag egy parent_id-vel rendelkező hierarchikus adatszerkezet miatt van szükség a subqueryre. Ugye a hozzaszolas.id és a hozzaszolas.hozzaszolas_id ugyanarra a tulajdonságra mutatnak, csak ez utóbbi a parent_id. Ez alapján már lehet generáltatni kódot, viszont a felület még nem állt össze teljesen fejben, majd agyalok még egy kicsit rajta, aztán leírom.

    A limittel lehetnek még gondok, ha subquery-ben kell, meg a groupby-sortby összetételekkel, mert ugye lehet rendezni csoporton belül is, stb...

    Mutasd a teljes hozzászólást!
  • Hát megpróbálom ezt a joinosat felépíteni Ebből tanul az ember, mert ha nem sikerül, akkor módosítani kell a rendszert
    Azt hallottam, hogy nagy lekérdezéseknél érdemes view-eket használni, mert sokkal gyorsabbak, szóval nem tudom, hogy mennyi értelme van ilyen rétegeket írni, de azért megpróbálom
    Mutasd a teljes hozzászólást!
  • Szerintem ez jó lenne így ahogy van, ha nem fordulna elő sosem, hogy egy kicsit összetettebb lekérdezést kell csinálni. Például nehezen oldanád meg így az alábbi MySQL query-t, pedig egy csak egy fórum egy topikjában a megadott oldalszámon a megadott X hozzászólás tulajdonságait adja vissza (a relációs jelek közé rakott készek értelemszerűen behelyettesítendő adatokat jelölnek):

    SELECT h.id AS id, h.topik_id AS topik_id, h.felhasznalo_id AS felhasznalo_id, IF(f.felhasznalonev = NULL, '[megszűnt felhasználó]', f.felhasznalonev) AS felhasznalonev, h.hozzaszolas_id AS hozzaszolas_id, IF(h.hozzaszolas_id <> 0, e.felhasznalonev, '') AS elozmeny_felhasznalonev, IF(h.hozzaszolas_id <> 0, e.datum, '') AS elozmeny_datum, h.moderalva, h.datum, h.szoveg FROM hozzaszolasok h LEFT JOIN felhasznalok f ON f.id = h.felhasznalo_id LEFT JOIN ( SELECT bh.id AS id, IF(bf.felhasznalonev = NULL, '[megszűnt felhasználó]', bf.felhasznalonev) AS felhasznalonev, bh.datum AS datum FROM hozzaszolasok bh LEFT JOIN felhasznalok bf ON bf.id = bh.felhasznalo_id ) e ON e.id = h.hozzaszolas_id WHERE h.topik_id = '<A_TOPIK_AZONOSÍTÓJA>' ORDER BY h.datum <RENDEZÉSI_IRÁNY> LIMIT <OLDALSZÁM_SZERINTI_KEZDŐ_HOZZÁSZÓLÁS>, <EGY_OLDALON_LEVO_HOZZASZOLASOK_SZAMA>;

    És ebben semmi extra nincs, alap tulajdonságokat adja vissza (előzény megjelölésével).

    De egy korábbi projektemben volt olyan MySQL query, ami (igaz, hogy az áttekinthetőség/olvashatóság miatt) közel 100 soros lett, mire korrektre elkészült. Na ezt a hatalmas query-t már megérheti a te módszereddel felépíteni, miel ekkora lekérdezésnél már átbillen a mérleg a te módszered áttekinthetősége és a MySQL kód olvashatósága között. A gond az, hogy az a böhöm query annyira összetett lett, hogy magát a lekérdezést külön részletesen le kellett dokumentálni. Egy ennyire bonyolult lekérdezést össze tudnál rakni a te módszereddel? Ha igen, profi munkát végeztél.
    Mutasd a teljes hozzászólást!
  • Üdv.

    Próbálok összehozni egy perzisztenciaréteget, amit fokozatosan bővítenék, attól függően, hogy éppen mire van szükségem. Egyelőre azon gondolkodom, hogy hogyan kéne belekezdeni mindebbe, aztán gondoltam hátha akadnak itt olyanok, akiknek vannak jó ötleteik.

    Úgy indultam el, hogy vannak Field és Table ősosztályaim, és ezek mellett FieldSet és TableSet gyűjteményeim. Úgy vettem észre, hogy a "mezőket kötöm a táblákhoz" megközelítés jobb, mint a "tábla tartalmazza a mezőket". Példa az ilyen típusú felépítésre:
    //tables: $users=new Table(); $users->setName("users"); $books=new Table(); $books->setName("books"); $usersBooks=new Table(); $usersBooks->setName("users_books"); //fields: $userID=new IntegerField(); $userID->setName("user_id"); $userName=new TextField(); $userName->setName("user_name"); $bookID=new IntegerField(); $bookID->setName("book_id"); $bookName=new TextField(); $bookName->setName("book_name"); //bounds: $userID->bindAsKey($users); $userName->bind($users); $bookID->bindAsKey($books); $bookName->bind($books); $userID->bind($usersBooks); $bookID->bind($usersBooks);

    Kiválasztásnál a lehető legtöbb dolgot automatizálni szeretném, valami hasonló felületre gondoltam, mint a most következő.
    Ugye fent megadtam, hogy az users össze van kötve a books-al... Na most csináltam User és Book osztályokat. Ezeket nem a táblákkal, hanem a mezőkkel kötöm össze.

    Szóval az osztályok:
    //classes: class User { public function setId(int $id) {...} public function setName(string $name) {...} public function addBook(Book $book) {...} public function getBooks() {...} } class Book { public function setId(int $id) {...} public function setName(string $name) {...} }

    és a nekik megfeleltetett mezők:
    //class fields: $user=new ClassPointer('User'); $user->addSetter('setId',$userID); $user->addSetter('setName',$userName); $book=new ClassPointer('Book'); $book->addSetter('setId',$bookID); $book->addSetter('setName',$bookName); $user->addSetter('addBook',$book);
    A mezőknél úgy szeretném megoldani, hogy ha osztályra hivatkozást adok meg a setternek, akkor azt automatikusan GROUP_BY-nak vegye, és összekötő táblát keressen hozzá....


    Egy lekérdezés meg kb így menne:
    (ez a része még nem teljesen tiszta, szeretném majd olyanra megoldani, hogy lehessen cachelni a kapott SQL-t...)
    //selection: $nameInput=new TextParam(); $connection=new Connection(); $connection->bindParam($nameInput,'Béla Kovács'); $connection->bindParam($nameInput,'István Kiss'); $connection->bindParam($nameInput,'Olga Kirpicsova'); $criteria=new Criteria($userName,'equals',$nameInput); $condition=new Condition(); $condition->addCriteria($criteria); $selection=new Selection(); $selection->addCondition($condition); $selection->requiredClass($user); $userInstances=$connection->execute($selection); foreach ($userInstances as $userInstance) { print('<div class="user">'); print('<a href="http://x.com/users/'.$userInstance->getId().'/">'.$userInstance->getName().'</a>'); print('<div class="books">'); foreach ($userInstance->getBooks() as $bookInstance) { print('<a href="http://x.com/books/'.$bookInstance->getId().'/">'.$bookInstance->getName().'</a><br />'); } print('</tbody>'); print('</div>'); print('</div>'); }

    A kérdésem annyi ezzel kapcsolatban, hogy szerintetek jó e ez a felület, úgy általánosságban az adatbázis eléréshez, vagy gyakran csődöt mondana bonyolultabb lekérdezéseknél, vagy bizonyos adatbázis típusoknál??
    (Konkrétan azért kérdezem, mert nincsen valami szerteágazó tapasztalatom adatbázisok terén.)
    Mutasd a teljes hozzászólást!
abcd