2009-03-11 15 views
4

was der beste Weg ist die folgende ..."One-to-many" Modellierung Frage

Angenommen, ich habe zwei Objekte zu modellieren: Agency und Publisher, und beide haben eine 1-zu-n-Beziehung zu Employee . Dies ist eine echte 1-zu-n-Beziehung, da jeder Employee nur für einen Agency oder einen Publisher arbeiten kann. Nehmen wir weiterhin an, dass ich keinen Supertyp (Employer) einführen kann, der die 1-zu-n-Beziehung enthält.

Meine bevorzugte Lösung ist ein Fremdschlüssel in Employee zu haben, die entweder Verbindung zu einem Primärschlüssel Agency oder Publisher (alle meine Primärschlüssel 64-Bit-IDs sind, die über die Datenbank eindeutig sind). Jetzt kann ich jedoch keine bidirektionale Verknüpfung mehr zuordnen, ohne in Employee anzugeben, ob es sich um eine Agency oder Publisher Beziehung handelt.

Meine andere Option ist die Verwendung von zwei Tabellen AgencyEmployee und PublisherEmployee, die dann als traditionelle 1-zu-n bidirektionale Verbindungen verknüpft werden können.

Was halten Sie in dieser Situation für die beste Vorgehensweise?

UPDATE: Danke für die tollen Antworten in so kurzer Zeit! Was halten Sie von der folgenden Lösung: Fremdschlüssel in Employee für beide Agency und Publisher, wie agency_id und publisher_id?

Antwort

1

Die beste Vorgehensweise wäre wahrscheinlich die Einführung einer Arbeitgeberklasse.

Teilen Employee in AgencyEmployee und PublisherEmployee, auf der anderen Seite, wäre ein Bad Thing ™ zu tun.

Wenn die Einführung von Arbeitgeber nicht in Frage kam, würde ich den Arbeitgebertyp (Agentur oder Verlag) in Mitarbeiter angeben.

Antwort auf die Frage aktualisiert:

, dass eine Option, aber employer_type ist besser, weil:

  1. Sie könnten andere Arbeitgeber Typen hinzufügen möchten, in die Zukunft
  2. Es wird ein leeres Feld in jeder Zeile der Employees-Tabelle.
+0

Ich stimme den Best Practice- und Bad Thing-Aufrufen zu, aber ich denke, dass aus Sicht der Normalisierung eine dritte Tabelle mit EmployeeID als PK, EmployerID und EmployerType besser wäre. –

+0

@Harper: Das ist richtig, aber aus einer pragmatischen Sicht bedeutet das eine andere Verbindung (und einen mehrspaltigen Primärschlüssel). –

0

Sounds wie dies könnte als ternary relationship modelliert werden. Sehen Sie, ob Ihnen die Vorgehensweise in diesem MSDN-Artikel gefällt.

0

Meine persönliche Präferenz wäre eine Tabelle haben Sie sich ausdrücklich nicht verwendet werden, annehmen kann (der übergeordneten Typ von Agentur und Verlag, Arbeitgeber)

Eine einfache Alternative wäre, einfach nicht die Fremdschlüssel zu erzwingen. Dies ist nicht unbedingt problematisch, vorausgesetzt, alle Änderungen an der Datenstruktur erfolgen über Stored Procedures, die Sie steuern.

Meine letzte Präferenz würde Ihrem Vorschlag ähneln, eine Tabelle für AgencyEmployees und eine für PublisherEmployees zu haben. Aber ich würde das noch einen Schritt weiter trennen ...

Table1: Agency    (id, name, etc) 
Table2: Publisher   (id, name, etc) 
Table3: Employee   (id, name, etc) 
Table4: AgencyEmployees  (agency_id, employee_id) 
Table5: PublisherEmployees (publisher_id, employee_id) 


Ein Grund, warum ich dies tun würde, ist, dass es trivial wird diese Zeit abhängig zu machen. Mitarbeiter starten, verlassen und bewegen sich zwischen Unternehmen. Die folgende leichte Änderung des oben Sie erlauben würde, dass zu verfolgen ...

Table1: Agency    (id, name, etc) 
Table2: Publisher   (id, name, etc) 
Table3: Employee   (id, name, etc) 
Table4: AgencyEmployees  (agency_id, employee_id, start_date, leave_date) 
Table5: PublisherEmployees (publisher_id, employee_id, start_date, leave_date) 

Dies erzwingt keinen 1 Arbeitgeber pro Mitarbeiter zu jeder Zeit, aber das kann durch Ihre gespeicherten Prozeduren, GUI erzwungen werden, usw. ..

0

ich diesen Ansatz verwendet haben:

Employee.EmployerType ('Agentur' oder 'PUBLISHER')

Employee.EmployerID (AgencyID oder PublisherID)

Es funktioniert in Ordnung, aber Sie benötigen eine Fallanweisung in vielen Ihrer SQL. Auch wenn Sie ein ORM verwenden, verlieren Sie die FK-Beziehung.

Ich verschiebe den Großteil meines Codes in die n: m Beziehungen, so dass ich die Vorteile unserer ORMs FK-Unterstützung nutzen kann.

0

eindeutig ein Arbeitgeber Unternehmen bevorzugt werden würde, aber sonst ...

AgencyEmployee & PublisherEmployee Tabellen zu haben bedeutet, es wird schwierig sein, zu bestimmen, ob ein Mitarbeiter eine oder andere Kategorie gehört.

Also stattdessen würde ich hinzufügen und EmployerType-Spalte in der Employees-Tabelle; Es fügt Ihren nachfolgenden SQL-Abfragen ein wenig zusätzliche Komplexität hinzu, aber es funktioniert innerhalb der Einschränkungen, die Sie angegeben haben.

Aus Interesse, warum würden Sie in der Lage sein, AgencyEmployee & PublisherEmployee-Tabellen hinzuzufügen, aber keine Employer-Tabelle hinzufügen? Nur neugierig ...

0

A +1 für Can Berk Güder.

Technisch bedeutet die Einführung eines Employer-Supertyps die Einführung einer Employer-Beziehung mit allen Attributen von Agency und Publisher, einer AgencySpecific (nicht sicher, wie man es nennt) Relation zum Employer-Schlüssel und allen Agency-spezifischen Attributen und dem Employer Schlüssel als Fremdschlüssel, dann Agentur als Abfrage oder Sicht, die nur AgencySpecific mit Arbeitgeber, und ebenso für Publisher verbindet.

Es mag ein wenig umständlich sein, wenn Agentur- und Publisher-Daten über zwei Tabellen verteilt sind, denen Sie jedes Mal beitreten müssen. Die Alternative besteht darin, die meisten Ihrer Anfragen zweimal mit Agent und einmal mit Publisher zu schreiben und dann handhabt ihre Gewerkschaften, um die Ergebnisse zu kombinieren. (Ich habe noch keinen Query Builder gesehen, der mit grundlegenden Dingen wie diesem hilft.) Ich musste es für ein Projekt tun, das den Ansatz "no supertypes" verwendet und ich möchte es nicht noch einmal machen.

BTW ternäre Beziehungen und sogar n-zu-n-Beziehungen sind keine gute Design-Praxis, wenn Sie mich fragen. Unter Verwendung von nur Funktionen (d. H. 1-zu-n und 1-zu-1) z. Einschränkungen werden viel einfacher zu formulieren.