Toon posts:

[PHP] Database abstractie

Pagina: 1
Acties:
  • 178 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Al enige tijd denk ik na over een framework wat ik wil gaan schrijven. Dit framework wil ik het liefst dusdanig generiek maken dat het op ieder systeem werkt (voor zover mogelijk).

Als onderdeel van dit framework zou ik graag gebruik maken van een database abstractie laag. Deze laag zou dusdanig abstract moeten zijn dat verschillende databases generieke data kunnen opslaan. Hierbij valt te denken aan bijvoorbeeld de datatypen van Metabase welke zijn gemerged met Pear::DB tot MDB2 van Pear (datatypen).

Daarnaast biedt MDB2 ook de mogelijkheid om de data op een OO-stijl te querien in plaats van de normale SQL queries. Ook dit concept had ik reeds eerder in gedachten. Hieronder een (niet MDB2) voorbeeld van de OO-stijl.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  // Get an insert statement
  $stmt = $db->getInsertStmt();

  // Set the name of the table
  $stmt->table('tableName');

  // Add a boolean column
  $stmt->intColumn('columnName', 'columnValue');

  // Add an integer column
  $stmt->boolColumn('deleted', true);

  // Execute the query
  $stmt->execute();


Graag zou ik een open discussie willen starten over het gebruik van beide ideeën. Hierbij denk ik zelf aan:
  • zijn er mensen die gebruik maken (of gemaakt hebben) van MDB2 (zo ja, wat zijn je bevindingen);
  • hoe staan mensen tegenover het gebruik van generieke datatypen;
  • het gebruik van OO-stijl queries i.p.v. SQL;
  • performance problemen (hoe groot kan het verschil zijn / mag het verschil worden);
  • andere voor- en/of nadelen.

  • whoami
  • Registratie: December 2000
  • Laatst online: 22:55
het gebruik van OO-stijl queries i.p.v. SQL;
:? Wat bedoel je hiermee ? Als je een RDBMS wilt gaan querien, zal je toch SQL nodig hebben.

Soms vind ik eigenlijk dat mensen een beetje te ver doordraven. Ik bedoel: wat is het nut om zo te gaan werken zoals in je code-voorbeeld ? IMHO maak je het er echt niet duidelijker op; een SQL statement vind ik vele malen duidelijker.

Is het niet beter om, indien je een groot project hebt, gewoon geen rekening te houden met dingen die niet nodig zijn ?
Je kan je er wel op voorzien, maar is het dan gewoon niet beter om voor iedere DB die je wilt gaan ondersteunen een aparte data-laag te schrijven, die geoptimaliseerd is voor die bepaalde DB ?
Als je het een beetje slim aanpakt, hoef je dan ook helemaal niets meer in je presentatie/logic laag gaan wijzigen.

Wat is het voordeel van jouw manier van aanpak? Ik zie enkel nadelen: trager, imho onduiderlijker, en minder flexibel, en meer werk.

[ Voor 6% gewijzigd door whoami op 22-09-2006 11:17 ]

https://fgheysels.github.io/


  • BCC
  • Registratie: Juli 2000
  • Laatst online: 07:42

BCC

Er zijn NOGAL wat bestaande frameworks die dit doen. ADODB Active Records, Ruby On Rails, Hibernate (Java), etcetera. Ik denk dat je beter een bestaand iets kan pakken dan het wiel opnieuw gaan uitvinden.

Daarnaast krijg je ALTIJD performance problemen bij dit soort oplossingen, maar meestal is daar wel goed omheen te werken dmv custom queries.. of een dikkere database server :)

[ Voor 30% gewijzigd door BCC op 22-09-2006 11:24 ]

Na betaling van een licentievergoeding van €1.000 verkrijgen bedrijven het recht om deze post te gebruiken voor het trainen van artificiële intelligentiesystemen.


Verwijderd

Topicstarter
whoami schreef op vrijdag 22 september 2006 @ 11:16:
...

:? Wat bedoel je hiermee ? Als je een RDBMS wilt gaan querien, zal je toch SQL nodig hebben.
In plaats van SQL verschillende statement objecten aanbieden die onafhankelijk zijn van het onderliggende RDBMS. De bovenliggende lagen kunnen gebruik maken van van deze objecten om zo de database te accessen. De objecten zelf genereren onder water de juiste SQL om vervolgens de database te benaderen.
whoami schreef op vrijdag 22 september 2006 @ 11:16:
...
Wat is het voordeel van jouw manier van aanpak? Ik zie enkel nadelen: trager, imho onduiderlijker, en minder flexibel, en meer werk.
Je hebt gelijk dat het trager is. Onduidelijker kan aan mij liggen :), het ligt er ook aan wat je gewend bent. Je kunt je database niet meer tweaken voor een specifieke RDBMS, in zoverre ben je minder flexibel. Het wordt wel weer eenvoudiger om data tussen verschillende database uit te wisselen. Meer werk is natuurlijk ook maar de vraag. Het ondersteunen van een nieuwe database is eenvoudiger wanneer er veel software gebruik maakt van de onderliggende abstractie laag. Misschien kan het op de langere termijn wel werk besparen.

  • BCC
  • Registratie: Juli 2000
  • Laatst online: 07:42

BCC

whoami schreef op vrijdag 22 september 2006 @ 11:16:

Soms vind ik eigenlijk dat mensen een beetje te ver doordraven. Ik bedoel: wat is het nut om zo te gaan werken zoals in je code-voorbeeld ? IMHO maak je het er echt niet duidelijker op; een SQL statement vind ik vele malen duidelijker.
Ik merk zelf dat zelfs bij simpele websites, het vooral de implementatie snelheid verhoogd. Een simepele variant (zoals Active Records) zorgt er al rap voor dat je al je ellende van parameter verificatie etc bij het verwerken van posts kwijt bent.

Na betaling van een licentievergoeding van €1.000 verkrijgen bedrijven het recht om deze post te gebruiken voor het trainen van artificiële intelligentiesystemen.


  • whoami
  • Registratie: December 2000
  • Laatst online: 22:55
Zoals BCC al zegt: er bestaan al genoeg dergelijke frameworks (O/R mappers) die het werk heel wat beter zullen doen. Ik speel zelf de laatste tijd wat met NHibernate, en die doet dat redelijk goed, op een paar minpunten na.

Echter, bij het ontwikkelen van een project hou ik niet van de woorden 'de investering / werk dat we nu doen kan misschien werk besparen'.
Tja, het werk dat je dan geinvesteerd hebt, bespaar je dan... Dan denk ik: neem een reeds bestaande oplossing.
In plaats van SQL verschillende statement objecten aanbieden die onafhankelijk zijn van het onderliggende RDBMS. De bovenliggende lagen kunnen gebruik maken van van deze objecten om zo de database te accessen. De objecten zelf genereren onder water de juiste SQL om vervolgens de database te benaderen.
Aha, jouw vraag was gewoon raar geformuleerd. Die objecten maken ook gebruik van SQL, dus zou je het beter anders verwoorden.

Ik ben zelf ook een tijd geleden lange tijd bezig geweest met het zoeken naar een 'silver bullet'. Echter, een dergelijk framework zelf bouwen is goed te doen zolang je enkel simpele queries ondersteunt. Eens het ingewikkelder wordt, dan denk ik dat je gauw zult inzien dat je het werk ws onderschat hebt. (Joins, inheritance, etc... )

https://fgheysels.github.io/


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 09-12-2025
Ik heb zelf een framework geschreven voor het querien van de DB. Ik gebruik idd. een OO stijl. Ik heb daarbij de verschillende concepten geabstraheerd in de vorm van objecten. Enkele voorbeelden van classes:

DatabaseAdapter - Een implementatie van een database, welke gelijk een abstract factory is voor andere objecten.
SelectQuery - Een SELECT query. Zo heb ik voor andere type queries ook objecten.
Selection - De selectie voor het selecteren, oftewel de WHERE clause.
ResultSet - Het resultaat van een select query.
Record - Een record uit de ResultSet.

Mijn ervaring is dat je met een goed framework zo'n 80% van de queries DB onafhankelijk kunt maken. Soms wil je echter iets doen wat je gekozen DB alleen kan, dan komt het toch vaak aan op handmatig SQL queries schrijven. Vanuit je framework moet je daar ook zeker de mogelijkheid voor leveren.

Ik heb ook nog enkele hulp classes geschreven waarmee je veel voorkomende queries in 1 regel kunt schrijven. Scheelt je veel tijd en moet je zeker doen.

Ik heb zelf geen last van performance problemen. Direct SQL schrijven is natuurlijk iets sneller (in het uitvoeren, niet in schrijven), maar ik heb zelf geen problemen kwa performance ondervonden, dus ik blijf zeker zo werken.

Noushka's Magnificent Dream | Unity


Verwijderd

Topicstarter
whoami schreef op vrijdag 22 september 2006 @ 11:46:
Aha, jouw vraag was gewoon raar geformuleerd. Die objecten maken ook gebruik van SQL, dus zou je het beter anders verwoorden.
Excuses hiervoor :).
whoami schreef op vrijdag 22 september 2006 @ 11:46:
Ik ben zelf ook een tijd geleden lange tijd bezig geweest met het zoeken naar een 'silver bullet'. Echter, een dergelijk framework zelf bouwen is goed te doen zolang je enkel simpele queries ondersteunt. Eens het ingewikkelder wordt, dan denk ik dat je gauw zult inzien dat je het werk ws onderschat hebt. (Joins, inheritance, etc... )
Ik bezef me heel goed dat het enorm veel werk is wil je moeilijkere queries ondersteunen en dat is ook een van de redenen om dit topic te openen en hierover eens te discusiëren.

Ik ben het met BCC eens dat het de implementatiesnelheid kan verhogen en ik denk dat het de kans op fouten kan verkleinen. Daarnaast is het volgens mij eenvoudig om zo bijvoorbeeld ook SQL-injection te voorkomen. Dus ik zie wel wat voordelen.

Het zelf schrijven van deze software of een reeds bestaand pakket gebruiken maakt me nog niet zoveel uit. Het gaat me hier meer om de gedachten van de concepten.

[ Voor 7% gewijzigd door Verwijderd op 22-09-2006 12:04 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 22:55
Mja, ik denk gewoon dat, indien er een framework bestaat die aan de meeste van jouw eisen voldoet, je beter dat kunt nemen ipv zelf een te gaan ontwikkelen. :)
BCC:
Ik merk zelf dat zelfs bij simpele websites, het vooral de implementatie snelheid verhoogd
Eens je een goed framework hebt, inderdaad. Echter, het zelf implementeren van zo'n FW neemt heel wat tijd in beslag...

Ikzelf hou me de laatste tijd nogal bezig met Domain Driven Design. Ook voor die projecten gebruik ik een O/R mapper (nhibernate), dus ik zeg zeker niet dat het een slecht idee is om een dergelijke tool te gaan gebruiken.
Echter, indien ik geen bestaande tool zou gebruiken, dan zou ik niet zo snel zelf iets gaan maken denk ik. Misschien wel een tool die ik kan gebruiken voor het uitvoeren van queries, en het creeëren van de juiste bestaande data-access classes (heb ik een tijd geleden gedaan :P ).
Echter, in m'n Repositories (de classes die je eigenlijk als een collectie van Business Objects kan benaderen), zou ik dan gewoon een bepaalde gateway accessen, en die gateway bevat dan gewoon de native SQL voor de DB die ondersteunt wordt.

Bv: Je hebt een class CustomerRepository, die Customers kan laden, saven, etc.... Deze class zou dan de juiste CustomerGateway gebruiken (die een bepaalde interface implementeert), en die specifieke gateway bevat dan bv de queries die nodig zijn voor een SQL Server, Oracle, MySql DB.

https://fgheysels.github.io/


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 09-12-2025
Maar dan kan het toch ook handig zijn om een DB abstractie laag te gebruiken. Je kunt dan een abstracte Gateway maken welke queries uitvoert die door de DB abstractie laag ondersteund worden. Exotische queries kun je dan per DB apart implementeren. Of werk je toch liever niet zo?

Noushka's Magnificent Dream | Unity


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Verwijderd schreef op vrijdag 22 september 2006 @ 11:12:
• zijn er mensen die gebruik maken (of gemaakt hebben) van MDB2 (zo ja, wat zijn je bevindingen);
Nee maar wel van Creole. Omdat Propel (de O/R mapper die ik gebruik) die gebruikt. Creole schijnt betere metadata (generieke datatypen) support te hebben. In de nieuwste versie van Propel gaan ze alleen overstappen op PDO. Waarom is dat geen optie voor jou? Lijkt me een stuk sneller omdat het een extensie is ipv PHP code.
• hoe staan mensen tegenover het gebruik van generieke datatypen;
Bedoel je dat je een metadata laag gebruikt om zoveel mogelijk RDBMS goed te kunnen ondersteunen? Anders begrijp ik je vraag niet.
• het gebruik van OO-stijl queries i.p.v. SQL;
In Propel gebruik je daarvoor Criteria. Best mooi, maar als je complexe queries wilt uitvoeren is SQL veel handiger. Maarja dan kun je weer niet abstraheren.
• performance problemen (hoe groot kan het verschil zijn / mag het verschil worden);
Ik vind de performance van Propel behoorlijk matig. Ik heb laatst eens naar het CodeIgigniter framework gekeken, welke ook database abstractie heeft maar geen O/R mapper, en dat is zoveel sneller!

Verwijderd

Topicstarter
Bedoel je dat je een metadata laag gebruikt om zoveel mogelijk RDBMS goed te kunnen ondersteunen? Anders begrijp ik je vraag niet.
Ja, dat bedoel ik :).
Nee maar wel van Creole. Omdat Propel (de O/R mapper die ik gebruik) die gebruikt. Creole schijnt betere metadata (generieke datatypen) support te hebben. In de nieuwste versie van Propel gaan ze alleen overstappen op PDO. Waarom is dat geen optie voor jou? Lijkt me een stuk sneller omdat het een extensie is ipv PHP code.
Het gaat hier om database abstractie, niet de access abstractie (wat PDO doet):
PHP:
PDO provides a data-access abstraction layer, which means that, regardless of which database you're using, you use the same functions to issue queries and fetch data. PDO does not provide a database abstraction; it doesn't rewrite SQL or emulate missing features. You should use a full-blown abstraction layer if you need that facility.
PDO biedt dus geen abstractie zoals ik het hierboven heb beschreven en is een subset van het geheel wat ik graag zou willen hebben.
Er vind dan dus ook abstractie plaats op de volgende twee punten:
  • De datatypen zijn abstract. Wil je booleans ondersteunen dan moeten ze in de RDBMS worden opgeslaan. Sommige RDBMS-en ondersteunen booleans, bij andere zul je die moeten converteren naar bijvoorbeeld een integer.
  • SQL heeft vele dialecten. Het bekendste voorbeeld is een limit/offset/etc. Hierin valt ook een abstractie te maken waardoor iedere database op dezelfde manier te benaderen valt (de uitgevoerde SQL query kan per database verschillen).

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Oh ok. Nou dan zou ik ter inspiratie eens naar Creole gaan kijken:
We would have loved to use existing technology rather than spawn a new project, but quite simply none of the other projects have the features Propel needs.

Mostly importantly, Propel needs a datatype abstraction system -- so that generic types can be mapped to native database types. Propel needed a richer set of types than the very basic selection offered by MDB/Metabase or ADOdb, which offer a mapping of PHP types (there aren't many of those) to SQL types.

Relatedly, Propel needed a system that was able to properly prepare different types of data (especially date/time columns, BOOLEAN, BLOB) for the specific RDBMS. Creole handles native PHP dates (unix timestamp) and puts them in the right format for the target database.

  • BCC
  • Registratie: Juli 2000
  • Laatst online: 07:42

BCC

Propel is trouwens ook heel vet :)

Na betaling van een licentievergoeding van €1.000 verkrijgen bedrijven het recht om deze post te gebruiken voor het trainen van artificiële intelligentiesystemen.


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
BCC schreef op vrijdag 22 september 2006 @ 16:46:
Propel is trouwens ook heel vet :)
Ja letterlijk en figuurlijk ;).

  • Brakkie
  • Registratie: Maart 2001
  • Niet online

Brakkie

blaat

Ik ben sinds kort aan de slag gegaan met doctrine. Dit is een data persistence en ORM tool. PHP 5.1 is vereist.

Ik ben er zelf dus pas net mee bezig maar het is erg veelbelovend en uitgebreid als je het mij vraagt.

Hieronder een deel van de feature list.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
    *  Multiple databases
    * Runtime configuration (no XML needed!)
    * Database abstraction with PDO + Doctrine session drivers
    * Database views
    * Column aggregation inheritance as well as class table inheritance
    * Nested transactions
    * UnitOfWork pattern (flexible session flushing)
    * EventListeners
    * Validators
    * Transactional errorStack population with validators
    * Query caching
    * Pessimistic offline locking
    * Transactional query optimization (gathering of DELETE statements)
    * State-wise records and sessions
    * Foreign key relations as well as association table relations
    * Tree structures
    * Association table self-referencing
    * Full data type abstraction
    * Relation aliases
    * PHP Array / Object data types for columns (automatic serialization/unserialization)
    * Enum data type emulation for all databases
    * OO-style query API for both DQL and raw SQL
    * DQL (Doctrine Query Language)
    * LIMIT / OFFSET support
    * Sequence / autoincrement emulation
    * Object population trhough rawsql
    * Proxy fetching
    * Lazy property fetching
    * Composite, Natural and autoincremented identifiers
    * Database query profiling
    * Automatic table creation

[ Voor 4% gewijzigd door Brakkie op 23-09-2006 13:11 ]

Systeem | Strava


Verwijderd

Topicstarter
Zowel Creole als Doctrine zien er interessant uit en ik ga ze zeker nog eens goed bekijken.

Overigens vind ik het schrijven van een eigen abstractielaag steeds interessanter worden. Ik heb me nu redelijk ingelezen en ik kom steeds meer zaken tegen die me verbazen.

Een voorbeeld:

Neem de volgende tabel (leden):
naamleeftijd
Jan26
KeesNULL
Piet63

Voer daar de volgende query op uit in verschillende databases:
SQL:
1
SELECT naam, leeftijd FROM leden ORDER BY leeftijd

MySQLPostgreSQL

naamleeftijd
Jan26
Piet63
KeesNULL


naamleeftijd
KeesNULL
Jan26
Piet63

Het resultaat verbaast me enigzins en persoonlijk vind ik het een zwakte van SQL aangezien de standaard daar geen uitsluitsel over geeft.
Pagina: 1