Prof. Dr.-Ing. Johannes Schildgen
johannes.schildgen@oth-regensburg.de

Datenbanken

Kapitel 2: ER-Modelle

2020-10-20

Datenmodellierung

Konzeptionelles Datenmodell

  • Unabhängig vom eingesetzten DBMS
  • ER-Diagramme, UML, ...
[[ { _e: "Personen", pos: [150, 100], attributes: [ { _a:"PersNr", options:["primary"], pos: [89, 13] }, { _a:"Name", pos: [245, 13] } ] }, { _e: "Termine", pos: [530, 100], attributes: [ { _a:"Datum", pos: [475, 25], options:["primary"] }, { _a:"Uhrzeit", pos: [634, 25], options:["primary"] }, { _a:"Raum", pos: [722, 106], options:["primary"] }, { _a:"Dauer", pos: [650, 189]}, { _a:"Bezeichnung", pos: [475, 189]} ] } ], [ { _r: "nehmen teil", _e: ["Personen", "Termine"], card: ["N", "M"] } ]]

DB-Entwurf

  1. Wir stellen uns etwas aus der
    realen Welt vor
  2. Modellierung einer Miniwelt
    als konzeptionelles Schema
  3. Transformation in ein DB-Schema
    (Relational, XML, ...)

Ziele des DB-Entwurfs

  • Genaue Abbildung
  • Aktuell
  • Verständlich
  • Simpel
  • Redundanzfrei
[[ { _e: "Personen", pos: [150, 100], attributes: [ { _a:"Vorname", options:["primary"], pos: [89, 13] }, { _a:"MySpace-URL", pos: [245, 13] }, { _a:"ZKX-Nr.", pos: [175, 183]} ] } ], [ ]]

Viele Fehler und Probleme fallen bereits in der Modellierungsphase auf. So können sie frühzeitig behandelt werden.

Entity-Relationship-Modell

Das ERM modelliert Dinge (Entities) und
Beziehungen (Relationships) zwischen diesen.

7
[[ { _e: "Entitätstyp 1", pos: [150, 100] }, { _e: "Entitätstyp 2", pos: [530, 100] } ], [ { _r: "Beziehung", _e: ["Entitätstyp 1", "Entitätstyp 2"], card: ["", ""] } ]]

Entitätstypen und Entities

[[ { _e: "Personen", pos: [20, 50] } ], [ ]]

Entitätstyp

  • Rechteck im ER-Diagramm
  • z. B. "Personen"

Entität

  • Unterscheidbare Objekte der Miniwelt
  • Ausprägungen von Entitätstypen
  • z. B. "Peter mit der Personalnummer 5"
  • Entitäten tauchen nicht im ER-Diagramm auf

Was ist ein sinnvoller Entitätstyp?

  • Webshop
  • Kunden
  • Login
  • Titanik

https://frage.space

Attribute

  • Eigenschaften von Entitäten
    und Entitätstypen
  • Haben Werte
  • Ellipsen im ER-Diagramm

"Peter hat die Personalnummer 5"

"Personen haben eine Personalnummer
und einen Namen"

[[ { _e: "Personen", pos: [130, 100], attributes: [ { _a:"PersNr", options:["primary"], pos: [69, 13] }, { _a:"Name", pos: [225, 13] } ] } ], [ ]]

Primärschlüssel

8
  • Entitäten müssen wohlunterscheidbar sein
  • 1 oder mehr Attribute bilden den Primärschlüssel
  • Beschreibt eine Entität eindeutig
  • Im ER-Diagramm: Attribut(e) unterstreichen
[[ { _e: "Personen", pos: [150, 100], attributes: [ { _a:"PersNr", options:["primary"], pos: [89, 13] }, { _a:"Name", pos: [245, 13] } ] }, { _e: "Termine", pos: [530, 100], attributes: [ { _a:"Datum", pos: [415, 15], options:["primary"] }, { _a:"Uhrzeit", pos: [535, 15], options:["primary"] }, { _a:"Raum", pos: [655, 15], options:["primary"] }, { _a:"Dauer", pos: [765, 40]}, { _a:"Bezeichnung", pos: [765, 110]} ] } ], [ ]]

Darf es am gleichen Tag zur gleichen Uhrzeit mehr als ein Termin geben?

  • Ja, sogar im gleichen Raum
  • Nein, auf keinen Fall
  • Ja, aber nicht im gleichen Raum
  • Nein, allein das Datum muss schon eindeutig sein

https://frage.space

Unterattribute

Attribute können aus mehreren Sub-Attributen zusammengesetzt sein.

[[ { _e: "Personen", pos: [150, 100], attributes: [ { _a:"PersNr", options:["primary"], pos: [89, 13] }, { _a:"Name", pos: [245, 13] }, { _a:"Adresse", pos: [409, 105], attributes: [ { _a: "Straße", pos: [324, 160] }, { _a: "PLZ", pos: [437, 188] }, { _a: "Ort", pos: [550, 170] } ] } ] } ], [ ]]

Mehrwertige Attribute

[[ { _e: "Personen", pos: [150, 100], attributes: [ { _a:"PersNr", options:["primary"], pos: [89, 13] }, { _a:"Name", pos: [245, 13] }, { _a:"Telefon", pos: [409, 105], options:["multi"] } ] } ], [ ]]
[[ { _e: "Personen", pos: [150, 100], attributes: [ { _a:"PersNr", options:["primary"], pos: [89, 13] }, { _a:"Name", pos: [245, 13] }, { _a:"Telefon", pos: [409, 105], options:["multi"], attributes: [ { _a:"Typ", pos: [527, 62] }, { _a:"Nummer", pos: [527, 130] } ] } ] } ], [ ]]

Beziehungen

9-10, 12
  • Beteiligt sind mind. 2 Entity-Typen
  • Rauten im ER-Diagramm
  • Funktionalitäten: 1:1, 1:N / N:1, N:M

[[ { _e: "Personen", pos: [150, 100], attributes: [ { _a:"PersNr", options:["primary"], pos: [89, 13] }, { _a:"Name", pos: [245, 13] } ] }, { _e: "Termine", pos: [530, 100], attributes: [ { _a:"Datum", pos: [475, 25], options:["primary"] }, { _a:"Uhrzeit", pos: [634, 25], options:["primary"] }, { _a:"Raum", pos: [722, 106], options:["primary"] }, { _a:"Dauer", pos: [650, 189]}, { _a:"Bezeichnung", pos: [475, 189]} ] } ], [ { _r: "haben", _e: ["Personen", "Termine"], card: ["1", "N"] } ]]

1:N-Beziehungen

  • Eine Person hat N Termine (beliebig viele)
  • Ein Termin gehört immer zu einer Person

1:N-Beziehungen

  • Eine Person hat N Termine (beliebig viele)
    • Peter hat einen Friseurtermin
    • Peter hat einen Zahnarzttermin
    • Peter hat Fußballtraining
  • Ein Termin gehört immer zu einer Person
    • Der Friseurtermin befindet sich in Peters Kalender

 

 

 

 

N:M-Beziehungen

[[ { _e: "Personen", pos: [150, 100], attributes: [ { _a:"PersNr", options:["primary"], pos: [89, 13] }, { _a:"Name", pos: [245, 13] } ] }, { _e: "Termine", pos: [530, 100], attributes: [ { _a:"Datum", pos: [475, 25], options:["primary"] }, { _a:"Uhrzeit", pos: [634, 25], options:["primary"] }, { _a:"Raum", pos: [722, 106], options:["primary"] }, { _a:"Dauer", pos: [650, 189]}, { _a:"Bezeichnung", pos: [475, 189]} ] } ], [ { _r: "nehmen teil", _e: ["Personen", "Termine"], card: ["N", "M"] } ]]
  • Eine Person nimmt an beliebig vielen Terminen teil
  • An einem Termin können beliebig viele Person teilnehmen

N:M-Beziehungen

  • Eine Person hat beliebig viele Termine
    • Peter hat einen Friseurtermin
    • Peter hat Fußballtraining
  • An einem Termin können beliebig
    viele Person teilnehmen
    • Am Friseurtermin nimmt Peter teil
    • Am Fußballtraining nimmt Peter teil
    • Am Fußballtraining nimmt Katja teil

 

 

 

 

1:1-Beziehung

11
[[ { _e: "Personen", pos: [150, 100], attributes: [ { _a:"PersNr", options:["primary"], pos: [89, 13] }, { _a:"Name", pos: [245, 13] } ] }, { _e: "Kreditkarten", pos: [530, 100], attributes: [ { _a:"Kreditkartennr", pos: [475, 25], options:["primary"] }, { _a:"Ablaufdatum", pos: [595, 25] }, { _a:"Typ", pos: [702, 63] }, { _a:"Sicherheitscode", pos: [702, 135]} ] } ], [ { _r: "haben", _e: ["Personen", "Kreditkarten"], card: ["1", "1"] } ]]
  • Eine Person hat 1 Kreditkarte
  • Eine Kreditkarte gehört immer nur zu einer Person
[[ { _e: "Personen", pos: [400, 100], attributes: [ { _a:"PersNr", options:["primary"], pos: [235, 78] }, { _a:"Name", pos: [310, 20] }, { _a:"Kreditkartennr", pos: [430, 6] }, { _a:"Ablaufdatum", pos: [550, 6] }, { _a:"Typ", pos: [626, 48] }, { _a:"Sicherheitscode", pos: [637, 109]} ] } ], []]

Rekursive Beziehung

  • "Beziehung mit sich selbst"
  • Entitätstyp nimmt mehrfach an einer Beziehung teil
  • Rollennamen zur Unterscheidung notwendig

Beziehungsattribute

11
[[ { _e: "Personen", pos: [150, 100], attributes: [ { _a:"PersNr", options:["primary"], pos: [89, 13] }, { _a:"Name", pos: [245, 13] } ] }, { _e: "Termine", pos: [530, 100], attributes: [ { _a:"Datum", pos: [475, 25], options:["primary"] }, { _a:"Uhrzeit", pos: [634, 25], options:["primary"] }, { _a:"Raum", pos: [722, 106], options:["primary"] }, { _a:"Dauer", pos: [650, 189]}, { _a:"Bezeichnung", pos: [475, 189]} ] } ], [ { _r: "nehmen teil", _e: ["Personen", "Termine"], card: ["N", "M"], attributes: [ {_a:"ist Organisator", pos: [317, 194] } ] } ]]
  • Peter nimmt am Fußballtraining teil
    und ist Organisator
  • Katja nimmt am Fußballtraining teil
    und ist kein Organisator

Webshop-Beispiel

11
[[ { _e: "Kunden", pos: [150, 100], attributes: [ { _a:"Kundennr", options:["primary"], pos: [40, 15] }, { _a:"Name", pos: [159, 9] }, { _a:"E-Mail", pos: [280, 25] } ] }, { _e: "Produkte", pos: [630, 100], attributes: [ { _a:"Produktnr", pos: [575, 25], options:["primary"] }, { _a:"Bezeichnung", pos: [734, 25] }, { _a:"Preis", pos: [822, 106] } ] }, { _e: "Hersteller", pos: [577, 304], attributes: [ { _a:"Firma", pos: [750, 280], options:["primary"] }, { _a:"Land", pos: [750, 345] } ] } ], [ { _r: "sind von", pos: [612, 191], _e: ["Produkte", "Hersteller"], card: ["N", "1"] }, { _r: "bewerten", _e: ["Kunden", "Produkte"], card: ["N", "M"], attributes: [ {_a:"Sterne", pos: [317, 194] }, {_a:"Text", pos: [430, 194] } ] } ]]

N:M-Bez. vs. eigener Entitätstyp

[[ { _e: "Kunden", pos: [50, 10], attributes: [ { _a:"Kundennr", options:["primary"], pos: [10, 85] }, { _a:"...", pos: [140, 85] } ] }, { _e: "Produkte", pos: [730, 10], attributes: [ { _a:"Produktnr", options:["primary"], pos: [690, 85] }, { _a:"...", pos: [810, 85] } ] } ], [ { _r: "bewerten", _e: ["Kunden", "Produkte"], card: ["N", "M"], attributes: [ {_a:"Sterne", pos: [340, 100] }, {_a:"Text", pos: [480, 100] } ] } ]]
[[ { _e: "Kunden", pos: [50, 10], attributes: [ { _a:"Kundennr", options:["primary"], pos: [10, 85] }, { _a:"...", pos: [140, 85] } ] }, { _e: "Produkte", pos: [730, 10], attributes: [ { _a:"Produktnr", options:["primary"], pos: [690, 85] }, { _a:"...", pos: [810, 85] } ] }, { _e: "Bewertungen", pos: [390, 10], attributes: [ {_a:"Bewertungsnr", pos: [300, 100], options:["primary"]}, {_a:"Sterne", pos: [430, 100] }, {_a:"Text", pos: [560, 100] } ] } ], [ { _r: "schreiben", _e: ["Kunden", "Bewertungen"], card: ["1", "N"] }, { _r: "für", _e: ["Bewertungen", "Produkte"], card: ["N", "1"] } ]]

Schwache Entitätstypen

13
  • Kein eigener Primärschlüssel, stattdessen wird der Primärschlüssel von einer anderen Entität vererbt und erweitert
  • ⇒ Existenzabhängig von einem anderen Entitätstypen
  • Entitätstyp und Beziehung doppelt umrahmen
[[ { _e: "Anbieter", pos: [20, 80], attributes: [ { _a:"Anbieternr.", options:["primary"], pos: [5, 5] }, { _a:"Anbietername", pos: [120, 5] } ] }, { _e: "Handytarif", pos: [350, 80], options: ["weak"], attributes: [ { _a:"Tarifbezeichn.", options:["extending_primary"], pos: [300, 5] }, { _a:"Datenvolumen", pos: [417, 5]}, { _a:"Preis", pos: [520, 40]} ] } ], [ { _r: "hat", _e: ["Anbieter", "Handytarif"], options: ["weak"], card: ["1", "N"] } ]]

Die Kombination aus Anbieternummer und Tarifbezeichnung identifiziert einen Handytarif eindeutig, z. B. Vugafon "Data Extreme".

N:M-Bez. vs. schwacher Entitätstyp

[[ { _e: "Kunden", pos: [50, 10], attributes: [ { _a:"Kundennr", options:["primary"], pos: [10, 85] }, { _a:"...", pos: [140, 85] } ] }, { _e: "Produkte", pos: [730, 10], attributes: [ { _a:"Produktnr", options:["primary"], pos: [690, 85] }, { _a:"...", pos: [810, 85] } ] }, { _e: "Bewertungen", pos: [390, 10], options: ["weak"], attributes: [ {_a:"Sterne", pos: [340, 100] }, {_a:"Text", pos: [480, 100] } ] } ], [ { _r: "schreiben", _e: ["Kunden", "Bewertungen"], options: ["weak"], card: ["1", "N"] }, { _r: "für", _e: ["Bewertungen", "Produkte"], options: ["weak"], card: ["N", "1"] } ]]

N:M-Bez. vs. schwacher Entitätstyp

[[ { _e: "Kunden", pos: [50, 10], attributes: [ { _a:"Kundennr", options:["primary"], pos: [10, 85] }, { _a:"...", pos: [140, 85] } ] }, { _e: "Produkte", pos: [730, 10], attributes: [ { _a:"Produktnr", options:["primary"], pos: [690, 85] }, { _a:"...", pos: [810, 85] } ] }, { _e: "Bewertungen", pos: [390, 10], options: ["weak"], attributes: [ {_a:"Sterne", pos: [340, 100] }, {_a:"Text", pos: [480, 100] } ] } ], [ { _r: "schreiben", _e: ["Kunden", "Bewertungen"], options: ["weak"], card: ["1", "N"] }, { _r: "für", _e: ["Bewertungen", "Produkte"], options: ["weak"], card: ["N", "1"] }, { _r: "gefallen", pos: [80, 161], _e: ["Kunden", "Bewertungen"], card: ["N", "M"] } ]]

N:M- vs. zwei 1:N-Beziehungen

[[ { _e: "Gäste", pos: [150, 100], attributes: [ { _a:"Kundennr", options:["primary"], pos: [89, 25] }, { _a:"Tischnr", pos: [245, 25] } ] }, { _e: "Getränke", pos: [530, 100], attributes: [ { _a:"Bezeichnung", pos: [475, 25], options:["primary"] }, { _a:"Preis", pos: [627, 25]} ] } ], [ { _r: "trinken", _e: ["Gäste", "Getränke"], card: ["N", "M"] } ]]

Besser:

[[ { _e: "Gäste", pos: [20, 100], attributes: [ { _a:"Kundennr", options:["primary"], pos: [5, 25] }, { _a:"Tischnr", pos: [120, 25] } ] }, { _e: "Bestellpositionen", pos: [350, 100], options: ["weak"], attributes: [ { _a:"Positionsnr.", options:["extending_primary"], pos: [375, 25] } ] }, { _e: "Getränke", pos: [750, 100], attributes: [ { _a:"Bezeichnung", pos: [695, 25], options:["primary"] }, { _a:"Preis", pos: [847, 25]} ] } ], [ { _r: "geben auf", _e: ["Gäste", "Bestellpositionen"], options: ["weak"], card: ["1", "N"] }, { _r: "von", _e: ["Bestellpositionen", "Getränke"], card: ["N", "1"] } ]]

Ternäre Beziehungen

13
  • Bisher: Beziehungs-Grad = 2 (binäre Beziehung)
  • Grad: Anzahl der teilnehmenden Entitätstypen
  • Ternäre Beziehung: Grad = 3
[[ { _e: "Kunden", pos: [150, 100], attributes: [ { _a:"Kundennr", options:["primary"], pos: [89, 13] }, { _a:"Name", pos: [245, 13] } ] }, { _e: "Tarife", pos: [530, 100], attributes: [ { _a:"Bezeichnung", pos: [475, 25], options:["primary"] }, { _a:"Mindestlaufzeit", pos: [599, 25]}, { _a:"Preis", pos: [698, 71]} ] }, { _e: "Fitnessstudios", pos: [334, 277], attributes: [ { _a:"Strasse", pos: [205, 212], options:["primary"] }, { _a:"Hausnummer", pos: [205, 275], options:["primary"] }, { _a:"Ort", pos: [510, 274], options:["primary"] } ] } ], [ { _r: "buchen", _e: ["Kunden", "Tarife", "Fitnessstudios"], card: ["N", "1", "M"], attributes: [{_a:"Datum", pos: [462, 195]}] } ]]

Ternäre Beziehungen

  • Ein Kunde kann in einem Fitnessstudio nur einen Tarif buchen
  • Ein Kunde kann einen Tarif in vielen Studios buchen
  • Ein Tarif kann in einem Studio von vielen Kunden gebucht werden

Ternäre vs. drei binäre Beziehungen

[[ { _e: "Kunden", pos: [150, 100], attributes: [ { _a:"Kundennr", options:["primary"], pos: [89, 13] }, { _a:"Name", pos: [245, 13] } ] }, { _e: "Tarife", pos: [530, 100], attributes: [ { _a:"Bezeichnung", pos: [475, 25], options:["primary"] }, { _a:"Mindestlaufzeit", pos: [599, 25]}, { _a:"Preis", pos: [698, 71]} ] }, { _e: "Fitnessstudio", pos: [334, 277], attributes: [ { _a:"Strasse", pos: [205, 250], options:["primary"] }, { _a:"Hausnummer", pos: [205, 320], options:["primary"] }, { _a:"Ort", pos: [510, 274], options:["primary"] } ] } ], [ { _r: "buchen", _e: ["Kunden", "Tarife"], card: ["N", "1"], attributes: [{_a:"Datum", pos: [364, 27]}] }, { _r: "angemeldet bei", pos: [284, 188], _e: ["Kunden", "Fitnessstudio"], card: ["N", "M"] }, { _r: "buchen", _e: ["Kunden", "Tarife"], card: ["N", "1"], attributes: [{_a:"Datum", pos: [364, 27]}] }, { _r: "gilt in", pos: [452, 193], _e: ["Fitnessstudio", "Tarife"], card: ["N", "M"] } ]]
  • Ein Kunde bucht stets nur einen Studio-übergreifenden Tarif.
  • Ein Kunde kann bei vielen Studios angemeldet sein
  • Ein Tarif ist in vielen Fitnessstudios gültig

Generalisierung

13
  • Spezialisierung, Vererbung
  • Attribute, Primärschlüssel und
    Beziehungen des Super-Typen
    werden an die Sub-Typen
    vererbt.
  • "is-a"-Pfeil im ER-Diagramm
[[ { _e: "Kunden", pos: [110, 100], attributes: [ { _a:"Kundennr", options:["primary"], pos: [15, 10] }, { _a:"Name", pos: [130, 10] }, { _a:"E-Mail", pos: [250, 10] } ] }, { _e: "Privatkunden", pos: [10, 250], isa: {_e:"Kunden"}, attributes: []}, { _e: "Geschäftskunden", pos: [200, 250], isa: {_e:"Kunden"}, attributes: []} ], [ ]]

Welche Attribute hat ein Privatkunde?

  • Nur Kundennr
  • Keine
  • Kundennr, Name, E-Mail
  • Kundennr, Name, E-Mail, Type-Tag

https://frage.space

Generalisierung

[[ { _e: "Kunden", pos: [110, 100], attributes: [ { _a:"Kundennr", options:["primary"], pos: [15, 10] }, { _a:"Name", pos: [130, 10] }, { _a:"E-Mail", pos: [250, 10] } ] }, { _e: "Privatkunden", pos: [10, 250], isa: {_e:"Kunden"}, attributes: [ {_a:"Bonuspunke", pos: [35, 334]} ]}, { _e: "Geschäftskunden", pos: [200, 250], isa: {_e:"Kunden"}, attributes: [ { _a:"USt-IdNr.", pos: [225, 334]} ]}, { _e: "Produkte", pos: [730, 100], attributes: [ { _a:"Produktnr", options:["primary"], pos: [690, 10] }, { _a:"...", pos: [810, 10] } ] } ], [ { _r: "bewerten", _e: ["Kunden", "Produkte"], card: ["N", "M"], attributes: [ {_a:"Sterne", pos: [390, 10] }, {_a:"Text", pos: [500, 10] } ] }, { _r: "verkaufen", pos: [538, 189], _e: ["Geschäftskunden", "Produkte"], card: ["1", "N"] } ]]

Notationsformen

https://de.wikipedia.org/wiki/Entity-Relationship-Modell

Wir verwenden die Chen-Notation
 

Nicht anpassbar in Chen:

  • Es gibt Orte ohne Personen
  • Es gibt Personen ohne Ort

Krähenfuß-Notation

Die Krähenfuß-Notation kommt in vielen
Datenbank-Modellierungs-Tools zum Einsatz.

  • Genau eins
  • Höchstens eins
  • Mindestens eins
  • Mindestens keins (beliebig viele)

Kapitelzusammenfassung

  • DB-Entwurf mit ER-Diagrammen
  • Entitätstypen, Attribute, Beziehungen
  • Primärschlüssel
  • Schwache Entitätstypen
  • Ternäre Beziehungen
  • Generalisierung
  • Krähenfuß-Notation

Kochrezept: ER-Diagramm erstellen

  1. Text lesen; beim Lesen markieren;
    wichtige Zusatzinfos unterstreichen
    • Rosa: Entitätstypen
    • Gelb: Attribute
    • Grün: Beziehungen
  2. Das Markierte in ER-Diagramm überführen
  3. Nochmals Text lesen und ER-Diagramm überprüfen
  4. Letzte Überprüfung mittels Checkliste (nächste Folie)

Checkliste: ER-Diagramm erstellen

Sind alle Kardinalitäten an Beziehungen?

Kardinalitäten richtig herum?

Gibt es überflüssige Entitätstypen?

Hat jeder Entitätstyp einen Primärschlüssel?

Müssen manche Entitätstypen schwach sein?

Ist die entsprechende Beziehung doppelt umrahmt?

Sind erweiternde Primärschlüssel unterstrichelt?

Sind Generalisierungen korrekt modelliert?

Beispielaufgabe

Eine Bibliothek möchte eine Datenbank einsetzen, um Bücher zu speichern. Jedes Buch hat eine eindeutige ISBN, mehrere Autoren, und einen Titel. Bücher sind von einem Verlag. Von einem Verlag kann es mehrere Bücher geben. Jeder Verlag wird durch eine Verlags-ID identifiziert und hat einen Namen sowie einen Ort.

Beispielaufgabe

Eine Bibliothek möchte eine Datenbank einsetzen, um Bücher zu speichern. Jedes Buch hat eine eindeutige ISBN, mehrere Autoren, und einen Titel. Bücher sind von einem Verlag. Von einem Verlag kann es mehrere Bücher geben. Jeder Verlag wird durch eine Verlags-ID identifiziert und hat einen Namen sowie einen Ort.

[[ { _e: "Bücher", pos: [150, 100], attributes: [ { _a:"ISBN", options:["primary"], pos: [50, 13] }, { _a:"Autoren", options: ["multi"], pos: [175, 13] }, { _a:"Titel", pos: [295, 13] } ] }, { _e: "Verlage", pos: [530, 100], attributes: [ { _a:"Verlags-ID", pos: [475, 25], options:["primary"] }, { _a:"Name", pos: [595, 25] }, { _a:"Ort", pos: [702, 63] } ] } ], [ { _r: "sind von", _e: ["Bücher", "Verlage"], card: ["N", "1"] } ]]

Falsche Lösung

[[ { _e: "Bibliothek", pos: [30, 100], attributes: [ ] }, { _e: "Datenbank", pos: [180, 300], attributes: [ ] }, { _e: "Bücher", pos: [350, 100], attributes: [ { _a:"ISBN", pos: [250, 13] }, { _a:"Autoren", options: ["multi"], pos: [375, 13] }, { _a:"Titel", pos: [495, 13] } ] }, { _e: "Verlage", pos: [730, 100], attributes: [ { _a:"Verlags-ID", pos: [675, 25], options:["primary"] }, { _a:"Name", pos: [795, 25] } ] } ], [ { _r: "sind von", _e: ["Bücher", "Verlage"], card: ["1", "N"] }, { _r: "setzt ein", _e: ["Bibliothek", "Datenbank"], card: ["1", "1"] }, { _r: "verwaltet", _e: ["Datenbank", "Bücher"], card: ["", ""] } ]]