Welche Datenbankklasse?
jörg foltro
- php
0 mario1 dedlfix0 Jörg foltro2 dedlfix0 Jörg foltro0 dedlfix
Hallo Forumgemeinde,
ich stehe hier grad vor der Wahl einer Datenbankklasse.
Eine eigene zu schreiben, davon bin ich längst abgewichen, da ich mich somit auf MySql begrenzen würde, da ich nur hier annähernd Ahnung habe. Da bieten fertige Klassen mir einfach die Möglichkeit, den Datenbankserver "unterm Ar***" auszutauschen und ich brauche an meinen PHP-Skripten nichts ändern.
Jetzt frage ich mich im Wald dieser ganzen Datenbankklassen aber, welche ich verwenden sollte:
PEAR:DB
PEAR:MDB2
AODb
POD
mysqli
Bei POD bin ich mir nicht sicher, inwiefern ich bei Kunden davon ausgehen kann, dass ihre Server dies zur Verügung stellen.
Gruß
Hallo,
Du solltest definitiv auf PDO und Prepared Statments (SELECT * WHERE x=?) setzen. PDO ist offiziell erst ab PHP 5.0 dabei; aber es gibt eine Fallback-/Emulation für ältere PHP-Versionen:
http://www.xpdo.org/api/xpdo-pdo/_pdo.class.php.html
MDB2 oder ADODB werden erst wirklich dann interessant, wenn du komplexe Tabellendefinitionen zur Laufzeit erstellen willst. (Binary BLOBs und einige Funktionen haben z.B. in MySQL und Postgres unterschiedliche Namen.)
G!
mario
Hallo,
danke erstmal für deine Antwort.
Das mit PDO klingt gut. Prepared Statements wollte ich auf jedenfall nutzen.
Da es eine Fallback-Lösung gibt gefällt mir das auch echt gut.
Tabellendefinitionen?
Inwiefern komplex?
Mit den unterschiedlichen Namen habe ich bei PDO aber dann schon Probleme? Ich meine PDO kann nur Statements umsetzten, die die DB-Systeme unterstützen, oder?
Sorry damit kenne ich mich nicht so gut aus. Ich kenne mich mit MySql etwas aus und bin dran es zu lernen, weiß aber, dass ich möglichst DB-System-unabhängig sein möchte, deswegen suche ich nach so einer Lösung.
Gruß
echo $begrüßung;
ich stehe hier grad vor der Wahl einer Datenbankklasse.
[...] Da bieten fertige Klassen mir einfach die Möglichkeit, den Datenbankserver "unterm Ar***" auszutauschen und ich brauche an meinen PHP-Skripten nichts ändern.
Das ist eine Illusion, die sich nur dann nicht in Enttäuschung auflöst, wenn die verwendeten SQL-Statements in der Form auch im neuen System laufen. Damit schränkt man sich teilweise erheblich in der verwendbaren Funktionalität ein.
Welche Gründe für einen Wechsel kann es denn geben?
Ein Wechsel ist nicht eben mal schnell durch Austausch der Verbindungsdaten zu erreichen. Danach sollte ein umfassender Test stattfinden, der aufzeigt, dass alles bzw. das was nicht läuft. Oder die Anwendung muss so umgeschrieben werden, dass die neuen Leistungsmerkmale genutzt werden können.
Jetzt frage ich mich im Wald dieser ganzen Datenbankklassen aber, welche ich verwenden sollte:
Das ist eine Entscheidung, die du selbst treffen musst, denn nur du bist derjenige, der deine Anforderungen kennt. Ich kann nur empfehlen, zwischen Datenbank(abstraktionsschicht) und Anwendung noch eine Datenschicht einzuziehen. Diese stellt der Anwendung die Daten über definierte Schnittstellen zur Verfügung. Zum DBMS hin setzt sie die Anforderderungen in SQL-Statements um. Wenn wirklich mal das DBMS getauscht werden soll, muss nur diese Datenschicht berücksichtigt werden. Man kann sogar so weit gehen, nach "unten" hin ein anderes Speichermedium anzubinden, ohne dass die Anwendung davon Wind bekommt und dort Änderungen notwendig sind. Auch kann man diese Datenschicht während der Entwicklung Dummydaten liefern lassen, und die Implementation erst später ausführen.
Empfehlenswert ist auch, wenn du dir mal das MVC-Architekturmuster anschaust.
echo "$verabschiedung $name";
Hallo,
vielen Dank für deine Antwort. So lamgsam erkenne ich enige Vorteile einer bestimmten Lösung und komme hinter die Gedanken.
Also ich denke das sinnvollste ist wirklich eine Datenabstraktion und eine Datenbankabstraktion (POD) zu haben.
Die oberste Schicht greift dann auf die Datenabstraktion zu und diese holt die Daten, in dem Fall da MySql mit der POD-Klasse.
Nun stellen sich mir nur für die konkrete Umsetzung paar Fragen:
Ist es sinnvoll die Datenabstraktion abstract zu halten, sprich ohne Instanz und wenn ich z.B. alle User brauche, die Daten per Datenabstraktion::Users() zu holen? Oder gibt es konkrete Erfordernisse einer Instanz der Datenabstraktion?
Werden in der Datenabstraktion jegliche Datenbedürfnisse, die konkret auftauchen in eine Methode gefasst oder beschränke ich mich auf bestimmte Routinen; sprich habe ich eine Methode HoleAlle(), die mir dann aus einer übergebenen "Tabelle" alle Einträge holt oder habe ich eine Methode HoleAlleUser() und HoleAlleProdukte()?
Eigentlich finde ich ersteres sinnvoller, jedoch finde ich keinen gemeinsamen sinnvollen Nenner, um Abfragen auf so eine Form zu bringen ...
Sprich wie soll ich sonst diese Abfragen verarbeiten, die einen Join erfordern? Ich würde dann einfach in der Datenabstraktion eine Methode schreiben, die nur heißt HoleDatenDieLeftJoinErfordern()?
Vielleicht versteht jemand mein Denkproblem.
Gruß
echo $begrüßung;
Also ich denke das sinnvollste ist wirklich eine Datenabstraktion und eine Datenbankabstraktion (POD) zu haben.
PDO meinst du wahrscheinlich, nicht POD.
Die oberste Schicht greift dann auf die Datenabstraktion zu und diese holt die Daten, in dem Fall da MySql mit der POD-Klasse.
Prüfe, ob dir der Funktionsumfang von PDO ausreicht, und ob die Anwendungsdetails sich mit deinen Anforderungen decken. PDO muss Kompromisse machen, damit es mehrere unterschiedliche DBMS unter einer (doch nicht ganz so) einheitlichen Oberfläche abfragen kann.
Nun stellen sich mir nur für die konkrete Umsetzung paar Fragen:
- Ist es sinnvoll die Datenabstraktion abstract zu halten, sprich ohne Instanz und wenn ich z.B. alle User brauche, die Daten per Datenabstraktion::Users() zu holen?
Im Sinne der OOP musst du schon konkret werden. Statisch vs. Instanz ist auch was anderes als abstrakt vs. konkret.
Oder gibt es konkrete Erfordernisse einer Instanz der Datenabstraktion?
Das wirst du bei der Implementierung sehen. Ist es sinnvoll, wenn sich die Anwendung erst ein Objekt erstellen (oder z.B. per Singleton irgendwo holen) muss, damit es an Daten kommt, oder reicht eine Funktion bzw. statische Methode. Vielleicht möchtest du ja Datenobjekte, die sich selbst beim Initialisieren mit den Werten aus dem DBMS bestücken und diese wieder wegschreiben können.
- Werden in der Datenabstraktion jegliche Datenbedürfnisse, die konkret auftauchen in eine Methode gefasst oder beschränke ich mich auf bestimmte Routinen; sprich habe ich eine Methode HoleAlle(), die mir dann aus einer übergebenen "Tabelle" alle Einträge holt oder habe ich eine Methode HoleAlleUser() und HoleAlleProdukte()?
Du wist sicher die grundlegenden Anforderungen von RUDI (eigentlich ja CRUD, aber RUDI gefällt mir besser) mit allgemeine Statements zusammenbauenden Funktionen erledigen können. Darüber hinaus wird es spezielle Anforderungen geben, bei der komplexe Statements verwendet werden müssen. Das fängt schon da an, wenn Funktionen eingebaut werden müssen, bei denen sich nicht aus einer festen Regel herleiten lässt, wann sie anzuwenden sind.
Eigentlich finde ich ersteres sinnvoller, jedoch finde ich keinen gemeinsamen sinnvollen Nenner, um Abfragen auf so eine Form zu bringen ...
Sprich wie soll ich sonst diese Abfragen verarbeiten, die einen Join erfordern? Ich würde dann einfach in der Datenabstraktion eine Methode schreiben, die nur heißt HoleDatenDieLeftJoinErfordern()?
Aus Sicht der Anwendung ist es unerheblich, ob die Datenbeschaffung ein einfaches oder komplexes Statement erfordert. Das sollte sich auch nicht im Namen der Funktion niederschlagen, denn das Statement kann ja unabhängig von der Anwendung später mal so optimiert werden, dass der Name nicht mehr passt. Der Name sollte sich eher am Inhalt oder der Aufgabenstellung orientieren und dabei Implementierungsdetails verbergen, denn gerade letztere will man ja ohne Beeinflussung der Anwendung änderbar halten.
Joins gehören ebenso wie alle nicht-trivialen RUDI-Statements zu den Spezialfällen, bei denen einige der vorhandenen Datenabstraktionen anfangen, Kopfstände zu machen, damit sie diese Fälle mit generischen Lösungen erschlagen können, so dass der Anwendungsprogrammierer möglichst gar nicht mit SQL in Berührung kommt, und man dann scheitert, weil man garantiert irgendwann irgendeinen Spezialfall erwischt, der damit nicht geht. Deswegen bevorzuge ich eine Mischung aus RUDImentären und komplett selbst implementierbaren Funktionen, wobei natürlich auch Lösungen zwischen den beiden Extremen für wiederkehrende Spezialfälle möglich sind. Alternativ kann man natürlich auch darüber nachdenken, Funktionalität des DBMS zu nutzen, wie Views und Stored Procedures.
Zend_Db_Table aus dem Zend Framework diene mir mal als nur ein Beispiel für solche Kopfstände in Abstraktionen. Das erste Example unter Inserting Rows to a Table zeigt einfach(e) hinzuzufügende Daten. Beim zweiten Example muss man sich ein Zend_Db_Expr-Objekt erstellen, damit die Funktion CURDATE() als solche und nicht ihr Name als String-Wert im Statement landet. Wenn ich die Entwicklung richtig mitverfolgt habe, war Zend_Db_Table am Anfang nur RUDImentär, und die Zend_Db_Expr-Lösung erst nachträglich auf Anwenderwunsch "angebaut" worden.
Joins baut man sich mit Hilfe von Relationships zusammen. Dies ist erst der Aufwand, damit ein Mechanismus um ein Statement generieren kann. Ich kann mir gut vorstellen, beim händischen Zusammenschreiben nicht langsamer zu sein, und dann ist das Statement schon fertig und muss nicht erst noch zur Laufzeit ausformuliert werden.
Die Anfangseuphorie über Django (für Python) legte sich bei mir ebenso schnell wieder, als ich die Autobahn (0815-Dinge hat man mit hoher Geschwindigkeit erledigt) verlassen musste und dann auf ähnliche Weise im Wald stand. Wie ich grade sehe, hat man die Möglichkeit eigene SQL-Statements direkt einzubinden nun auch hinzugefügt/dokumentiert[1] [2], doch zu spät, ich hab mir schon meine eigene Lösung entwickelt.
Vielleicht versteht jemand mein Denkproblem.
Du musst nicht gerade eine multiple Persönlichkeit werden, aber es hilft doch gelegentlich, wenn man mal Probleme loslassen kann um sie aus einem anderen Blickwinkel neu betrachten zu können. Dabei kann man ruhig mal egoistisch sein und nur für die Belange des jeweiligen Standpunkts die jeweils beste Lösung formulieren ohne Rücksicht auf die anderen Beteiligten. Anschließend macht man das mit den anderen Standpunkten und versucht zum Schluss die Anforderungen des einen mit den Möglichkeiten des anderen unter einen Hut zu bringen.
echo "$verabschiedung $name";
Hallo,
vielen Dank noch einmal. Echt klasse deine Ausführungen.
Langsam spinnen sich meine eigenen Gedanken ;-)
Ich werde einfach noch ein wenige mich umschauen und umlesen.
Immerhin hat sich die Suche von einer anscheinen "ultimativen" Datenbankklasse geändert.
Die Datenabstraktion werde ich mir nun selber schreiben.
Wobei eine Datenbankabstraktion schon prsktisch für mich wäre vorallem prepared-Statements ... da muss ich mich nur mal mit den Komproissen von PDO auseinandersetzen.
Gruß
echo $begrüßung;
Wobei eine Datenbankabstraktion schon prsktisch für mich wäre vorallem prepared-Statements ... da muss ich mich nur mal mit den Komproissen von PDO auseinandersetzen.
Das ist zum Beispiel einer der Kompromisse. Wenn ich richtig beobachtet habe, werden Prepared Statements für MySQL nur simuliert. Dafür ist das PS-Handling unter PDO einfacher als unter mysqli, besonders wenn eine variable Anzahl Parameter berücksichtigt werden soll. Aber dafür gibt es einen Workaround: </archiv/2008/2/t167140/#m1090087>
echo "$verabschiedung $name";