Montag, 22. Juli 2013

Datenbankentwurf ist nicht Datenbankentwurf

Ein guter Datenbankentwurf ist bereits sehr viel wert.
Aber es gibt da auch noch sehr viel mehr zu beachten.

Man muss auch die Weiterentwicklung eines Systems im Auge behalten.


  •  So viel benötigte Daten wie möglich auf einem Schlag via Mysql holen !

Mangels Wissen und Könnens werden benötigte Daten zu häufig z.B. mittels PHP aus den Abfrageergebnissen gebildet und sogar  erneute Abfragen zwischendurch gestartet.

Dabei haben alle DB Systeme eine sehr umfangreiche Sammlung von Funktionen und Möglichkeiten die man nutzen kann.

Ganz einfaches Beispiel aus der Praxis entnommen:

SELECT  content_id FROM cms_content WHERE 1 ORDER BY hierarchy;

Result:

+------------+
| content_id |
+------------+
|         15 |
|         34 |
|         36 |
|         37 |
|         29 |
|         30 |
|         46 |
|         45 |
|         38 |
|         47 |
|         19 |
|         49 |
|         13 |
|         22 |
|         16 |
|         18 |
|         44 |
|         55 |
|         54 |
|         51 |
|         52 |
|         56 |
|         24 |
|         20 |
|         39 |
|         40 |
|         41 |
|         42 |
|         43 |
|         50 |
|         25 |
|         26 |
|         28 |
+------------+
33 rows in set (0,00 sec)

Dann wird das Ergebnis in einer Schleife ergänzt und durchnummeriert von 0 bis x für irgendwelche Zwecke.

Der Name der Variable ist index und der wird auch so im weiteren Verlauf genutzt.

Wir haben hier drei Probleme 
  • Das benötigte RAM hierfür wird mehr als verdoppelt, da das DB Ergebnis kopiert wird
  • Den Zeitaufwand für die Kopieraktion
  • index  ist unter Mysql ein reserviertes Wort 
Direktlösung:

SELECT  @num:=@num + 1 AS index_, content_id FROM (SELECT @num:=-1)n,cms_content WHERE 1 ORDER BY hierarchy;

Result:

+--------+------------+
| index_ | content_id |
+--------+------------+
|      0 |         15 |
|      1 |         34 |
|      2 |         36 |
|      3 |         37 |
|      4 |         29 |
|      5 |         30 |
|      6 |         46 |
|      7 |         45 |
|      8 |         38 |
|      9 |         47 |
|     10 |         19 |
|     11 |         49 |
|     12 |         13 |
|     13 |         22 |
|     14 |         16 |
|     15 |         18 |
|     16 |         44 |
|     17 |         55 |
|     18 |         54 |
|     19 |         51 |
|     20 |         52 |
|     21 |         56 |
|     22 |         24 |
|     23 |         20 |
|     24 |         39 |
|     25 |         40 |
|     26 |         41 |
|     27 |         42 |
|     28 |         43 |
|     29 |         50 |
|     30 |         25 |
|     31 |         26 |
|     32 |         28 |
+--------+------------+
33 rows in set (0,00 sec)

Die Verwendung von index statt index_ würde zu folgendem führen:

 SELECT  @num:=@num + 1 AS index, content_id FROM (SELECT @num:=-1)n,cms_content WHERE 1 ORDER BY hierarchy;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'index, content_id FROM (SELECT @num:=-1)n,cms_content WHERE 1 ORDER BY hierarchy' at line 1

Fällt einem also nachträglich ein das man dies mit der DB direkt erledigen könnte und hat vorher per Script Variable eingefügt deren Namen unter dem DB System reserviert sind, dann ist der Aufwand es zu ändern möglicherweise groß - je nachdem wie häufig es verwendet wird.

Mit anderen Worten - hier hat man sich eine Entwicklungsmöglichkeit u.U. komplett verbaut.

Tatsächlich findet man in den meisten Opensource - Projekten geradezu lächerliche Pippifax - Abfragen immer im Verbund mit nachfolgenden Schleifen und erneuten Zwischenabfragen.

  • Man benötigt ein Result als Objekte

Ein Fehler bereits in der Basis - Entwicklung - man sucht sich ein Klassensystem aus wie AdoDB weil man daran denkt seine Arbeit vielleicht auch mal unter anderen DB Systemen nutzen zu wollen.

Nun benötigt man seine Results als Array von Objekte.
Dazu müsste die DB Klasse auch z.B. mysqli_fetch_object oder die analogen Mittel aus einer PDO Anbindung beherrschen können.

Da macht man aber unter AdoDB eine lange Nase - denn das gibt es dort nicht.

Das Problem - das eigentliche Result muss nach der Abfrage umkopiert werden.

Wir haben hier zwei Probleme 
  • Das benötigte RAM hierfür wird mehr als verdoppelt, da das DB Ergebnis kopiert wird
  • Den Zeitaufwand für die Kopieraktion
Unterm Strich haben wir immer zwei Problemkreise

  1. Mangelnde Kenntnisse des Programmierers
  2. Aus 1. heraus mangelnde Konstruktion der Tabellen
Es gibt da Auswüchse ohne Ende.

Ein tragisches Beispiel wäre der bei Cmsmadesimple dort so benannte Menumanager der aus ein paar tausend Zeilen Code besteht  um Menüs generieren zu können und es werden zig Abfragen ausgeführt - je mehr Submenüs desto mehr Abfragen.
Das aber kann man dort ebenso mit einem Aufwand von rund 30 Zeilen erledigen und es gibt nur eine einzige Abfrage.
Nun könnte man unendlich viele Beispiele aus diversen Programmen und Bereichen aufführen - hier an dieser Stelle will ich lediglich einmal darauf aufmerksam machen.

RAM - Bedarf und der Zeitfaktor bei der Ausführung stehen immer in einem engen Zusammenhang - gerade bei auf Webtechniken basierenden Anwendungen.

Es wird gerade dort immer sehr gerne unterdrückt das die Last einer Webapplikation rasant mit der Anzahl der gerade aktuellen Nutzer steigt.
Das  kann immer sehr schnell dazu führen das man bereits bei relativ wenigen Nutzern die Wachstumsgrenze erreicht hat.
Die Grenze ist dann erreicht wenn die Nutzer nicht innerhalb einer angemessenen Zeit mit Inhalten bedienen kann.
Und dieses Zeitlimit liegt bei 1 Sekunde - aber komplett gerendert beim Empfänger vorliegend.

Keine Kommentare: