Anders, geben Sie nicht auf jede Integrität oder Härte, zB Typ Sicherheit.
(Antwort folgt).
@Anders. Nein, ganz und gar nicht, Subtypisierung ist in Ordnung (die Frage ist, welche Form Sie verwenden und was die Nachteile sind). Geben Sie keine Stärke oder Integrität oder Typsicherheit oder Prüfungen oder DRI auf. Die von Ihnen gewählte Form erfordert zusätzliche Prüfungen und vielleicht ein wenig Code (hängt von Ihrer Plattform ab).
Dieses Thema kommt häufig zur Sprache, aber der Suchende hat immer eine eingeschränkte Perspektive; ich mache immer wieder die gleichen Aussagen (eine Teilmenge) aus einer unveränderlichen Menge. Es geht darum, alle Optionen zu bewerten. Also schreibe ich ein Dokument. Leider dauert es länger. Vielleicht 4 Seiten. Noch nicht fertig zum Posten. Aber die Diagramme sind fertig, ich denke, Sie sind am Ball, und Sie können es sofort verwenden.
Warnung: Nur erfahrene Projektbauingenieure
Straße nicht geeignet für Wohnwagen oder Leser mit hohem Eek-Faktor
Link zu Vier alternative Datenmodelle in Dokument im Aufbau. Ich entschuldige mich für die Unordnung auf dem Boden; ich werde bald aufräumen.
Link zur IDEF1X-Notation für alle, die mit dem Standard für die Modellierung relationaler Datenbanken nicht vertraut sind.
-
Sie sind alle relational, mit voller Integrität.
-
Die 6NF-Optionen. Relational heute (SQL) bietet keine Unterstützung für 6NF; es verbietet es nicht, es bietet nur nicht die 5NF6NF Strukturen. Daher müssen Sie einen kleinen Katalog erstellen, den manche als "Metadaten" bezeichnen. Dabei handelt es sich eigentlich nur um eine Erweiterung des Standard-SQL-Katalogs (sys-Tabellen). Der erforderliche Grad der Kontrolle wird in jeder Option modelliert.
-
Im Grunde ist EAV richtig gemacht, mit voller Kontrolle und Integrität (Typsicherheit, deklarative referentielle Integrität usw.) und nicht das übliche Chaos.
Diese Fragen/Antworten könnten für Sie von Interesse sein (siehe insbesondere die Datenmodelle):
Mehrfach fest vs. abstrakt flexibel
Datenbankschema-bezogenes Problem
"Einfaches" Datenbankentwurfsproblem
Antwort auf Kommentare
... Auf diese Weise können wir leicht "Kommentar"-Zeilen erfassen, die mit einer bestimmten spezialisierten Typinstanz verbunden sind. Ist dies der richtige Weg, oder werde ich diese Entscheidung später bereuen? Gibt es ein anderes Muster, das wir übersehen?
Ich bin nicht sicher, was Sie meinen. Kommentare, Notizen, Adressen werden am Ende in vielen Tabellen verwendet (Spalten in), so dass die richtige Methode ist, sie zu normalisieren; bieten Sie eine Tabelle für Kommentar, die von jeder Tabelle, die es erfordert referenziert wird. Hier ist eine allgemeine Tabelle für Kommentare. Sie wird in Product (dem Supertyp) verwendet, weil Sie angegeben haben jede Produkt. Es kann genauso gut in einigen der Produkt-Subtypen verwendet werden und in anderen nicht; in diesem Fall wird die FK in diesen Produkt-Subtypen sein.
Ihr Datenmodell
Welchen Zweck erfüllt die Tabelle ProductType in Ihrem Beispiel Product 5NF/subtype? Enthält sie eine Zeile für jedes spezialisierte Produkt, z. B. ProductCPU? Ich nehme an, sie gibt an, welche Spezialisierung das Basisprodukt ist.
(Kleiner kritischer Fehler im Diagramm, korrigiert.)
Ja, genau.
In der relationalen Standardsprache (nicht in dem unkontrollierten Durcheinander, das sich als Datenbank ausgibt) ist der ProductType die Diskriminierungsmerkmal Sie gibt an, welche der Produktuntertypen auf dieses Produkt zutreffen. Sagt Ihnen, mit welcher Produktuntertyp-Tabelle Sie sich verbinden müssen. Beide zusammen ergeben ein logisches Produkt. Vergessen Sie nicht, die Views zu erstellen, eine für jeden ProductType.
-
(Bewerten Sie für jedes der vier Datenmodelle, wie sich ProductType ändert und welche Rolle es genau spielt).
-
"Generalisierung-Spezialisierung" ist alles Hokuspokus, OO-Terminologie; ohne die Grenze zu überschreiten und zu lernen, wozu Relational seit 30 Jahren fähig ist. Wenn Sie ein wenig über Relational lernen, werden Sie die volle Leistung haben; andernfalls sind Sie auf den sehr begrenzten OO-Ansatz für alles beschränkt (Ambler und Fowler haben eine Menge zu verantworten). Bitte lesen Sie diese Stelle , von 11 Dez 10 weiter. Relationale Datenbanken modellieren Entitäten, keine Objekte, keine Klassen.
Wenn Sie zum Beispiel ein neues Produkt hinzufügen, möchten Sie eine Dropdown-Auswahl der Produkttypen anbieten, die Sie hinzufügen können. Anhand dieser Auswahl lässt sich ableiten, in welche Tabellen die Daten eingegeben werden sollen. Ist das richtig? Es tut mir leid, dass ich über Anwendungscode spreche, aber ich muss es einfach in die richtige Perspektive setzen
Ja. Und welche Seite (mit Feldern) soll als nächstes bereitgestellt werden, damit der Benutzer Daten eingeben kann.
Es ist kein Problem, über den Anwendungscode zu sprechen, der die Rdb verwenden wird, sie gehören zusammen wie Mann und Frau (nicht wie Mann und Sklave).
-
Für Ihre OO-Klassen ordnen Sie den Klassenbaum der Rdb zu, sobald Sie die Modellierung der Rdb abgeschlossen haben, unabhängig von jeder Anwendung, die sie verwenden wird. Nicht andersherum. Und nicht abhängig von einer bestimmten Anwendung.
-
Vergessen Sie das "Persistieren", es bringt viele Probleme mit sich (verlorene Aktualisierungen; beschädigte Datenintegrität; problematische Fehlersuche; massive Konflikte; usw.). Alle Aktualisierungen der Rdb sollten in Transaktionen erfolgen, mit ACID-Konformität, die seit 30 Jahren verfügbar ist, aber Fowler und Ambler haben davon noch nichts gelesen. Normalerweise bedeutet das einen gespeicherten Proc vor xact.
Die Diskriminante ist eine FK zu einer Typ-Tabelle, wie wir bereits festgestellt haben. Sie gibt an, welche spez. Untertyp, an den sich der Basistyp hält. Doch was enthält die Diskriminantentabelle im Einzelnen?
Geht das nicht aus dem Datenmodell hervor? ProducType CHAR(1)
o (2). Name Char(30)
.
Es könnte ein anzeigefreundlicher Text sein, der den Typ für UI-Zwecke angibt,
Ja, u. a. zur Kontrolle, Einschränkung usw., zur Beseitigung von Mehrdeutigkeiten bei der Kodierung oder Berichterstattung.
aber enthält sie auch den genauen Tabellennamen, der den spezialisierten Typ enthält?
Nein. Das wäre ein bisschen zu physisch, um in Daten untergebracht zu werden. Aus Prinzip nicht erlaubt.
Aber das ist nicht notwendig.
Angenommen, ich interessiere mich für das Produkt mit ID = 1. Es hat eine Diskriminante, die anzeigt, dass es ein ProductCPU ist. Wie würden Sie vorgehen, um diese ProductCPU aus Ihrem Anwendungscode abzurufen?
Das wird einfach sein, wenn Sie das bereitgestellte Modell nehmen und es (alle Tabellen) als Klassen, korrekt, etc. implementieren. Das von Ihnen angefragte Beispiel verwendet keine Views (die für Listen und allgemeinere Verwendung gedacht sind). Der Pseudo-Code würde sein:
-
in Anbetracht der ProductId
(Untertyp unbekannt, daher sollten Sie nicht in einem Untertyp-spezifischen Fenster sitzen), laden Sie die Product
nur Supertyp
-
basierend auf dem Discriminator Product.ProductType
setzen, Indikatoren setzen usw. und den entsprechenden Subtyp laden, einen von ProductCPU; ProductMemory; ProductDisk; ProductTape
; usw.
-
Ich habe OO-Methoden gesehen (und bin damit nicht einverstanden), die alle Subtypen für den gegebenen ProductId
auf einmal: ein Subtyp ist gültig, die anderen sind ungültig. Der Code muss sich noch auf die gültige Klasse für die Product
auf Grund Product.ProductType
.
Alternativ, z.B. wenn der Kontext ist, sitzt der Benutzer in einem Subtype-spezifischen Fenster, z.B. ProductCPU
mit dieser eingestellten Klasse, und fordert ProductId
xxx. Verwenden Sie dann die ProductCPU
Ansicht. Wenn sie null Zeilen zurückgibt, existiert sie nicht.
- Möglicherweise gibt es eine
ProductDisk
xxx, aber nicht ein ProductCPU
xxx. Wie man damit umgeht, ob man angibt, dass es ein Product`xxx gibt, es aber keine CPU ist, oder nicht, hängt von den Anforderungen der App ab.
Für Listen, bei denen die App ein Raster ausfüllt, ohne Rücksicht auf die ProductId
Verwenden Sie die Ansichten (jeweils eine), um jedes Gitter zu laden. Dieses SQL basiert auf der Verknüpfung und muss sich nicht auf ProductType
.