ugrás a tartalomhoz

Php - ORM rendszerek

inf · 2009. Szep. 17. (Cs), 04.06
Sziasztok!

Érdekelne, hogy ORM redszerekkel kapcsolatban kinek milyen tapasztalatai vannak?
Ez az a része a dolgoknak, amit nagyon nem szeretnék saját kezűleg megírni. :-) Én egyelőre a doctrinet kezdtem el nézegetni, és elég szimpatikus a megközelítésük.
 
1

általánosan

krisy · 2009. Szep. 17. (Cs), 09.06
Szia!

PHP-s ORM rendszert még nem használtam, csak JAVA-sat (JPA - Toplink, Eclipselink, mint provider), de szerintem azért tapasztalatként 1-2 dolog mindkét nyelven megállja a helyét :-)

Ami megdöbbentő volt számomra, az az, hogy mennyire gyorsan lehet benne fejleszteni (főleg, ha valami normális IDE-t használ az ember, ami támogatja a code completion-t).
1-2 nap alatt olyan kódot lehet vele írni/generálni, amit ha "kézzel" írsz meg, akkor mondjuk 2-3-szor ennyi idő is elmegy rá.

Viszont persze a hátránya az egésznek (és itt lenne fontos, hogy konkrétan melyik ORM-et választja az ember), a konfigurálhatóság, testre szabhatóság.
Napjaim mentek el olyan apróságokra, hogy pl.: a Toplink nem képes kezelni az időtúllépést, és így "elveszik" a query, illetve előfordul sok olyan eset, amik össze-vissza kell JOIN-olgatnod, meg GROUP BY-olnod, stb. és ezt nem mindig egyszerűen, és ésszerűen lehet megoldani.


Szóval szerintem mindenképpen jó ötlet használni, de könnyedén tud vele szívni is az ember :-)
7

Java ORM

inf · 2009. Szep. 22. (K), 21.47
Hát nekem anno azt mondták, hogy javaban a hibernate AZ! ORM :-)
Azért szeretnék ORMet használni, mert nem szeretnék mindent újraírni majd adatbázis cserekor(ha lesz elég felhasználó, akkor szerver és db váltás lesz előbb-utóbb).
Másrészt meg szeretném megoldani valahogyan az automatikus escapelést,típuskonverziókat etc.... És nem szeretnék hónapokat azzal tölteni, hogy saját ORMet írjak. :-)
9

Hibernate

Ustak · 2009. Szep. 22. (K), 22.34
az jó, én is annak a segítségével fejlesztek most. Először szokatlan, hogy az sql mellé meg lehet (kell) még tanulni két lekérdező nyelvet (hql vagy (és) Criteria API), viszont ha ez megvan, hihetetlen gyorsan lehet benne haladni. Én egy már létező alkalmazás fejlesztésébe szálltam bele, mely már egy létező adatbázisra épült rá. Az ORM lényege viszont, hogy ezt visszafele is megoldhatod a java osztályokból (vagy akár középről elindulva a mapping.hbm.xm. -ekből) mikor is a kész objektum modelledből generálod az adatbázis le. Nos, ilyet nem csináltam, esetleg ez egy elég kacifántos dolognak tűnhet, minthogy a relációs adatbázis az csak nem egy objektum orientált dolog, és mégis úgy kezeli le a hibernate. Egyébként az irodalmak szerint nagyon jól megbirkózik a problémával, bár mindig megemlítik, hogy ennek a kettősségnek hátrányai is vannak.
Eddig phpra CodeIgnitert használtam, most ismerkedem a Kohanaval. Úgy látom abban is van ORM rész, kíváncsi vagyok... esetleg ha van róla véleményetek örömmel fogadom :-)
Béke:
Gábor.

Szerk: Érdemes logolni az sql-t, és így láthatod, mi történik a háttérben. Én így debugoltam legutóbb egy olyan problémát, mikor is a hibernate a .toLowerCase() függvénnyel egy LOWER() -t szúrt be az adott helyre az sql -ben, és nagyon lelassult a dolog...Szerencsére itt a weblaboron találtunk megoldást a problémára (utf8_bin ről utf8_hungarian_ci -re a collation és már nem is kell a lower)
10

Érdekes :-)

inf · 2009. Szep. 23. (Sze), 01.39
Érdekes hallani, hogy tényleg használhatóak ezek a rendszerek. Én egyelőre elgondolkodtam, hogy hogyan kéne nekifutni a dolognak, ha mégis sajátot csinálnék.

Abból indultam ki, hogy vannak tábláid, és van egy felületed, amit egy osztály (vagy aktív rekord) képvisel. Az ORM lényegében a táblákat köti össze a felülettel, szóval az osztály tulajdonságai a táblák megfelelő oszlopainak felelnek meg.

Egyelőre valami ilyesmi használatra gondoltam:


final class UserDataMapper extends DataMapper
{
	protected $dsn='mysql://root.mypswd@localhost:3306/testdb';
	
	public function __construct()
	{
		$this->hasTable('users')
			->hasColumn('uid','integer',8,'required','primary-key')
			->hasColumn('email','varchar',128,'required','unique')
			->hasColumn('realname','varchar',128,'required');
		
		$this->hasInterface('User')
			->hasProperty('id','users.uid')
			->hasProperty('name','users.realname')
			->hasProperty('address','users.email');
	}
}


final class User extends ActiveRecord
{
	public $id=array();
	public $name=array();
	public $address=array();
	
	public function __set(...)
	{
		...
	}
	
	protected function getMapper()
	{
		return UserDataMapper::getInstance();
	}
}

final class UserModel
{
	public function find($name)
	{
		$user=new User();
		$user->name=$name;
		$user->find();
		return $user;
	}
}

final class UserController
{
	public function findByName()
	{
		if ($this->checkName($_POST['name']))
		{
			$user=$this->model->find($_POST['name']);
			$this->view->assign('result',$user);
			$this->view->display('find-user:result.tpl');
		}
		else
		{
			$this->view->assign('name',$_POST['name']);
			$this->view->display('find-user:wrongname.tpl');
		}
	}
}

(Elnézést, ha valahol nem stimmelne az osztályok elnevezése, nem sok lövésem van arról, hogy mi a dataMapper és az activeRecord :D)

Nem tudom, hogy létezik-e ehhez hasonló logikájú ORM, de szívesen használnám :-P Ha nem, akkor lehet, hogy megírom MySQL-re, aztán meg majd PgSQLre. Egyelőre mondjuk még elég hiányos az sql tudásom. A hasTable mellé mondjuk még felvennék egy hasRange tulajdonságot, amivel a JOINokat kezelném le, de ahhoz már fáradt vagyok, hogy arra is írjak az én logikám szerinti példát.

Btw. egyébként nekem nagyon tetszene, ha írnátok példákat arra, hogy az általatok használt ORMben hogyan valósítható meg valami. Szerintem így másoknak is hasznos lehetne később ez a topic.
12

kohana

Drawain · 2009. Szep. 30. (Sze), 00.04
Kohana ORM-jének egy előnye van, nagyon egyszerűen kezelhető, sokkal gyorsabban megtanulható, mint mondjuk egy Doctrine-t. Egyébként nem túl gyors és nem is lehet benne mindent megcsinálni, amit másban (bonyolultabb sémák esetén). Másrészt én mégis ezt használom és meg vagyok vele elégedve, olyan óriási forgalmú oldalakat még nem csináltam, ahol szükség lett volna a cseréjére.
2

doctrine

Drawain · 2009. Szep. 17. (Cs), 10.05
Standalone ORM-ekből én is a doctrine-t választanám - bár jómagam a kohana beépített könyvtárát használom. Annak idején mikor még sokat foglalkoztam a Symfony-val az előbbit egekig magasztalták a Propellel szemben (sebesség kérdésében), bár nekem a Propel szintaktikája jobban bejött.
Másrészt - szerintem - nem kell a használatuktól félni, egy idő után az ember rájön mikor érdemes használni az ORM-et és mikor a hagyományos lekérdezéseket, hogy optimális maradjon az oldal.
3

sebesseg

carstepPCE · 2009. Szep. 17. (Cs), 10.54
hat en is hasznaltam ORM-t, tobbek kozott a Doctrine -t is, de egy dolog nagyon aggasztott, az pedig a sebesseguk es memoriaehseguk. Szerintem konnyu vele dolgozni, de ha sebessegre es memoriara kell optimalizalni, akkor en abban a pillanatban ki is huznam oket a listarol (pont ezert nem is kezdtem el e symphonyt keretrendszert tanulni, mert az ORM miatt eszetlen lassu)

that's my 2 cent

-cs-
Sanyi
4

számított?

krisy · 2009. Szep. 17. (Cs), 13.20
Számított ennyire a sebesség, vagy volt ennyire lassú?
Úgy értem, általában több nagyságrenddel nagyobb szokott lenni 1-1 oldal letöltődése,renderelése, mint mondjuk a generálása, illetve az adatbázis lekérdezések.

Bár biztos vannak olyan esetek, amikor számít :-)
5

ORM vs sebesség

fchris82 · 2009. Szep. 17. (Cs), 13.44
Nem igazán jó a hozzáállásod és az érvelésed.
1. Tökéletes programot nem fogsz tudni csinálni! Mindenhol és mindig lehet optimalizálni, gyorsabbat készíteni, csak van egy pont, aminél nem éri meg több időt a kódra szánni, mert egyszerűen plusz havi 10$ kiadással raksz alá nagyobb vasat és többet gyorsul az egész, mint ha hetekig tökölne az ember a további optimalizálással.
2. A sebességet nem kell túlmisztifikálni! Meg kell mérni, hogy egyáltalán mi és mennyi ideig tart. Ha az derül ki, hogy eleve nagy mennyiségű adattal kell dolgozni az adatbázisban és vannak lekérések, amik önmagukban tized másodpercig tartanak, akkor teljesen mindegy, hogy a te PHP kódod 50 vagy 100 század másodperc alatt fut le, ha a teljes idő 60-80%-a az adatbázis lekéréssel megy el.
3. Az idő pénz! És ne felejtsük el, jobb ma egy veréb, mint holnap egy túzok! Egyrészt az ORM és a keretrendszerek:
- jelentősen tudják csökkenteni a fejlesztési időt (értsd: 6-10 hónap helyett -> 3-4 ez egyáltalán nem elhanyagolható különbség)
- átláthatóbbá és könnyebben fejleszthetővé teszi az elkészült munkát
- csökkenti a hibalehetőségek számát egyes komplexebb lekéréseknél
- amennyiben úgy látom jónak - van ilyen -, sima MySQL-es lekérést használok továbbra is, tehát megtehetem, hogy egyes helyeken mégse használom

Ez az egész kicsit hasonlít arra, mint régen a PHP (vagy más script nyelv használata) vs C++ . Lehet, hogy az utóbbival nagyon gyors oldalakat lehet csinálni, de a fejlesztési idő össze sem vethető a PHP-val. Egyszerűen a keretrendszerrel olyan előnyökre teszel szert, amik bőven kárpótolják az esetek többségében a sebességvesztést.

Persze a fentiek nem szentírások. Egyszerű weboldalaknál mi sem használjuk a Symfony-t, de komplexebbeknél, ahol tényleg hónapos fejlesztési időről beszélünk, fel se merül, hogy a sebesség miatt "pure PHP-ban" írogassunk. Ha az oldal terheltsége indokolja, később átírjuk, de ha pl nem válik be az üzleti elképzelés, és az oldal nem hoz annyi látogatót, vagy az a mennyiség, amennyit hoz, bőven elfut Symfony-n is (vagy más keretrendszeren, itt most az elv a lényeg, nem a konkrét rendszer), akkor felesleges pénzkidobás és időpazarlás lett volna sebességmániában körüllengve 2-3-szor annyi idő alatt egy kb 50%-al gyorsabb oldalt összedobni, miközben esetleg század, maximum tized másodpercekről beszélünk. Az a 2-3-szoros időtényező pedig olyan, mint a nyugdíjkorhatár: 1 év eltolás 2 év "nyereség". Ugyanis nem elég, hogy a plusz fejlesztési idő pénzbe kerül, azon idő alatt nem is termel!
Sokkal de sokkal fontosabb, hogy gyorsan legyen egy működő oldal, mint hogy később legyen egy majdnem tökéletes.

A keretrendszerek ráadásul bizonyos kereteket kényszerítenek rád, ami inkább előny, mint hátrány. Sok esetben még a későbbi bővítés is gyorsabban megy bennük. (Pl írok egy új filtert 30 sorban és már kész is, saját rendszer esetén meg lehet, hogy 6 fájlban kellene átírnom dolgokat - tudom, mert 10 éve ezt csinálom és anno, keretrendszerek nélkül is csináltam nagyobb munkákat, vagy éppen saját keretrendszert)

Hogy a topikot nyitónak is válaszoljak:
Én használtam Propelt és Doctrine-t is. Az utóbbinál sokkal kevesebbszer kellett kerülő megoldáshoz folyamodnom - értsd: magam írtam be az SQL lekérdezést -, abból kifolyólag, hogy nem vagy csak nagyon bonyolultan lehetett volna összerakni a szükséges lekérdezést! Tehát én egyértelműen Doctrine-ra szavazok és nem a sebessége miatt, de ahogy fentebb is írtam, ha számít a sebesség, kihagyom. Pl van egy formunk, ami automatikusan menti, ha kitöltött egy mezőt az illető, AJAX-szal, a háttérben. Bár symfony-s az oldal, az egészet megoldottam egy mezei, 50 soros PHP-val.
6

tapasztalat

carstepPCE · 2009. Szep. 17. (Cs), 14.41
Nem flamelni akartam/akarok, mindossze a tapasztalat beszel belolem:

viszonylag sokat teszteltem a doctrine-t es legfokeppen azon bosszankodtam mikor megneztem a trace/profile fajlokat, hogy maga a lekerdezes 1 egyseg alatt megvolt, mig a tobbi objektum meg php kod, ami az orm-t kapcsolatos, ahhoz 2 egyseg kellett.

[Szemelyen szubjektiv tapasztalat, akar ki is hagyhato :-)]:
Masik fele a dolognak, hogy mire beallitottam es telepitettem a doctrine-t, addigra egy komplett projektreszt megirtam volna. De mivel volt 1 het szabad idom, addig gondoltam kiprobalom mit tud. Elotte nem nagyon hasznaltam ilyen komplex orm-t ugyhogy 1 napot a doctrine tanulassal plusz telepitessel plus yaml tanulassal toltottem. Igazabol sokat szivtam, azzal hogy a dokumentacio es a letoltheto doctrine abszolut nem volt szinkronban egymassal. Ugyhogy buheralas lett belole, amit nagyon nem szeretek csinalni, de pozitivan alltam a dologhoz(meg). Nagyon sokat bibelodtem a yaml irasaval is, mert istennek sem akarta az igazsagot latni, rengeteget szivtam vele. Szerintem ebben a reszben nagyokat hibaztak a forditott logika hasznalataval a 'foreign key' kapcsan. Az automatikus forditasok yaml modellek segitsegevel nagyon jo dolog, csak ne kellett volna 4 oran at allitgatni, hogy mi merre milyen konyvtar, igy nem stimmel ugy nem stimmel, egy hajmereszto mutatvany volt.
[Szubjektiv resz vege]

Mindenesetre lehet nem fekszik az en logikamnak, amit a doctrine nyujt (ebben szinte biztos vagyok), es emiatt rengeteg bosszankodasom volt vele. Tovabba egy sima joinos lekerdezes mysql_query-vel elfert 3 megaba, mig doctrine-el 13 megaba, azert rendesen elgondolkoztatott, hogy ez igy tenyleg megeri e? Persze a celkornyezetben, mindossze 16 mega allt rendelkezesre egy lekerdezeshez, dehat meg egy keretrendszernek is el kellett fernie benne.

Igazabol akkor latom ertelmet a doctrine hasznalatanak, amikor nagy belso intrantetes projekt van, ahol elobb utobb valtozas fog tortenni az adatbazist illetoen. Lehet ez verziovaltas vagy akar komplett motorvaltas is. Minden mas eseteben a nativ sql lekerdezesek letrehozasa es tesztelese nalam 1 nagysagrenddel kevesebb idobe telett, mint doctrine hasznaltaval. Ehhez hozzajarul az is, hogy nekem tetszik az sql nyelv.

Programtervezesi szempontbol, sulyozni kell, hogy kinek mennyire nehez sql-eket irni, mennyire valtozik a futtato kornyezet, hanyan dolgoznak a projektben es ez alapjan merlegelni, h. segedeszkozokhoz nyuljon vagy sajat maga csinalja meg. Az applikacio tobbi reszeben en is altalaban keretrendszerekhez fordulok. Nekem eddigi tapasztalataim alapjan majdnem minden keretrendszer eseteben a leggyengebb lancszem az adatbaziskezeles volt.

Kesobb szerencsere talalkoztam masik orm-mel, amely olyan kezes volt, mint a barany es nem kellett nekem 3 oranal tobb az elsajatitasahoz, ezt hivjak ezComponent-nek(ez nem reklam akar lenni). Az itt talalhato logika nagyon kis mertekben mas, mint magaban az sql-ben talalhato, mindossze az osszehasonlito muveletek igenyelnek nemi megszokast.

-cs-
Sanyi
8

Hmm

inf · 2009. Szep. 22. (K), 21.52
Nem látom át, hogy Symfony miben nyújt többet, mint egy FrontController+Template+ORM hármas. Egyébként gondolkodtam rajta, hogy átteszem Symfonyra a projectet, mert sok jót mondtak róla, csak egyelőre annyit látok, hogy gyakorlatilag mindent szétdaraboltak külön fájlokra, semmi mást. Persze még nézegetem, az ORM viszont biztosan kelleni fog.
11

Joel

fchris82 · 2009. Szep. 25. (P), 00.16
Na, nem csak én mondom azt, hogy fontosabb a "legyen vmi gyorsan", mint hogy gyors, hibátlan és szép legyen: http://www.joelonsoftware.com/items/2009/09/23.html
13

lworm

lfaz · 2010. Nov. 19. (P), 21.46
Van egy kicsi, de hatékony ORM library PHP-hoz, lworm a neve, ha gondolod, nézd meg itt: http://code.google.com/p/lworm/
14

RedBeanPHP

gabesz666 · 2010. Nov. 20. (Szo), 00.07
Egy projektünknél most használjuk, elég könnyű használni, mindent tud: http://redbeanphp.com/
15

Propel vs Doctrine

nova76 · 2010. Nov. 20. (Szo), 12.00
Visszatérve a symfonyhoz, a legújabb propel gyorsabb mint a doctrine. Én még nem találkoztam olyan sql lekérdezéssel, amit ne lehetett volna megvalósítani Propelllel. De nagyságrendileg több idő megy el vele, mint sima sql-ben megírni. Némelyik fél napot is igénybe vesz, ami felér egy propel továbbképzéssel. Aztán van olyan lekérdezés, amit a symfony eleve rosszul generál le. Például ha egy táblát több mezővel kapcsolok egy másik táblához. Például egy raktárkészlet programban, a forgalom tábla 2 mezővel kapcsolódik össze a mértékegység táblával. Beszerzési és raktározási mértékegység. Ilyenkor a generált doSelectJoinAll metódus hibás. Ha viszont a sima doSelect-tel jelenítem meg a forgalom táblát, akkor egy 50 soros táblázat már 150 lekérdezést (forgalom + 2 mértékegység) tartalmaz. Ezt persze lehet cachelni, de az újabb meló, hiszen ez sincs benne alapból. Viszont bármennyire sok a lekérdezés, időben nem biztos hogy előrébb leszek, ha kijavítom a doSelectJoinAll metódust. Hiszen a gép ugyanaz, ha a mysql lekérdezés fut és ugyanaz, ha a PHP. Nyilván osztott rendszeren számítana, hogy kijavítom és használom, vagy nem.

A keretrendszer használata is nyilván memória igényesebb és lassabb mint nélküle, de főleg a sok legenerált kód miatt gyorsabb a fejlesztés. De a PHP eleve ilyen, ráférne nagyon egy GC. Volt olyan hogy nagy mennyiségű rekordot akartunk bevinni a formok segítségével, de sehogy se sikerült megállítani a memória szivárgást. Valahogy végül nagy nehezen sikerült belepréselni magunkat az 512 megába :-) A sebesség meg sok mindenen múlik. Ha a vevő oldalon a rendszergazda láma, akkor lehetsz bármilyen okos, ha viszont okos, akkor akár még segíthet is (pl: APC cache).

De jó tapasztalatom nincs azzal kapcsolatban hogy a Propel mysqlen kívül bármire használható lenne. Firebirden nem megy. Oracle alatt meg rengeteg a szívás. A saját magad által leírt queryk meg pont azért rosszak, mert lehet benne olyan ami a másik db-ben nincs (pl: Groupconcat, de firebirdnél nincs limit se).