ebonyifinance.com

  

Beste Artikel:

  
Main / So implementieren Sie SQL-Insert vom Supertyp-Subtyp

So implementieren Sie SQL-Insert vom Supertyp-Subtyp

In diesem letzten von drei Artikeln bauen wir das physische Design aus dem logischen Design auf. Wir werden zuerst einen geraden Port aus dem logischen erstellen und dann Tabellen, die aus der Hierarchie der Supertypen und Subtypen erstellt wurden, in verschiedenen Mustern zusammenführen.

Unabhängig vom Design müssen wir Prüfbeschränkungen und manchmal komplexere auslösende Subsysteme hinzufügen, um sicherzustellen, dass die Daten konsistent bleiben. In der zweiten Hälfte des Artikels haben wir die Geschäftsregeln für unser Beispielproblem eingeführt, teilweise in Business Process Model und Notation Version 2.

Dort haben wir erklärt, warum Generalisierungshierarchien für die Datenmodellierung selbst von zentraler Bedeutung sind und wie beispielsweise Mehrfachvererbung in Box-in-Box-Notation korrekt ausgedrückt wird. Obwohl ich hoffe, dass Sie diese Artikel lesen, habe ich diesen Artikel so gestaltet, dass er größtenteils in sich geschlossen ist.

Unser Ausgangspunkt ist die Überprüfung des logischen Diagramms selbst - und dann dreht sich alles um die Datenbank. Die Generalisierungshierarchie wird mit dem Employee-Supertyp, den direkt untergeordneten Subtypen Manager und Engineer und dem mehrfach abgeleiteten Mangineer gebildet.

Das Subtypisierungssymbol zeigt den Diskriminator des Mitarbeiters an. Wenn kein "X" vorhanden ist, überlappt sich die Hierarchie. Ein Mitarbeiter kann sowohl Manager als auch Ingenieur sein. Die Hierarchie ist ebenfalls unvollständig - ein Mitarbeiter wird nicht unbedingt durch einen Subtyp beschrieben - obwohl dies im IE nicht angezeigt werden kann. Eine weitere Geschäftsregel unseres Beispielproblems, die wir nicht grafisch darstellen können, ist, dass eine Person, die sowohl Manager als auch Ingenieur ist, auch ein Mangineer sein muss - das Diagramm kann nur die logische Umkehrung implizieren.

Diese Regel wurde im ersten Artikel durch das BPMN-Variantenmodell festgelegt, mit dem der Mangineer eingeführt wurde. Dies ist das physikalische Modell mit geringfügigen Änderungen, die aus dem logischen Modell generiert wurden.

Wir haben die Viele-Viele-Beziehung zwischen Stunden gelöst. Da das Modell jetzt mit SQL Server verbunden ist, entwerfen wir Schemata für Gruppierung und Sicherheit. Schließlich haben wir eine Tabelle aus der Klassifizierungseinheit hr erstellt. Die Beziehungen in Rot konvergieren auf dem mehrfach abgeleiteten Subtyp h. Wir können, können wir nicht? Schließlich haben Sie möglicherweise bemerkt, dass die Diskriminatorspalte in der Mitarbeitertabelle fehlt, wie dies häufig der Fall ist.

Aber wir können es zurückbringen. Als nächstes werden wir die Mangineer-Regel einführen, die unsere Gedanken zur Mehrfachvererbung erweitert und wie wir sie unterstützen. Schließlich werden wir untersuchen, wie der fehlende Diskriminator des Supertyps unterstützt werden kann - was häufig aus gutem Grund der Fall ist. Zusammengenommen führen uns das Problem des geteilten Fremdschlüssels, die Mangineer-Regel und die Unterstützung des Diskriminators zum Entwurf eines benutzerdefinierten auslösenden Subsystems, um deren Lösungen zu vereinheitlichen, und so werden wir fertig. Im Datendesign sind Subtypen eine Art schwache Entität.

Eine schwache Entität stützt sich für ihre eigene Existenz auf die Existenz einer anderen Entität, die als Eigentümer bezeichnet wird. Dies wird durch die Tatsache deutlich, dass der Schlüssel der schwachen Entität den Schlüssel der referenzierten Entität enthält.

Aufgrund dieser Existenzabhängigkeit möchten wir schwache Entitätsmitglieder löschen, wenn referenzierte Entitätsmitglieder gelöscht werden. In der obigen Abbildung sehen Sie den Fehler, den Sie erhalten, wenn Sie versuchen, den zweiten Fremdschlüssel in der Stunde auf dem EmployeeID-Schlüssel zu platzieren.

Natürlich könnten wir unsere kaskadierenden Lösch-Fremdschlüssel erhalten, indem wir die beiden Fremdschlüssel des Mangineers durch einen ersetzen, der direkt auf hr verweist. Wir können auch die Schlüsselspalte EmployeeID des Mangineers nicht in zwei Teile aufteilen, für die jeweils eine Kaskadenlöschung definiert ist, und eine Prüfbedingung einführen, die sicherstellt, dass die Spaltenwerte immer gleich sind.

Wir erhalten den gleichen Fehler, und zum Glück ist das Duplizieren einer Spalte, deren einziger Zweck darin besteht, einen Fremdschlüssel aufzuhängen, keine akzeptable Lösung. In unserem dritten Versuch erstellen wir die Fremdschlüssel des Mangineers ohne das kaskadierende Löschen und definieren anstelle von Triggern in den Manager- und Engineer-Tabellen das Vorlöschen von Mangineer-Zeilen, wenn Manager- oder Engineer-Zeilen gelöscht werden. Die Nachricht sagt uns, dass anstelle von Triggern und kaskadierenden Lösch-Fremdschlüsseln in derselben Tabelle nicht kompatibel sind.

Wenn Sie zuerst den Trigger und dann den Fremdschlüssel erstellen, wird eine ähnliche Fehlermeldung 1787 angezeigt. Diese Zwei-Bedingungen-Erweiterung erweitert sich auf diese beiden implizierten bedingten Anweisungen sowie deren Kontrapositive, die mit dem Hauptsymbol gekennzeichnet sind:

Wir beginnen unsere Analyse mit den Bedingungen B und B '. Wenn wir uns sowohl auf das physikalische Modelldiagramm als auch auf den vorherigen Abschnitt über geteilte Schlüssel beziehen, wissen wir, dass wir Fremdschlüssel vom Mangineer an den Manager und den Ingenieur implementieren werden - nur ohne die Kaskadenlöschaktion. Die Schlüssel reichen aus, um Bedingung B zu erzwingen und um sicherzustellen, dass bei Einfügevorgängen der Mangineer an letzter Stelle steht.

Die fehlende Aktion bedeutet jedoch, dass die Schlüssel selbst B 'nicht erzwingen können, was beim Löschen im Manager oder Ingenieur auftritt. Dies bestätigt unsere Schlussfolgerung im Abschnitt über geteilte Schlüssel: Unsere Maßnahmen zur Unterstützung von A sind jedoch nicht so einfach und werden in der Praxis häufig übersehen. Wie bereits erwähnt, enthält das physikalische Entwurfsdiagramm - oder logisch oder konzeptionell - nichts, was diese Regel impliziert.

In unserer Datenmodellierung ist die Teilnahme an Beziehungen zwischen dem Quellenmanager und -ingenieur zum Ziel-Mangineer optional, wie dies in diesem Alles-oder-Nichts-Szenario der Fall sein muss.

Wir dokumentieren und übermitteln die A-Anforderung an die Entwickler, aber anstatt auf das Beste zu hoffen, sollten wir proaktiv sein. Wir können A in dem auslösenden Subsystem, das wir entwerfen, aufgrund des Timings nicht erzwingen, aber wir können Transaktionsverletzungen in einem Hintergrundthread erkennen und protokollieren.

Als Kontrapositiv von A sagt Bedingung A 'im Wesentlichen dasselbe, aber der Wortlaut deutet stärker auf die Regel auf der Löschseite hin. Aus Sicherheitsgründen können wir in unserem Auslösemechanismus durchsetzen, dass der Mangineer nicht direkt gelöscht werden kann - dass er tatsächlich nur durch Löschen der entsprechenden Ingenieur- oder Managerzeile gelöscht werden muss.

Wenn wir die Diskriminatorspalte wieder zur Mitarbeitertabelle hinzufügen möchten, muss sie dynamisch aktualisiert werden, wenn ihre untergeordneten Tabellen geändert werden.

Wie bei der Regel für geteilte Fremdschlüssel und Mangineer überlassen wir die Implementierung aus Sicherheitsgründen nicht dem wachsenden Bestand an Code für gespeicherte Prozeduren, sondern möchten ihn im neu entstehenden auslösenden Subsystem.

Da Overhead und Fehleranfälligkeit erforderlich sind, speichern wir diese systemimplizierten Daten nur dann redundant, wenn dies durch Abfragemuster gerechtfertigt ist. Nehmen wir an, sie tun es. Oder teilen Sie es in zwei Bitspalten auf - wir werden dies nicht berücksichtigen.

Wir werden diese Einschränkungen teilweise in die Mitarbeitertabelle einfügen, um sicherzustellen, dass neue Zeilen den Status Null haben: Eine implizite Tatsache ist eine Tatsache, die durch eine Abfrage in einer Tabelle s erhalten werden kann, und als solche erlauben wir niemals, dass ihr Wert durch Benutzercode festgelegt wird. dies würde zu Inkonsistenzen führen. Da der Diskriminatorwert von Einfüge- und Löschvorgängen abhängt, die für untergeordnete Tabellen ausgeführt werden, sollten ihn nur Trigger für diese Tabellen festlegen. Um dies sicherzustellen, benötigen wir auch einen AFTER-Update-Trigger für die Mitarbeitertabelle. Hier ist das relevante Snippet:

Der Kontextwert für die Verbindung darf nur durch untergeordnete Tabellenauslöser festgelegt werden. Andere Prozedurcodes sollten den Wert nicht kennen, sodass der Diskriminator schreibgeschützt ist. Wir werden sehen, wie der Kontext im folgenden Auslösemechanismus eingestellt wird, aber wir haben bereits den ersten Auslöser und andere Schutzmaßnahmen eingerichtet.

Und ja - das Einstellen des Kontexts auf die aktuelle SPID ist nicht die sicherste Strategie - nur eine Demonstration. Wir befassen uns mit der Durchsetzung komplexer Geschäftsregeln, wenn Einfüge- und Löschaktionen für die Tabellen ausgeführt werden, die wir aus den Entitäten Supertyp und Subtyp generiert haben. Um es noch einmal zu sagen: Beginnen wir mit dem Einfügen. Alle Trigger für die Manager- und Engineer-Tabellen sind im Wesentlichen gleich, daher zeige ich nur den Code für den Engineer.

Dieser Ausschnitt aus dem AFTER Insert-Trigger oben zeigt, dass die Aktion zum Aktualisieren des Diskriminators im nächsten gemeinsam genutzten Code ausgeführt wird: Das Zusammenführen des nahezu identischen Codes, der in insgesamt vier Triggern angezeigt wird, zu einem Modul macht die Logik komplexer, aber die zusätzliche Sicherheit sollte sich während des gesamten Wartungszyklus lohnen. Nachdem die Trigger die EmployeeID-Primärschlüssel aus der eingefügten oder gelöschten logischen Tabelle in einen benutzerdefinierten Tabellentyp gepackt und die Prozedur aufgerufen haben, legt der Prozedurcode zunächst den Verbindungskontextwert fest, sodass der Aktualisierungstrigger für die Mitarbeitertabelle die Änderung des Diskriminators ermöglicht .

Nach wie vor ist die Verwendung der aktuellen Sitzungs-ID nicht sicher - nur zu Demonstrationszwecken. Wenn sich der Diskriminator in einem korrekten Zustand befindet, wechselt er in den nächsten korrekten Zustand. Aus diesem Grund haben wir uns bemüht, den korrekten Startzustandswert 3 für die Einfügung im Abschnitt zur Unterstützung des obigen Diskriminators sicherzustellen.

Unter der Annahme, dass die Implementierung korrekt ist, überzeugen Sie sich selbst vom Handbuch! Im Gegensatz zu den Einfügetriggern müssen die Löschtrigger für Mitarbeiter, Manager und Techniker anstelle von Versionen sein, da sie neben dem Festlegen des Diskriminators auch das Löschen von Kaskaden implementieren müssen, und zwar in der Reihenfolge von Kind zu Eltern, um Verstöße gegen Fremdschlüssel zu verhindern.

Wie Sie sich erinnern, müssen wir aufgrund der Mehrfachvererbung unsere eigene Kaskadenlöschung durchführen, wie im Abschnitt über das Problem des geteilten Fremdschlüssels oben beschrieben. Die Löschauslöser für Manager und Techniker übernehmen das Löschen der Mangineer-Zeilen, falls vorhanden: Die Reihenfolge der Operationen ist kritisch.

Wir löschen zuerst die untergeordneten Mangineer, die nicht mehr existieren können, wenn einer der Eigentümer fehlt - Bedingung B '-, gefolgt von den Zeilen des Managers oder des Ingenieurs selbst, und nach allen Löschungen können wir den Diskriminator aktualisieren, wenn die Löschungen nicht im Stammverzeichnis begonnen haben Mitarbeiter.

Wie beim Code zum Aktualisieren des Diskriminators haben wir den Code zum Löschen der Mangineer in ein gemeinsames Modul eingefügt: Das Festlegen des Kontexts für die Verbindung ist auch Teil der Strategie, um das direkte Löschen des Mangineers zu verhindern.

Denken Sie daran, dass gemäß Geschäftsregel A 'im Abschnitt, der die obige Mangineer-Regel beschreibt, ohne die Mangineer-Zeile nicht sowohl Manager- als auch Engineer-Zeilen vorhanden sein können. Daher erlauben wir das Löschen durch Manager- und Engineer-Löschauslöser nur wie oben. Im Beispielcode sehen Sie, dass ich den Kontext erneut festgelegt habe. In jedem Fall verwendet dieses Snippet aus dem letzten Trigger - einem Trigger nach dem Löschen - in der Mangineer-Tabelle den Kontext, um ein direktes Löschen zu verhindern: Im vorhergehenden Abschnitt haben wir Fälle betrachtet, in denen der Supertyp und alle Untertypen aus dem logischen Entwurf als Tabellen implementiert wurden.

Tatsächlich haben wir jedoch die Wahl, welche Entitäten zu Tabellen werden sollen. Wir können Tabellen auf verschiedene Arten zusammenführen: Wir rechtfertigen das Zusammenführen, um das Abfragen zu vereinfachen oder das Design zu vereinfachen oder eine bessere Leistung zu erzielen. In der Praxis erhalten wir jedoch nicht unbedingt einen dieser Vorteile. Wie immer ist eine sorgfältige Analyse der aktuellen und vorhergesagten Nutzungsmuster erforderlich.

Und wie immer müssen wir immer noch alle Geschäftsregeln durchsetzen, und wie ohne Zusammenführung sind häufig Auslöser beteiligt. Eine Folge der obigen Erklärung zur Durchsetzung von Geschäftsregeln ist, dass wir sicherstellen müssen, dass die Daten dieselben sind, wie sie ohne Zusammenführung gewesen wären. Für unser laufendes Beispiel sind die folgenden Optionen realisierbar: Wir werden auch untersuchen, wie der Mitarbeiter in die Manager- und Ingenieurtabellen gerollt wird, aber wir müssen die Regeln ändern.

In diesem Rollup-Design haben wir alle drei subtypbasierten Tabellen zum Supertyp - h - zusammengeführt. Wenn die Spalten in den Subtyp-Tabellen größtenteils nicht null waren, müssen sie in der Rollup-Tabelle alle null sein. Die gelben Tabellen standen vor dem Aufrollen in Beziehung zu den Subtypen, und ihre Beziehungen bleiben auf der Supertypebene.

Für unser Beispielproblem ist das Aufrollen insgesamt ein großer Gewinn bei der Reduzierung der Rohrleitungen, die den mehrfach abgeleiteten Mangineer unterstützen. Was den Diskriminator betrifft: Obwohl die bereits vorhandenen Beziehungen der Mitarbeitertabelle unverändert bleiben, müssen die neuen Beziehungen, die aus den Untertypentabellen abgerufen wurden, überprüft werden, um festzustellen, ob Fremdschlüssel allein die Regeln noch unterstützen.

Es bleiben also Probleme. Es gibt immer. Der Diskriminator bleibt eine implizite Tatsache, so wie wir es zuvor getan haben, um zu verhindern, dass Benutzercode ihn ändert. Als wir über die Unterstützung des Diskriminators für das Pre-Rollup-Design diskutierten, haben wir verschiedene Einschränkungen sowie einen Teil des auslösenden Subsystems eingeführt. Dazu gehörten das Platzieren von Auslösern in mehreren Tabellen, das Schreiben eines gemeinsam genutzten Codemoduls sowie das Festlegen und Testen des Verbindungskontexts.

Da jetzt alle benötigten Informationen in jeder Mitarbeiterzeile enthalten sind, machen wir den Diskriminator einfach zu einer berechneten, persistenten Spalte und fertig. In den meisten oder vielleicht in den allermeisten Situationen sollte die berechnete Spalte funktionieren und effizient sein, in unserem speziellen Fall jedoch nicht.

Weil aufgerollte Tischstunde.

(с) 2019 ebonyifinance.com