Was ist der beste Weg, um ein-zu-eins-Beziehungen in SQL?
Sagen wir, ich habe Alpha Dinge, die möglicherweise oder möglicherweise nicht werden oder Bezug auf Bravo oder Charlie Dinge.
Diese eins-zu-eins-Beziehungen: Kein Alpha beziehen sich auf mehr als eine Bravo. Und keine Bravo beziehen sich auf mehr als eine Alpha.
Habe ich ein paar Ziele:
- ein system, das leicht zu lernen und
pflegen. - Datenintegrität erzwungen, die in meiner
Datenbank. - ein schema, das entspricht der
Reale, logische Organisation
meine Daten. - Klassen/Objekte, die in meiner
Programmierung, die Karte gut zu
Datenbank-Tabellen (à la Linq to SQL) - schnelle lese-und Schreibvorgänge
- effektive Nutzung des Weltraums (wenige null-Felder)
Ich habe drei Ideen...
PK = primary key
FK = foreign key
NU = nullable
Einer Tabelle mit vielen nullalbe Felder (flat file)...
Alphas
--------
PK AlphaId
AlphaOne
AlphaTwo
AlphaThree
NU BravoOne
NU BravoTwo
NU BravoThree
NU CharlieOne
NU CharlieTwo
NU CharlieThree
Viele Tabellen mit null nullalbe Felder...
Alphas
--------
PK AlphaId
AlphaOne
AlphaTwo
AlphaThree
Bravos
--------
FK PK AlphaId
BravoOne
BravoTwo
BravoThree
Charlies
--------
FK PK AlphaId
CharlieOne
CharlieTwo
CharlieThree
Beste (oder schlechteste) der beiden: Viel nullalbe Fremdschlüssel zu viele Tabellen...
Alphas
--------
PK AlphaId
AlphaOne
AlphaTwo
AlphaThree
NU FK BravoId
NU FK CharlieId
Bravos
--------
PK BravoId
BravoOne
BravoTwo
BravoThree
Charlies
--------
PK CharlieId
CharlieOne
CharlieTwo
CharlieThree
Was ist wenn ein Alpha sein muss, entweder Bravo oder Charlie, aber nicht beide?
Was ist, wenn statt nur Bravos und Charlies, Alphas könnte auch alle Deltas, Echos, Foxtrots, oder Golfs, etc...?
EDIT: Dies ist ein Teil der Frage: Welche ist die beste Datenbank-schema für die navigation?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie wollen jedem Alpha zu sein, in Bezug auf die von nur einem Bravo würde ich vote für die Möglichkeit, mit Hilfe eines kombinierten FK/PK:
Diese Weise ein und nur ein Bravo kann sich auf Ihre Alphas.
Wenn die Bravos und Charlies ausschließen müssen, ist die einfachste Methode wäre wahrscheinlich zu erstellen Sie eine Diskriminator-Feld:
Diese Weise die AlphaType Feld zwingt die Datensätze gehören immer zu genau einem Subtyp.
Ich nehme an, Sie werden mit SQL Server 2000 /2005. Ich habe ein standard-Muster für die 1-zu-1-Beziehungen, die ich verwenden, was ist nicht zu unähnlich zu deiner 2. Idee, aber hier sind die Unterschiede:
Jede Person muss ein eigener Primärschlüssel, erste, so dass Ihre Bravo, Charlie, usw.-Tabellen definieren sollten, Ihre eigenen künstlichen Schlüssel, zusätzlich zu den foreign-key-Spalte für die Alpha-Tabelle. Sind Sie, dass Ihr domain-Modell Recht unflexibel durch die Angabe, dass der Primärschlüssel der einen Tabelle muss genau die selbe sein, wie der Primärschlüssel einer anderen Tabelle. Die Entitäten werden daher sehr eng gekoppelt, und ein Unternehmen kann nicht existieren, ohne eine andere, die ist nicht eine business-Regel, die muss durchgesetzt werden in Datenbank-design.
Fügen Sie eine foreign key-Einschränkung zwischen der AlphaID Spalten in der Bravo und Charlie Tabellen der primary key-Spalte auf der Alpha-Tabelle. Dies gibt Ihnen eine 1-zu-viele -, und auch können Sie angeben, ob die Beziehung ist obligatorisch, einfach durch einstellen der null-Zulässigkeit der FK-Spalte (etwas, das nicht möglich ist, in Ihrem aktuellen design).
Add a unique key-Einschränkung auf Tabellen Bravo, Charlie, etc. auf der AlphaID Spalte. Dies erzeugt eine 1-zu-1-Beziehung, mit dem Vorteil, dass der eindeutige Schlüssel fungiert auch als ein index, die helfen können, um die Geschwindigkeit von Abfragen, abrufen von Zeilen basierend auf dem Fremdschlüssel Wert.
Der große Vorteil dieses Ansatzes ist, dass änderungen einfacher:
Persönlich, habe ich viel Erfolg mit Ihrem zweiten Modell, das mit einem PK/FK auf eine einzelne Spalte.
Ich hatte noch nie eine situation, wo alle Alphas waren erforderlich, um einen Datensatz in einer Bravo oder Charlie-Tabelle. Ich habe immer befasst mit 1 <-> 0..1 nie 1 <-> 1.
Zu deiner letzten Frage, das ist nur so, dass viele mehr Tabellen.
Ein weiterer Ansatz ist, die 3 Tabellen für die Speicherung der 3 Personen und eine separate Tabelle für die Speicherung der Beziehungen.
Könnten Sie eine join-Tabelle, der angibt, eine Alpha-und eine zugehörige ID. Sie können dann fügen Sie eine weitere Spalte definieren, wenn es eine ID für die Bravo -, Charlie-oder was auch immer. Hält der Spalte kriechen unten auf Alpha, aber fügt einige Komplexität der Beitritt Abfragen.
Habe ich ein Beispiel funktioniert ziemlich gut so weit passt, dass Ihr Modell:
Habe ich Charlie und Bravo-Tabellen Mit Foreign Key alpha_id von Alpha. Wie dein erstes Beispiel, außer alpha ist nicht der Primärschlüssel, bravo_id und charlie_id sind.
Benutze ich alpha_id auf jedem Tisch, die ich brauche, um die Adresse zu diesen Unternehmen, so, zu vermeiden, die ein SQL-Script, das kann zu Verzögerungen führen, die Erforschung sowohl Bravo und Charlie zu finden, die man Alpha ist, habe ich mir eine AlphaType Tisch und auf Alpha-Tabelle habe ich seine id (alpha_type_id) als foreign key. So kann ich wissen, in einer programmatischen Weise, die AlphaType ich beschäftige mich mit ohne verknüpfen von Tabellen, die möglicherweise Tausende von Datensätzen. in tSQL:
Sie werfen eine Menge von Fragen, die machen es schwer zu wählen, alle von Ihnen vorgeschlagenen Lösungen ohne viel mehr Klarheit über das genaue problem, das Sie lösen möchten. Denken Sie daran, nicht nur meine Klarstellung Fragen, aber die Kriterien, die Sie verwenden, um zu bewerten, meine Fragen als Zeichen für die Menge der Details benötigt, um Ihr problem zu lösen:
Was "System" ist es einfach zu erlernen und zu pflegen? Der source-code der app, oder die app-Daten über end-user-interface?
Was meinst du mit "durchgesetzt, die in meiner Datenbank"? Bedeutet dies, dass Sie nicht durch Mittel, die die Kontrolle der Datenintegrität auf andere Weise, D. H. das Projekt erfordert nur DB-basierte Daten-Integrität Regeln?
Können Sie uns die Reale Welt, logische Organisation, auf die Sie sich beziehen? Es ist unmöglich, folgern Sie aus Ihren drei Beispiele für die Daten, die Sie speichern möchten, D. H. annehmen, dass alle drei Strukturen sind völlig falsch. Wie würden wir wissen, dass, wenn wir wissen, dass die real-world-spec?
Diese Forderung klingt wie Ihre hand ist gezwungen, diese zu erstellen ist mit linq to SQL, ist das der Fall?
Was ist "speedy"? .03 Sekunden? 3 Sekunden? 30 Minuten? Es ist unklar, weil Sie nicht die Angabe der Daten nach Größe und Art der Operationen, auf die Sie sich beziehen.
Effektive Nutzung des Weltraums hat nichts zu tun mit der Anzahl der null-Felder. Wenn du meinst, eine normalisierte Datenbank Struktur, von der abhängen wird, erneut auf das real-world-spec-und anderen design-Elemente von der Anwendung, die nicht bereits in der Frage.
Ich würde gehen, mit der option 1, es sei denn, ich hatte einen entscheidenden Grund, nicht zu. Es könnte nicht Kosten Sie so viel Platz wie man denkt, esp. wenn Sie mit varchars in der Bravo. Vergessen Sie nicht, dass man es Kosten wird Sie für Fremdschlüssel, sekundäre Identität und Indizes benötigt.
Einen Ort, wo Sie vielleicht in Schwierigkeiten geraten ist, wenn Bravo ist kaum gebraucht (<%10), UND Sie benötigen, um schnell zu Abfrage von einem seiner Felder, so dass Sie indizieren.
Ich würde eine übergeordnete Typ /Subtyp-Beziehung.
So, zum Beispiel, ein alpha, das hat charlie aber nicht einen bravo:-
Beachten Sie, dass Sie nicht mehr als einen charlie für die alpha, als wenn Sie versucht haben, erstellen Sie eine zwei charlies mit einem ThingId von 1 Sekunde einfügen würde, um eine einzigartige index - /constraint-Verletzung.