ER-Design und Beispiel DB

Ja, es gibt bereits genug Beispiel-DB’s. Doch im Bemühen die Beispiele übersichtlich zu halten, wird meist radikal vereinfacht – gutes DB-Design bleibt dabei auf der Strecke. Ich habe mich deshalb dazu entschieden eine eigene Beispiel-DB zu entwerfen und nutze die Gelegenheit, um ein wenig über DB-Design bzw. ER-Modellierung nachzudenken.Oft bemüht wird das Beispiel Buch-DB. Ein einfaches Schema als abschreckendes Beispiel:

Bild 1: Einfaches Beispiel

Bild 1: Einfaches Beispiel

Ziel unserer Beispiel-DB soll ebenso eine kleine Literatur-DB sein. Dass man mit der obigen einfachen 1:n-Relation AUTOR – BUCH dabei nicht weit kommt ist klar. Vergegenwärtigen wir uns also Schritt für Schritt die Probleme:

  • Problem 1: Das Attribut ”VERLAG” der Tabelle ”BUCH” widerspricht bereits der 1. Normalform (siehe auch wikipedia).
    Die Bedingung ”Frei von Wiederholungsgruppen” wird hier verletzt.
  • Problem 2: Ein Buch kann auch mehrere Autoren haben.
  • Problem 3: Das Attribut ”NAME” der Tabelle ”AUTOR” widerspricht u.U. der Atomizitätsbedingung der 1. Normalform, da der Name i.d.R. aus Vor- und Nachname besteht.

zu Problem 3:
Die Atomizität eines Attributs ist aus der Sicht der Anwendung zu sehen. Die Kombination Strasse+Hausnummer in einem Attribut ist für private Adress-DBs sicher legitim, da eine Trennung erheblichen Mehraufwand oder Ergonomieverlust bedeutet. Warum? Entweder der Benutzer muss die Daten in getrennten Feldern eingeben (Ergonomieverlust, da lästig) oder die Anwendung trennt die Daten hinterher – der Aufwand ist aber nicht zu unterschätzen, denn auch Exoten wie ”Strasse des 17. Juni 17 1/4 3. Stock” traktieren hin und wieder die Anwendung – ganz zu Schweigen von internationalen Adressen.

Für gewöhnlich kann Strasse+HsNr als atomare Information betrachtet werden. Ein Portooptimierer für Serienbriefe kann auf eine getrennte Speicherung dieser Information dagegen schlecht verzichten, da in D Postleitzahlen von der Hausnummer abhängen können.

Für unser Autorennamen-Problem sehe ich das Namensproblem ähnlich entspannt: Die Eingabe im Format Sortiername, Restname scheint mir pragmatisch: Die Sortierung nach Namen erfolgt in der gewünschten Reihenfolge und die hübschere Darstellung (Restname + ” ” + Sortiername) ist leicht (z.B. bei der SQL-Abfrage) generierbar.

Beispiele:

Form in DB:                           schöne Darstellung:
----------------------------          ---------------------------
Droste-Hülshoff, Annette von          Annette von Droste-Hülshoff
Ibn Arabi, Muhyiddin                  Muhyiddin Ibn Arabi
Morus, Thomas                         Thomas Morus

In SQL lässt sich die Drehung am Komma leicht bewirken – hier das Oracle-Beispiel:

select ltrim(substr(NAME, instr(NAME, '','', 1, 1)+1 ))
          || '' ''
          || substr(NAME, 1, instr(NAME, '','', 1, 1)-1) as NiceName
  from AUTOR

Die Verbesserungen der Probleme 1+2 führen zu folgendem Ergebnis:

Bild 2: n:m Autor-Buch-Beziehung

Bild 2: n:m Autor-Buch-Beziehung

Schon ganz nett, aber wir wollen mehr:

  • Problem 4: Literaturfreunde möchten vielleicht Kurt Tucholskys Schloss Gripsholm auch in der rororo Gesamtausgabe Gesammelte Werke Band 9 (1931) von 1985 finden. Eigentlich wollen wir also Texte verwalten und nicht die Verkaufs- und Inventareinheit Buch, wie der freundliche Buchhändler oder der Bibliothekar der Stadtbücherei.

Auch hier wird klar, dass das Design in erster Linie aus der Anwendung abgeleitet wird. Aber: Weitsichtige ER-Designer achten beim Requirements Engineering auf die richtige Fragestellung und müssen dazu sehr wohl die Natur der Dinge (Entities) im Auge habe. Für die Ausleihverwaltung der Schulbücherei hätte also unser Autor-Buch-Modell gereicht. Kommt jedoch ein Informations- und Auskunftssystem hinzu, so benötigen wir die Trennung von Werk und Publikation.

Bild 3: Text und Publikation werden differenziert

Bild 3: Text und Publikation werden differenziert

Sehr schick ist auch, dass nun veschiedene Ausgaben ein und des selben Texts in der Publikation unterschieden werden können.

  • Problem 5: Eine immer gern gesehene Phantasielosigkeit in Datendesigns betrifft Code-Nummer – hier die ISBN. Die ISBN mag zwar die Standard-Buchnummer sein, doch ist sie nicht die einzige: ASIN (Amazon Standard Identification Number), BCID (BookCrossing ID), EAN (European Article Number / Europäische Artikelnummer), LCCN (Library of Congress Control Number) und Nummern anderer Bibliotheken, sowie ISSN (für Periodika) und schliesslich gibt es inzwischen zwei ISBN – eine 10 und eine 13-stellige.

Codes, auch unterschiedlicher Systeme, verwaltet man am besten über eine einheitliche Code-Tabelle. Der Vorteil liegt darin, dass die Suche über eine Tabelle vereinfacht wird. Der Benutzer gibt den Code ein und erhält die zugehörige Publikation ohne wissen zu müssen, was für ein Code-Typ nun auf dem Etikett steht. Ein Nachteil dieses Verfahrens liegt darin, dass ein einheitliches Char-Feld für alle Code-Typen verwendet wird. Die Metriken können jedoch über eine beim Typ hinterlegte Maske (z.B. als Regular Expression) festgelegt werden.

Bild 4: Multiple Codes für die Publikation

Bild 4: Multiple Codes für die Publikation

Ein wenig gemogelt haben wir: Die BCID (BookCrossing-ID) identifiziert keine Publikation, sondern ein konkretes Exemplar. Für die Verwaltung meines eigenen Bücherschranks wäre das kein Problem, solange ich Bücher nicht doppelt besitze. Für die Schulbücherei bräuchten wir natürlich noch eine Tabelle der Exemplare mit zugehörigen Inventarnummern (z.B. eigene oder BC-ID).
Eine interessante Frage wirft dabei die Verknüpfung von Exemplar zur Code-Tabelle auf. Da wir mit unserem Schema keine Bestände verwalten wollen, sondern uns auf die Texte konzentrieren, soll uns dieses Schema fürs erste genügen. Später werden wir es noch sinnvoll erweitern. Ausserdem möchte ich in den nächsten Tagen ein Skript zur Erzeugung des Schemas auf Oracle (und evtl. MySql) bereitstellen.

Bis dahin. Frank

Hinterlasse eine Antwort

XHTML: Diese Schlagwörter kannst du nutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>