Warning: include_once(/var/www/html/pmwiki-2.2.86/cookbook/soap4pmwiki/soap4pmwiki.php): failed to open stream: No such file or directory in /var/www/html/fields/dbp11/local/config.php on line 4

Warning: include_once(): Failed opening '/var/www/html/pmwiki-2.2.86/cookbook/soap4pmwiki/soap4pmwiki.php' for inclusion (include_path='.:/opt/php/lib/php') in /var/www/html/fields/dbp11/local/config.php on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/fields/dbp11/local/config.php:4) in /var/www/html/pmwiki-2.2.86/pmwiki.php on line 1250
Datenbankpraktikum SS 2011 - Main - Backend-modellierung
?

Konzeptuelle Modellierung

ER-Diagramm und Grundgedanken

Zu Beginn unserer Arbeit erstellten wir ein "konventionelles", nicht an Rails angepasstes ER-Diagramm. Attribute wurden der Übersichtlichkeit halber weggelassen.

Im weiteren Verlauf zeigte sich jedoch, dass Features wie Generalisierung, schwache Entitäten und n:m-Beziehungen mit Attributen sich schlecht bzw. gar nicht in Rails umsetzen lassen. Z.B. mussten wir die ursprüngliche Beziehung writes_message in eine Entität umwandeln, um ein Text-Attribut anhängen zu können. Vorteil bei dieser Transformation war, dass die Beziehungen transparenter wurden, d.h. der zu schreibende Rubycode lässt sich nahezu 1:1 aus dem Diagramm ablesen.

Umsetzung in Ruby on Rails

Migrations

Migrations stellen in Rails ein besonderes Feature dar, das gewährleistet, dass alle Mitentwickler und Anwender durch Ausführen des Befehls rake db:migrate das gleiche Datenbankschema erstellen, wie von uns erdacht. Gerade in unserem Fall unter Benutzung von SQLite3 stellt dies einen enormen Vorteil dar, da es keine zentrale Datenbank gibt. Rails erkennt über die Versionsnummern, die am Anfang einer jeden Migration stehen, die chronologisch korrekte Ausführung. Dabei werden die self.up-Methoden einer Migration aufgerufen, wodurch Rails die angegebenen Tabellen über automatisch generierte SQL-Statements in die Datenbank schreibt. Die self.down-Methoden invertieren diesen Vorgang. Dadurch ist es möglich, mithilfe des Befehls rake db:migrate VERSION=x die Datenbank auf einen als funktionierend bekannten Stand x zurückzusetzen.

Beziehungen

Das Modellieren von Beziehungen gestaltet sich in Rails, solange man sich an die Konventionen hält, als äußerst komfortabel. Leider gab es viele Situationen, in denen wir diesen Vorteil nicht nutzen konnten. Dies war beispielsweise bei User und Message der Fall, da zwei Beziehungen zwischen diesen Entitäten bestehen, um zwischen geschriebenen und erhaltenen Nachrichten zu unterscheiden. Anhand dieser Beziehung zeigen wir exemplarisch, wie wir dieses Problem gelöst haben:

Das Keyword has_many gibt an, dass es sich um eine 1:n-Beziehung handelt. An zweiter Stelle steht der Name der Beziehung, dann folgt der Name der Entität, auf die referenziert wird, mit foreign_key wird der Fremdschlüssel angegeben und an letzte Stelle wird die dynamische Integrität gesichert. In diesem Fall werden beim Löschen eines Users also seine erhaltenen Nachrichten gelöscht, bei seinen geschriebenen wird die Referenz nur auf nil gesetzt, damit diese für den Empfänger noch lesbar bleiben. Ist u ein User, so kann man nun mit u.received_messages und u.written_messages direkt auf seine erhaltenen bzw. geschriebenen Nachrichten zugreifen.

Integrität

Wie oben schon gezeigt, gibt es in Ruby on Rails einfache Mittel, dynamische Integrität sicherzustellen. :dependent => :destroy kommt dabei dem SQL-Statement on delete cascade gleich, :dependent => :update entspricht on update cascade und :dependent => :nullify wirkt wie on delete set null. Bei der statischen Integrität gibt es ebenfalls von Rails gegebene Methoden, die die angesprochenen Attributfelder auf Vorhandensein, bestimmte Wertebereiche, Einzigartigkeit und vieles mehr verifizieren. Möchte man spezifischere Benutzerprobleme abfangen (bspw. darf ein Mitfahrer nicht gleichzeitig Fahrer sein), müssen dafür eigene Validation-Methoden implementiert werden. Diese werden beim Erstellen eines Objekts initial aufgerufen, um ggf. eine falsche Eingabe abzufangen.


Page last modified on August 19, 2011, at 12:39 PM