Datenbankverbindungen

dg87

Erfahrenes Mitglied
Kann es denn sein dass man bei einer Web Anwendung mehrere Datenbank Typen dahinter stecken hat? Wenn ja wie geht man damit um. Ich habe bisher eine db Factory die den Typ (zb MySQL) erhalt und die jeweilige Instanz liefert.
Zb ruft man so auf:
DB::getInstance("MySQL")

So angenommen es kommt eine neue DB von MSSQL. Dann muss ich in jeder Datei den Aufruf der Factory ändern. Wie macht ihr das?
 
Du kannst das über Adapter lösen. Und wenn du weißt, dass du so oder so nur einen Datenbanktyp verwendest, dann gib doch stets bei DB::getInstance() die Instanz des Datenbankadapters aus. Wenn du in diesem dann noch die PDO verwendest, dann sollte es für die grundlegenden Abfragen keinen Änderungsbedarf geben.
 
Wieso einen Adpater, soll ich es nicht gleich über PDO machen.
Bzw wie könnte der Adpater aussehen, ich steh grad aufn schlauch?
Ich mein klar, ich hab nur einen Datenbanktyp, aber in der Praxis sollte man doch so programmierne, dass andere Typen ohne Probleme hinzugefügt werden können, ohne dass ich groß überall den Aufruf ändern soll. Deswegen mach ich das. Hatte gestern noch überlegt, eine Methode rauszukapseln, die mir immer den aktuellen DB Typ liefert (somit muss ich nur Zentral ändern, sollte der Typ sich ändern). Was mache ich aber wenn ich mehrere DB Typen im Einsatz habe (kommt das überhaupt vor?)
 
Über die Adapter-Klassen kannst du dann beispielsweise bestimme Abfragen kapseln, die bei den einzelnen SQL-Datenbanken unterschiedlich sind. Ich denke da nur daran, dass quasi jede Datenbank eine andere Abfrage für die Datenbank-/Tabellenstruktur und dann auch noch unterschiedliche Spaltentypen hat. Beispielsweise gibt es bei MySQL keinen direkten Typ für binäre Daten, PostgreSQL hingegen schon. Oder die Syntax für die Angabe des Limits und Offsets unterscheidet sich auch. Oder nicht zu vergessen, dass es Datenbanken gibt, die ein Rollback ermöglichen, andere hingegen nicht. Wenn du jetzt aber Rollbacks bei Möglichkeit verwenden willst, dann solltest du in deiner Datenbankfrage lieber vorher schauen, ob der Datenbanktyp das überhaupt kann. Wenn ja, dann kannst du die Abfragen in einem solchen Kontext abschicken, wenn nicht, dann solltest du sie entweder wie normale Abfragen behandeln oder dir was einfallen lassen, wie du ein Rollback simulieren könntest. Und was außerdem noch recht ekelhaft bei PDO ist: die Angabe der Verbindungsdaten. Ich persönlich löse das lieber über ein Array und lasse mir den Data Source Name (DNS) entsprechend zusammen bauen.
 
Wenn ich aber bei meinen Beispiel bleibe (der Instanzaufruf mit dem Datenbanktyp), dann lässt es sich bei folgenden Beispiel nicht vermeiden, Code auszubessern:
Ich bekomme einen neuen Typ meinetwegen Oracle dazu. Aber nicht alle Datenbankoperationen (die mit MYSQL laufen) müssen geändert werden. Nur ein teil der Operationen muss jetzt mit Oracle laufen.
Ich komm ja dann nicht drumrum, diese ganzen Aufrufe auszubessern, dass als Typ Oracle drinnen steht. Irgendwo muss man ja ausbessern oder kann man das geschickt anders lösen (außer PDO).


Edit:

Mir gehts darum, ich denke dass man ja irgendwo auch mal die Aufrufe anpassen muss. So oft ändert sich ja nicht der DB Typ. Ich würde halt dann einfach Oracle in der Factory hinzufügen, dass er diese als Instanz produzieren kann und im Instanzenaufruf überall 'ORACLE' reinschreiben.
Geht ja nicht anders, ich will ja nur ein paar Instanzen bzw. Verbindungen an Oracle zulassen, die von MYSQL sollen ja so bleiben.
Also müsste ich überall wo jetzt MYSQL steht aber Oracle hinsoll, den Instanzaufruf von 'MYSQL' auf 'ORACLE' ändern.
Denke in meinen Beispiel wie ich es mache derzeit (ohne PDO oder Adapter) gibts keine bessere lösung.
 
Zuletzt bearbeitet:
Ich weiß nicht, ob ich es bei dir schon mal erwähnt habe, aber mit dem ActiveRecord-Entwurfsmuster lassen sich Datenbankaufrufe ermöglichen, in welchen du gar kein SQL mehr brauchst, weil der Zusammenbau der Abfrage an die Datenbank von der Klasse übernommen wird. Eine Abfrage deinerseits könnte dann so aussehen:
PHP:
$people = Person::where('age >= ?', 18)->limit(10)->find();
 
Zuletzt bearbeitet:
Ja das hast du mir gehts aber grad nur um mein Prinzip und dem Beispiel. Nicht um Abfragen, sondern nur um den Aufruf! Klar gibt es bessere Möglichkeiten, mir gehts nur darum, dass man in meinen Fall dann immer den Code ausbessern müsste, weil es keine andere Möglichkeit gibt.

Aber egal, es gibt ja schließelich bessere möglichkeiten, die hast du gennant das ist schon ok so.

Vielen Dank für deine Hilfe
 
Wenn du genau weißt, an welchen Stellen du welche Datenbankverbindung brauchst, dann nutze in deiner Factory-Klasse das PDO und ruf es dann so auf:
PHP:
$mysql  = Database::get('mysql');
$oracle = Database::get('oracle');
$sqlite = Database::get('sqlite');
 
Zurück