base
portal
Suche:
Forum
Start
Neue Seite erstellen
Titel:
Das Aufbereiten komplexer Datenstrukturen wie Listen oder Hashes zur Speicherung in Datenbank-Feldern oder Dateien, nennt man <i>Serialisierung</i>. Die Listen oder Hashes können beliebig verschachtelt sein, so dass auch Listen von Listen oder Hashes von Listen von Hashes (oder ... ;-) ) möglich sind. Funktionen (Subroutines) die in Perl auch in Variablen enthalten sein können, können allerdings nicht gespeichert werden. Die Funktion dafür heisst <c>serial</c>. Ein spezielles Gegenstück zu <c>serial</c> gibt und braucht es nicht, denn der serialisierte Inhalt ist nichts anderes als Perl-Code, der -mit <c>eval</c> ausgeführt- eine entsprechende Liste oder einen entsprechenden Hash erzeugt: <code> $serial=serial @liste; </code> speichert die Liste <c>@liste</c> in serialisierter, komprimierter Form in der Variablen <c>$serial</c>. <code> @liste=eval $serial; </code> erzeugt die in <c>$serial</c> gespeicherte Liste wieder. Nun macht obiger Code an sich wenig Sinn, da die Liste ja schon existiert. Interessant wird es, wenn man die serialisierte Form speichert: <h2>In Dateien speichern</h2> <code> put serial(%hash), "bla.htx"; </code> speichert den Hash <c>%hash</c> in der Seite <c>bla</c>. Die Klammern braucht es, da <c>"bla.htx"</c> sonst dem Hash zugerechnet würde und nicht als Parameter für <c>put</c>. <code> %hash=eval get "bla.htx"; </code> liest den gespeicherten Hash wieder ein. <h2>In Datenbanken speichern</h2> Auch das Speichern in Datenbankfeldern geschieht denkbar einfach. Dabei weiss die Datenbank garnichts davon, dass in einem Feld z.B. eine Liste gespeichert ist; sie sieht nur den serialisierten Code. Folglich wird es zu Problemen oder unerwarteteten Ergebnissen kommen, wenn eine Serialisierung in bestimmte Feldtypen wie "Zahl" oder "EMail" geschrieben wird - diese überprüfen z.B. die Eingabe auf Korrektheit (Ist es eine Zahl? Ist es eine EMail-Adresse?), was mit der serialisierten Form nicht funktionieren kann. Auch eine Sortierung wird nicht klappen. Am Besten verwenden Sie für Felder, in denen Sie Listen oder Hashes speichern wollen die Feldtypen <c>text</c> oder <c>textarea</c>. <code> @kinder=("Barbara", "Ingrid", "Stefan"); put ["Name", "Hans", "Kinder", serial(@kinder)], "leute"; </code> speichert die Liste <c>@kinder</c> im Feld <c>Kinder</c> in der Datenbank <c>leute</c>. Die Klammern beim <c>serial</c> sind in diesem konkreten Fall zwar nicht unbedingt zwingend, aber wenn dahinter weitere Felder kommen sollten, sind sie zur Abgrenzung nötig. <code> get "Name==!Hans", "leute"; @kinder=eval $Kinder; out "Kinder von $Name: @kinder"; </code> gibt die Kinder von <c>Hans</c> aus. <h2>Serialisierung als Ersatz für Relationen?</h2> Komplexe Datenstrukturen in Datenbankfeldern können in vielen Fällen "klassische" Relationen ersetzen. Gerade für 1:n-Beziehungen (Alle Kunden eines Kundenberaters) bietet sich das Speichern der entsprechenden Ids in einer Liste an. Das hat viele Vorteile, u.a. einen direkten Zusammenhang (die Daten stehen gleich im zugehörigen Datensatz) und es ist keine spezielle Datenbank für die Relationen notwendig. Sollen auch Rückbezüge möglich sein, müssen diese allerdings zusätzlich in der zweiten Datenbank gespeichert werden. Diese Information ist dann somit doppelt vorhanden, was wieder Vor- und Nachteile hat. Ob man nun die "klassischen" Relationen mit einer dritten Datenbank für die Beziehungen verwendet, oder die Beziehungen mit einer komplexen Datenstruktur gleich bei den Einträgen speichert, hängt vom Einzelfall und dem persönlichen Geschmack ab. Dasselbe wie mit Listen funktioniert genauso mit Hashes, hier gleich in einer verschachtelten Ausführung: <code> %cds= ( "lc1109" => { "Interpret" => "Underworld", "Titel" => "dubnobasswithmyheadman", "Preis" => 19.95 }, "lc0121" => { "Interpret" => "Phil Collins", "Titel" => "Face Value", "Preis" => 12.95 }, "lc0485" => { "Interpret" => "The Police", "Titel" => "Zenyatta Mondatta", "Preis" => 14.95 } ); put ["Name", "Concrete Record Store", "Sortiment", serial(%cds)], "plattenlaeden"; </code> speichert den Hash <c>%cds</c> im Feld <c>Sortiment</c> in der Datenbank <c>plattenlaeden</c>. Hier das Auslesen: <code> while(get "Name~=c", "plattenlaeden") { out "<b>Laden: $Name</b><br>"; %cds=eval $Sortiment; foreach $nr (sort keys %cds) { $cds=$Sortiment{$nr}; out "Nummer: $nr, Interpret: $cds{Interpret}, Titel: $cds{Titel}, $cds{Preis}<br>"; } out "<br>"; } </code> liest alle Einträge der Datenbank <c>plattenlaeden</c> die mit <c>c</c> beginnen und gibt deren Name, sowieso alle CDs (Interpret, Titel und Preis) im Sortiment aus. <achtung> Das obige Beispiel ist gleich eines, das eine mögliche "Fehlanwendung" dieser Funktionalität verdeutlicht. Was ist, wenn man später alle CDs deren Interpret mit "p" anfängt ausgeben lassen will? Das ist mit obiger Umsetzung nicht oder nur mit sehr viel unnötigem Aufwand möglich. In den meisten Fällen sollte man für dieses Beispiel eine zusätzliche Datenbank mit den CDs anlegen und Relationen zwischen den beiden Datenbanken herstellen. </achtung> <h2>dump - Komplexe Datenstrukturen ausgeben</h2> Im Prinzip genauso wie der Befehl <c>serial</c> funktioniert <c>dump</c>. Während <c>serial</c> aber das Ergebnis so platzsparend wie möglich aufbereitet, erzeugt <c>dump</c> eine schöne HTML-Ausgabe. Hier ein Vergleich: <code> <perl> %hash=(Stefan => 23, Hans => 42); $hash{Texte}=["link" => "Dies hier ist ein blinder Text", "hier" => "dort"]; out serial %hash; out dump %hash; </perl> </code> ergibt folgende Ausgabe: <div class=info>("Texte",["link","Dies hier ist ein blinder Text","hier","dort"],"Hans",42,"Stefan",23)<pre style="background:#f0f0f0">(<br> "Texte",<br> ["link", "Dies hier ist ein blinder Text", "hier", "dort"],<br> "Hans",<br> 42,<br> "Stefan,<br> 23<br>)</pre></div> <c>dump</c> eignet sich hervorragend zur [103:Fehlersuche], da damit schnell und einfach Variablenwerte ausgegeben werden können.
Name:
Passwort:
Stichworte:
Version:
1
2
3 Angebot:
Alle
Nur Miete / Lizenz
Nur Miete / Lizenz professional
Nur Miete
Nur Miete smart + pro
Nur Miete smart + pro / Lizenz
Nur Miete pro
Nur Miete ab pure2, smart2, pro1
Nur Lizenz
Nur Lizenz professional
Nur Kostenlos
Ohne Änderungen zurück zur Seite
-
+
©
baseportal
GmbH. Alle Rechte vorbehalten.
powered in 0.01s by baseportal.de
Erstellen Sie Ihre eigene Web-Datenbank - kostenlos!