php.de

Zurück   php.de > Webentwicklung > Software-Design

Software-Design Diskussionen auf Profi-Niveau: PHP Lösungen auf konzeptioneller Ebene

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 09.01.2010, 14:11  
Neuer Benutzer
 
Registriert seit: 09.01.2010
Beiträge: 22
PHP-Kenntnisse:
Fortgeschritten
bghosting befindet sich auf einem aufstrebenden Ast
Standard

Du könntest dir die Spezifikationen des JCR anschauen (Java Content Repository). Eine PHP-Umsetzung gibt es dazu im Flow3-Projekt (dem neuen Typo3 Stream).

Im Grunde macht es bei Typo3 genau das: Vereinfacht dargestellt markierst du Objekte für die Datenbank. Sie werden dann mit ihren Attributen gespeichert und können später wieder geladen werden. Das, was dabei recht interessant ist. Abfragen werden über eine allgemeine Schnittstelle abgehandelt. Das sieht dann beispielsweise so aus:
PHP-Code:
$query $repository->createQuery();
$result $query->matching($query->and(
    
$query->equals('spalte1'$wert1),
    
$query->equals('spalte2'$wert2)
    )->
execute(); 
Als Anmerkung: Das, was im klassischen Sinne eine Datenbanktabelle ist, stellt das $repositoy dar. Sprich: Das $repository weiß demnach, welche Tabelle es abfragen muss.

Just my 2 cents
bghosting ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 09.01.2010, 16:37  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 34.246
PHP-Kenntnisse:
Fortgeschritten
nikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz sein
Standard

Leg doch lieber geschlossene Domainobjekte an und programmiere ggf. DAOs für spezifische Datenbanken nach. IMHO verspielst Du sonst jede Menge DB-spezifische Optimierungen. Der kleinste gemeinsame Nenner bietet sonst zwar austauschbare Zugriffsobjekte, die dafür aber schweinelangsam sind.
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--
nikosch ist gerade online   Mit Zitat antworten
Alt 11.01.2010, 08:27  
Erfahrener Benutzer
 
Registriert seit: 30.07.2008
Beiträge: 1.129
PHP-Kenntnisse:
Fortgeschritten
xm22 sorgt für eine eindrucksvolle Atmosphärexm22 sorgt für eine eindrucksvolle Atmosphärexm22 sorgt für eine eindrucksvolle Atmosphäre
Standard

Zitat:
die dafür aber schweinelangsam sind.
Aber doch nicht bei Standardabfragen.

Mit den DAOs das ist ja in der Tat ganz hübsch, aber irgendwann kommt immer der Punkt, an dem man der entsprechenden API wieder Funktionen hinzufügen muss, weil die vorhandenen eine bstimmte Anforderung nicht erfüllen.

In meinen Augen ist ein Mix aus fixen Abfragen und dem oben gezeigten, generischen Ansatz der beste Weg.
xm22 ist offline   Mit Zitat antworten
Alt 11.01.2010, 08:29  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 34.246
PHP-Kenntnisse:
Fortgeschritten
nikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz sein
Standard

Zitat:
Aber doch nicht bei Standardabfragen.
Standardabfragen können auch schnell sehr komplex werden. Wenn man dann nicht spezielle Gegebenheiten der einzelnen Systeme nutzt, verspielt man eine Menge Potential.
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--
nikosch ist gerade online   Mit Zitat antworten
Alt 11.01.2010, 14:54  
Erfahrener Benutzer
 
Registriert seit: 21.12.2004
Beiträge: 4.651
PHP-Kenntnisse:
Fortgeschritten
mepeisen ist ein Lichtblickmepeisen ist ein Lichtblickmepeisen ist ein Lichtblickmepeisen ist ein Lichtblickmepeisen ist ein Lichtblickmepeisen ist ein Lichtblick
mepeisen eine Nachricht über ICQ schicken mepeisen eine Nachricht über Skype™ schicken
Standard

Ab einer gewissen Größe ist der DB-Optimizer überfordert. Nicht weil er nicht zu optimieren wüsste sondern weil er für die Optimierung länger bräuchte als für die potentielle Abfrage und sie deswegen unterlässt. Anders ausgedrückt: Ab einer gewissen Komplexität ist es eventuell sinnvoller, die Datenbankabfrage in einzelne Abfragen zu spalten und diese mittels Anwendungslogik zusammenzusetzen. Dann hat man gleich auch die Chance, frühzeitig Datenkonstellationen zu erkennen, wo die weiteren Abfragen nicht mehr ausgeführt werden müssen, weil beispielsweise bereits die erste Menge leer ist.
Klar ist das bei DAOs ein zweischneidiges Schwert. Aber genauso zweischneidig ist es, die komplexeste Logik durch eine Methode und einen SQL immer abdecken zu wollen.
Eine pauschale Antwort gibt es aber nicht, denn es kommt immer auf den konkreten Anwendungsfall und den Daten/Datenmengen an, ob ein DAO mit vielen atomaren Funktionen und SQLs vorteilhaft ist oder ob man eine komplexe Methode und ein komplexes SQL vorziehen sollte.
__________________
Entwickler aus Leidenschaft und ein Zahnrad in einem der größten Java-Projekte der Welt.
mepeisen ist offline   Mit Zitat antworten
Alt 12.01.2010, 17:39  
Erfahrener Benutzer
 
Benutzerbild von Dark Guardian
 
Registriert seit: 10.10.2009
Beiträge: 2.201
PHP-Kenntnisse:
Fortgeschritten
Dark Guardian ist ein sehr geschätzer MenschDark Guardian ist ein sehr geschätzer MenschDark Guardian ist ein sehr geschätzer MenschDark Guardian ist ein sehr geschätzer Mensch
Standard

Ich hab mal mit einem Klassendiagramm angefangen um etwas mehr Überblick zu bekommen.



Selbstverständlich noch lange nicht vollständig. Für Fehler im Diagramm entschuldige ich mich schon einmal im vorraus. Haben das im erstem Ausbildungsjahr nur grob behandelt und bisher hatte ich noch nicht die Muße mich weiter mit UML zu beschäftigen.

Im Prinzip soll das ganze so ablaufen:

Es wird ein DBQuery erzeugt, in diesem werden mit Hilfe der anderen Klassen die Daten für den SQL-Befehl zusammengetragen. Das DBQuery Objekt wird an ein Objekt mit dem Interface IDatabaseDriver übergeben. Der Driver hat nun die Aufgabe aus den Daten die in den Objekten stecken einen SQL-Query zu bauen der in (seinem) DBMS ausgeführt werden kann und alle angeforderten Features unterstützt.

Z.B. setz man im DBQuery Objekt $queryType auf SELECT, gibt eine Reihe von DBColumn Objekten an sowie ein DBTable Objekt. Hierraus sollte der "Datenbanktreiber", entsprechend dem Syntax des DBMS einen "SELECT DBColumn1, DBColumn2... FROM DBTable" zusammenbauen können.

So gesehen ist es die Aufgabe des Drivers die Befehle auszuführen und vom OO Format in das Datenbankformat umzuwandeln und umgekehrt. Die Anwendung soll nur mit den Objekten arbeiten müssen um Änderungen an der Datenbank vorzunehmen.

Ein anderes Beispiel wäre ein ALTER TABLE Befehl in dem eine Spalte hinzugefügt werden soll. Ich möchte nur ein DBColumn Objekt anlegen, per addColumn()-Methode eines DBTable Objektes diesem die Spalte übergeben und mehr nicht. Das DBTable Objekt erzeugt das entsprechende DBQuery Objekt, der Driver übersetzt, führt aus, und gibt ggf. Antwort ob alles geklappt hat in Form eines DBResult Objektes.

Um zu viel Overhead zu vermeiden lassen sich Objekte von DBColumn u.Ä. welche nicht alltägliche Informationen enthalten durch einen Parameter ohne diese instanzieren. Ich muss jedenfalls nicht in jedem Query wissen ob eine Spalte ein Primary Key ist oder nicht, diese Informationen aber jedes Mal bei der Instanzierung automatisch abzufragen ist denke ich zu viel des Guten.

... was haltet ihr davon, wo seht ihr Denkfehler oder schon "früh" (sollte ich das tatsächlich so umsetzen wollen) Probleme auftauchen?

Edit: Ich hab mir auch mal Doctrine angeschaut. Das ist für meine Pläne schon etwas oversized.
__________________
Möglicherweise kommt zu "Menschen lügen" auch "Menschen bauen Mist".
Dark Guardian ist offline   Mit Zitat antworten
Alt 13.01.2010, 16:01  
Erfahrener Benutzer
 
Registriert seit: 30.07.2008
Beiträge: 1.129
PHP-Kenntnisse:
Fortgeschritten
xm22 sorgt für eine eindrucksvolle Atmosphärexm22 sorgt für eine eindrucksvolle Atmosphärexm22 sorgt für eine eindrucksvolle Atmosphäre
Standard

Was ich auf Anhieb sehe, ist eine rekursive Komposition von DBRow und DBTable. So was halte ich nicht für gut, weil die sich gegenseitig bedingen.
xm22 ist offline   Mit Zitat antworten
Alt 13.01.2010, 16:11  
Erfahrener Benutzer
 
Registriert seit: 21.12.2004
Beiträge: 4.651
PHP-Kenntnisse:
Fortgeschritten
mepeisen ist ein Lichtblickmepeisen ist ein Lichtblickmepeisen ist ein Lichtblickmepeisen ist ein Lichtblickmepeisen ist ein Lichtblickmepeisen ist ein Lichtblick
mepeisen eine Nachricht über ICQ schicken mepeisen eine Nachricht über Skype™ schicken
Standard

Table zu column ist bei dir eine n:m Beziehung. In relationalen Datenbanken ist das aber immer 1:n (also die Spalte gehört immer eindeutig zur Tabelle). Gleiches gilt für deine Beziehung zwischen Tabelle und Datenbank.

Dein Aufbau von DBQuery ist etwas fragwürdig. Er ist nicht falsch und kann auch durchaus für deine Sachen ausreichen, hat jedoch einige Einschränkungen. So sind bei dir keine Subselects möglich. Wie auch immer ist das aber eh etwas schwierig abzubilden

Nur Interesse halber: Wieso kennt die Datenbank die Queries?

@xm22: Wieso ist das ein Problem? Eine Beziehung zwischen zwei Entitäten lässt sich immer in beide Richtungen abbilden. Und nichts anderes hat er gemacht. Im übrigen ist eine Komposition immer ein ausgefülltes Rechteck. Er hat eine Aggregation gemacht.
Richtig wäre zwar in der Tat, dass eine Komposition von Table zur Column gäbe und keine Aggregation, da die Table das Vaterobjekt der Column ist. Da PHP jedoch Kompositionen nicht nativ unterstützt, ist es lediglich eine Geschmackssache, wie man es in UML darstellt.
__________________
Entwickler aus Leidenschaft und ein Zahnrad in einem der größten Java-Projekte der Welt.
mepeisen ist offline   Mit Zitat antworten
Alt 14.01.2010, 14:07  
Erfahrener Benutzer
 
Benutzerbild von Dark Guardian
 
Registriert seit: 10.10.2009
Beiträge: 2.201
PHP-Kenntnisse:
Fortgeschritten
Dark Guardian ist ein sehr geschätzer MenschDark Guardian ist ein sehr geschätzer MenschDark Guardian ist ein sehr geschätzer MenschDark Guardian ist ein sehr geschätzer Mensch
Standard

Zu den Kompositionen und Aggregationen:

Mittlerweile denke ich dass das DBTable Objekt innerhalb der DBRow nicht unbedingt gebraucht wird. Mir ist jedenfalls beim Erstellen von einigen Verwendungszwecken kein Fall aufgefallen wo ich es benötigen würde.

Dem Konzept der relationalen Datenbanken anch stimmt es das die Abbildungen von DBTable zu Database 1:n wäre. Ebenso wie DBColumn zu DBTable. Bei der Erstellung des Diagramms hatte ich jedoch folgendes Muster im Kopf:

Was ist wenn ich eine komplette Tabelle in mehrere Datenbanken kopieren möchte? Dann erzeuge ich ein DBTable Objekte und lasse dieses alle Daten zu Spalten und alle Zeilen auslesen und füge dieses in ein anderes Database Objekt ein. Die Quelltabelle gehörte ja bereits zu einer Datenbank. Ich hätte nun also 2 Datenbanken, in denen ich die gleiche Tabelle besitze welche nur durch ein DBTable Objekt repräsentiert werden. In diesem Fall wäre das Database-Objekt innerhalb von DBTable jedoch nutzlos.

Dies werde ich dadurch abändern das Methode wie Database->addTable() die neu hinzugefügte Tabelle als DBTable zurückliefern, oder die als Parameter übergebene Tabelle, je nachdem ob die Tabelle welche übergeben wurde schon zu einer Datenbank gehört oder nicht.

Aus dem letzten erwähnten Punkt heraus habe ich auch Aggregationen anstatt Kompositionen gewählt. Wenn ich eine neue Tabelle anlege, erzeuge ich ein DBTable Objekt und füge dieses einer Datenbank hinzu. Die Tabelle ist zwar Teil einer Datenbank, das Objekt welches sie abbildet kann aber auch ohne eine Datenbank existieren bis es zu einer oder mehreren Datenbanken hinzugefügt wird.

Ein kleines Beispiel um das zu verdeutlichen:

PHP-Code:
//Datenbanktreiber und Datenbank erzeugen
$dbDriver = new MySQLDatabaseDriver();
$database = new Database('test_db'$driver);

//Tabelle erzeugen mit Namen 'test_table';
$table = new DBTable('test_table');

$columns  = array();
//Spalte erzeugen mit Namen 'id', vom Typ Integer, auto increment true, primary key true
$columns[] = new DBColumn('id''int'10truetrue);

//weitere spalten
$columns[] = new DBColumn('wert1''char'10);
$columns[] = new DBColumn('wert2''varchar'255);
$columns[] = new DBColumn('wert3''enum', array('0''1'));

//Spaltendefinition der Tabelle hinzufügen
$table->addColumns($columns);

//Tabelle der Datenbank hinzufügen
$database->addTable($table); 
Die Objekte können also erzeugt werden ohne das sie zu einem Vaterobjekt vorher zugeordnet werden müssen. Soweit es mir beigebracht wurde schließt dies Kompositionen aus.

Zu dem Query Objekt:

Es fehlt sowieso noch ORDER BY, GROUP BY, HAVING, USING etc. Bei den SubSelects weiss ich auch noch nicht so recht weiter.

Bei der Where-Klausel im DBWhere Objekt ist das ja relativ leicht. Als Tabellenspezifikation schon schwieriger weil ich nicht weiss wo ich den Alias unterbringen soll. Ich bin am Überlegen dem DBTable Objekt die Fähigkeit zu geben durch einen Select-Query eine Struktur annehmen zu können und nicht durch eine Anzahl von DBColumn Objekten.

So wäre folgendes Beispiel möglich:

PHP-Code:
//Tabelle erzeugen mit Namen 'test_table';
$table = new DBTable('test_table');

//Wir erzeugen den Select
$select = new DBQuery('select');
$select->setColumns(...);
$select->setTable(...);
$select->setWhere(new DBWhere(....));

//hier wird nun der Query an die Tabelle übergeben und die Tabellenstruktur wird erzeugt
$table->structureQuery($select); 
Nun könnte ich mit $table so weiter verfahren das ich diese als Tabellenobjekt in DBQuery angebe oder auch in einem DBJoin verwende. Das MySQLDatabaseDriver Objekt kann somit darauf reagieren ob die Tabelle physikalisch existiert oder durch einen Select erzeugt wurde und entsüprechend den Select in den Query integrieren anstatt eifnahc nur den Tabellennamen zu verwenden (dieser ist dann im Falle eines Selects der Alias für die Tabelle).

Bei INSERT Befehlen verhält es sich ähnlich. Anstelle eines Liste von DBColumns wird ein DBQuery, welcher den Select repräsentiert angegeben. Bei UPDATE Befehlen im DBSet Objekt genauso. Dies konnte ich im Klassendiagramm leider nicht festhalten da es in dem Programm welche sich benutze anscheinend nicht möglich ist für eione Membervariable mehrere mögliche Datentypen anzugeben.

Nun zu der Frage warum die Datenbank die Queries kennt:

Die Datenbank kennt als einziges das IDatabaseDriver Objekt. Ich weiss noch nicht ob ich die DBQuery Objekte immer durchreichen will oder ob ich sie direkt bei der Datenbank registriere. Im Falle des letzteren würde die Datenbank die Queries kennen.

Außerdem dachte ich mir das es von Vorteil sein könnte wenn die DBQueruie Objekte die intern von den Klassen genutzt werden nicht bei jeder Verwendung in den Methoden als lokale Variablen neu erzeugt werden sondern zentral registriert werden. Das Database Objekt ist hierfür warscheinlich nicht der beste Platz, aber der Vermerk ist mir erst einmal lieber als diese Option hinterher zu vergessen.
__________________
Möglicherweise kommt zu "Menschen lügen" auch "Menschen bauen Mist".
Dark Guardian ist offline   Mit Zitat antworten
Alt 14.01.2010, 14:30  
Erfahrener Benutzer
 
Registriert seit: 21.12.2004
Beiträge: 4.651
PHP-Kenntnisse:
Fortgeschritten
mepeisen ist ein Lichtblickmepeisen ist ein Lichtblickmepeisen ist ein Lichtblickmepeisen ist ein Lichtblickmepeisen ist ein Lichtblickmepeisen ist ein Lichtblick
mepeisen eine Nachricht über ICQ schicken mepeisen eine Nachricht über Skype™ schicken
Standard

Zitat:
Zitat von Dark Guardian Beitrag anzeigen
Was ist wenn ich eine komplette Tabelle in mehrere Datenbanken kopieren möchte? Dann erzeuge ich ein DBTable Objekte und lasse dieses alle Daten zu Spalten und alle Zeilen auslesen und füge dieses in ein anderes Database Objekt ein. Die Quelltabelle gehörte ja bereits zu einer Datenbank. Ich hätte nun also 2 Datenbanken, in denen ich die gleiche Tabelle besitze welche nur durch ein DBTable Objekt repräsentiert werden. In diesem Fall wäre das Database-Objekt innerhalb von DBTable jedoch nutzlos.
gleich !== selbe

Du hast trotz allem aber immer eine Kopie. Wenn du in der Kopie eine Spalte hinzufügst nachträglich, ist sie im Original nicht hinzugefügt. Wenn du eine n:m-Beziehung hast und eine Tabellenkopie so umsetzt, dass dasselbe Objekt wiederverwendet wird, stimmt das nicht mehr.

Wenn du stattdessen zwei Tabellen haben willst, die wirklich dieselben sind und mit gleichen Inhalten in zwei Datenbanken auftauchen, dann nutze beispielsweise das Proxy-Pattern. Deine Implementierung wird jedoch ungleich etwas schwieriger, weil viele Datenbanksysteme solche Proxy-Tabellen oder wie mans nennen will (also Tabellen, die zeitgleich identisch in zwei Datenbanken verfügbar sind) erst einmal nicht unterstützen. Einige wenige können das.
Eine Alternative dazu wären Views.
__________________
Entwickler aus Leidenschaft und ein Zahnrad in einem der größten Java-Projekte der Welt.
mepeisen ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
[Erledigt] Konzept für einen PHP Web Crawler Dark Guardian Software-Design 10 23.11.2009 16:31
MVC Konzept Babbsdrebbler Software-Design 6 30.10.2009 08:13
Konzept für Bowsergame Wiillli Beitragsarchiv 1 21.10.2009 15:18
Grafiker gesucht - BG mit fertigem Konzept und Programmierern thezug Beitragsarchiv 0 28.08.2009 15:33
[Erledigt] Konzept Newssammler larsemann PHP-Fortgeschrittene 8 03.03.2009 17:20
Objekte und Sessions boehseronkel PHP Tipps 2008 17 07.10.2008 10:34
kleines DB Konzept Tomte Datenbanken 21 23.08.2008 10:22
dynamische Webseiten - Sitemap: Konzept dh1sbg PHP-Fortgeschrittene 4 14.08.2007 13:23
Möchtegern Browsergame Marian Trash 57 06.08.2006 03:32
Konzept Frage (2), DB Package greg PHP-Fortgeschrittene 0 15.07.2006 14:19
Überdenken des Konzept: Eigene Bildergalerien für User pixelcut PHP-Fortgeschrittene 3 16.01.2006 18:40
Konzept GFX-Community PHP Tipps 2005-2 2 22.08.2005 10:22
[Erledigt] Selectanfrage an eine Datenbank,aber aus mehreren Tabellen Datenbanken 2 26.10.2004 07:23
[Erledigt] Probleme beim Umsetzen von alten Konzept in Smarty PHP-Fortgeschrittene 4 13.09.2004 01:43
[Erledigt] Multigaming Warscript Konzept PHP-Fortgeschrittene 6 30.08.2004 20:56

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
flow3 createquery, relationale datenbank relation aggregation komposition, konzept datenbank abfragen, flow3 \query->matching\, flow3 createquery matching, austauschbare datenbankformate, grafik datenbankabstraktion, dao flow3, jcr datenbankabfragen, komposition in datenbank abbilden, php datenbankabstraktion erstellen, php datenbankabstraktion dao, php und dem klassischen treiber ausgeführt?, konzept datenbank enumeration, openoffice base tabellenkopie, typo3 tabellen relation konzeption, datenbankabstraktion klassen, datenbankabstraktion, was ist datenbankabstraktion, komposition datenbank rekursion

Alle Zeitangaben in WEZ +1. Es ist jetzt 14:33 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum