2 Stimmen

Wie kann man diese Mehrfachvererbungsbeziehung mit einem RDBMS modellieren?

Ich sehe mir dieses Datenmodell an, das ich mir ausgedacht habe, und fühle mich nicht wohl dabei. Ich habe die Entitätsnamen geändert, damit es (hoffentlich) mehr Sinn macht. Auf jeden Fall, wie würden Sie das folgende Modell?

Ich habe 3 Entitäten. GovernmentCustomer, PrivateCustomer, PublicCustomer. Private und PublicCustomer sind beide CorporateCustomers. Firmenkunden und Behördenkunden sind Konten. Alle Konten teilen sich denselben Schlüsselraum (wenn also PrivateCustomer eine PK von 1 hat, sollte es nicht möglich sein, dass Public oder GovernmentCustomer eine PK von 1 haben). CorporateCustomers haben einige 1:M-Beziehungen, die GovernmentCustomers nicht haben. PublicCustomers haben einige 1:M-Beziehungen, die PrivateCustomers nicht haben.

Das Erbe:

Account
  CorporateCustomer
    PrivateCustomer
    PublicCustomer
  GovernmentCustomer

Zurzeit hat mein Modell 5 Tabellen. Die Tabelle "Konto" ist die Wurzel dieser Hierarchie, wobei die PK jeder untergeordneten Tabelle eine FK zur PK der übergeordneten Tabelle ist. Alle Tabellen haben also die gleiche PK.

Also ja, wie würden Sie das modellieren? Ich hoffe, dass hier nicht irgendetwas völlig schief gelaufen ist :).

EDIT:

Außerdem: - Ich möchte, dass sich die DB um die Integrität der Schiedsrichter kümmert, nicht die App. - Es ist nicht möglich, dass ein CorporateCustomer existiert, ohne entweder ein privater oder öffentlicher Kunde zu sein. Es ist abstrakt.

1voto

northpole Punkte 10036

Eine Möglichkeit könnte sein:

ACCOUNTS -> ACCOUNT_CUSTOMERS <- CUSTOMERS

CUSTOMERS muss eine Spalte CUSTOMER_TYPE haben, die vom Typ Corporate(C), Private(P), Public(Z), Government(G) ist. Da alle öffentlichen und privaten Kunden auch Firmenkunden sind, könnten Sie, wenn Sie alle Firmenkunden benötigen, etwas wie folgt tun:

SELECT *
  FROM ACCOUNTS
     , ACCOUNT_CUSTOMERS
     , CUSTOMERS
 WHERE ACCOUNTS.ID = ACCOUNT_CUSTOMERS.ACCT_ID
   AND CUSTOMERS.ID = ACCOUNT_CUSTOMERS.CUST_ID
   AND CUSTOMERS.CUSTOMER_TYPE in ('C','P','Z')

Ich habe die ORACLE-Syntax verwendet, aber ich denke, Sie verstehen die Idee.

In response to your edit:

Es scheint, als hätten Sie nur zwei Arten von KUNDEN. Unternehmen und Behörden. Dann ist das sogar noch einfacher. Ich würde einen booleschen Indikator für KUNDEN mit dem Namen PUBLIC_IND verwenden, der, wenn er falsch ist, privat ist, oder einen anderen Typ wie ENTITY_TYPE, der Private(P), Public(Z) oder None(N) sein könnte. Wenn Sie dann alle öffentlichen Firmenkunden erhalten möchten, müssen Sie den Benutzer:

SELECT *
      FROM ACCOUNTS
         , ACCOUNT_CUSTOMERS
         , CUSTOMERS
     WHERE ACCOUNTS.ID = ACCOUNT_CUSTOMERS.ACCT_ID
       AND CUSTOMERS.ID = ACCOUNT_CUSTOMERS.CUST_ID
       AND CUSTOMERS.CUSTOMER_TYPE in ('C')
       AND CUSTOMERS.ENTITY_TYPE = 'Z'

0 Stimmen

Wenn ich diesen Ansatz richtig verstehe, werden Firmenkunden als separate Einheiten von öffentlichen und privaten Kunden behandelt. Ich habe die Frage aktualisiert, um dies zu verdeutlichen. CorporateCustomers kann nicht existieren, ohne ein privater oder ein öffentlicher Kunde zu sein. Kann dieser Ansatz in diesem Fall funktionieren? Im Grunde bin ich mir nicht sicher, wann ich jemals einen Datensatz mit dem Typ "Z" haben werde.

1voto

Darkmoth Punkte 126

Bevor Sie sich darauf festlegen, jede Klasse in dieselbe Tabelle zu packen, würde ich mir die Beziehungen an denen sie beteiligt sind - nicht an den Eigenschaften. Es ist trivial, bestimmte Felder leer zu lassen, wenn die Datensatzart "X" ist, aber es ist unglaublich unhandlich, Beziehungen zu haben, die nur für bestimmte Datensätze in einer Tabelle gelten.

Wenn die Beziehungen der Klassen zu anderen Entitäten genau gleich sind, können Sie sie alle in eine Tabelle packen, ohne dass es einen Nachteil gibt.

0voto

Eugene Yokota Punkte 92703

Es sei denn, es gibt einen signifikanten Unterschied in den Attributen, die unter verschiedenen Arten von Kunden verfolgt wird, würde ich nur eine Tabelle namens Konto mit einigen CustomerType Feld haben. Sie können die 1:m-Beziehung durch Detailtabellen mit FK zu AccountID ausdrücken.

Bearbeiten: Moderne Datenbanken können Datenintegritätsregeln hinzufügen, die über die referenzielle Integrität von FK hinausgehen. Mit SQL Server können Sie zum Beispiel Folgendes hinzufügen CHECK-Einschränkungen zu erzwingen, dass AccountType für bestimmte Stammdaten der Detailtabelle GovernmentCustomer ist. Das könnte etwa so aussehen:

CREATE FUNCTION EnforceGovernmentCustomer(@AccountID int)
RETURNS bit
AS 
BEGIN
   DECLARE @retval bit
   SELECT @retval = 0
   SELECT @retval = 1
   FROM Account
   WHERE AccountID = @AccountID AND AccountType = 3

   RETURN @retval
END;
GO
ALTER TABLE GovernmentCustomerDetail
ADD CONSTRAINT chkGovernmentCustomer CHECK (dbo.EnforceGovernmentCustomer(AccountID) = 1);
GO

0 Stimmen

Wenn ich diesen Ansatz richtig verstehe, müsste meine Anwendung einen Teil der Datenintegrität verwalten. Zum Beispiel wäre es möglich, dass ein Konto vom Typ GovernmentCustomer viele Finanzausweise hat. Nur Firmenkunden sollten diese Beziehung haben. Liege ich da richtig? Ich habe die Frage aktualisiert, um die Datenintegrität etwas deutlicher zu machen.

0 Stimmen

@eed3si9n Danke! Ich werde mal sehen, ob ich das unter Berücksichtigung einer benutzerdefinierten Prüfbeschränkung modellieren kann. Sie sind also generell gegen die Idee, dass sich 5 Tabellen eine PK teilen?

0 Stimmen

@TheDeeno, sofern Sie keine signifikant unterschiedlichen Informationen haben, die Sie für verschiedene Typen verfolgen, sehe ich keine Notwendigkeit, sie voneinander zu trennen. RDBMS verfolgen Entitäten und ihre Beziehungen, wie der Name schon sagt. OO versucht, die reale Welt genau abzubilden und führt auch Verhaltensweisen ein, die mit den Daten verbunden sind. Ich sehe keinen Vorteil darin, dies in diesem speziellen Szenario in die DB zu integrieren.

0voto

Mike G Punkte 4593

Ich denke, Sie sollten nur eine Konto- und eine Kundentabelle sowie eine CustomerRelationship-Tabelle haben. Die verschiedenen Arten von Kunden können mit einer Art Typcode unterschieden werden, und die Beziehungen können mit einer CustomerRelationship-Tabelle aufrechterhalten werden.

0voto

akf Punkte 37387

Ich stimme den anderen zu, dass ein customerType-Feld ausreichen sollte, wenn die verschiedenen Kundentypen ähnlich sind.

Für den Fall, dass dies gerechtfertigt ist, wäre ein Entwurf, der Ihnen hilft, die PK-Beschränkung durchzusetzen, eine MasterAccount-Tabelle, die auf alle Kunden nach ID (die PK-Beschränkung) verweist und einen Verweis auf ihren Typ auf der nächsten Ebene der Hierarchie (Unternehmen oder Regierung) hat.

müssen Sie noch die 1*-Beziehungen abbilden, was Sie mit zwei weiteren Tabellen tun könnten - einer Beziehungstabelle und einer Tabelle für die Zuordnung von Konten und Beziehungen.

0 Stimmen

Ich würde also 3 Tische haben. MasterAccount (ID, CustomerType), CorporateCustomer (Id - FK auf MA) und GovernmentCustomer(ID - FK auf MA)?

0 Stimmen

Ich schätze, dass nicht machen würde, zwischen öffentlich und privat sehr einfach zu unterscheiden, wenn nur die CorporateCustomer-Tabelle abgefragt wird. es wäre am besten, die Master-Tabelle zwischen corp und gov unterscheiden zu lassen, und die corp-Tabelle zwischen pub & priv unterscheiden zu lassen. egal, wie Sie es schneiden, wenn Sie nicht alle Konten auf der gleichen Tabelle halten können, erzwingen eindeutige ids über die Tabellen kompliziert wird.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X