Wann sollte ich eins zu eins Beziehung verwenden?


87

Entschuldigen Sie diese Noob-Frage, aber müssen Sie wirklich eine Eins-zu-Eins-Beziehung zu Tabellen in Ihrer Datenbank verwenden? Sie können alle erforderlichen Felder in einer Tabelle implementieren. Selbst wenn die Daten sehr groß werden, können Sie Spaltennamen auflisten, die Sie in der SELECTAnweisung benötigen , anstatt sie zu verwenden SELECT *. Wann brauchen Sie diese Trennung wirklich?

Antworten:


102

1 bis 0..1

  • Die "1 bis 0..1" zwischen Super- und Unterklassen wird als Teil der Strategie "Alle Klassen in separaten Tabellen" zur Implementierung der Vererbung verwendet .

  • Eine "1 bis 0..1" kann in einer einzelnen Tabelle dargestellt werden, wobei der Teil "0..1" durch NULL-fähige Felder abgedeckt wird. Wenn die Beziehung jedoch meistens "1 zu 0" mit nur wenigen "1 zu 1" -Zeilen ist, kann das Aufteilen des Teils "0..1" in eine separate Tabelle einige Vorteile hinsichtlich Speicherplatz (und Cache-Leistung) einsparen. Einige Datenbanken speichern NULL-Werte sparsamer als andere, sodass ein "Grenzwert", an dem diese Strategie realisierbar wird, erheblich variieren kann.

1 zu 1

  • Die reale "1 zu 1" partitioniert die Daten vertikal, was Auswirkungen auf das Caching haben kann. Datenbanken implementieren normalerweise Caches auf Seitenebene und nicht auf der Ebene einzelner Felder. Selbst wenn Sie nur einige Felder aus einer Zeile auswählen, wird normalerweise die gesamte Seite, zu der diese Zeile gehört, zwischengespeichert. Wenn eine Zeile sehr breit und die ausgewählten Felder relativ schmal sind, werden am Ende viele Informationen zwischengespeichert, die Sie eigentlich nicht benötigen. In einer solchen Situation kann es nützlich sein, die Daten vertikal zu partitionieren, damit nur der schmalere, häufiger verwendete Teil oder die Zeilen zwischengespeichert werden, sodass mehr von ihnen in den Cache passen und der Cache effektiv "größer" wird.

  • Eine andere Verwendung der vertikalen Partitionierung besteht darin, das Sperrverhalten zu ändern: Datenbanken können normalerweise nicht auf der Ebene einzelner Felder, sondern nur der gesamten Zeilen gesperrt werden. Durch Aufteilen der Zeile können Sie eine Sperre nur für eine der Hälften zulassen.

  • Trigger sind normalerweise auch tabellenspezifisch. Während Sie theoretisch nur eine Tabelle haben können und der Trigger die "falsche Hälfte" der Zeile ignorieren kann, können einige Datenbanken zusätzliche Grenzen setzen, was ein Trigger kann und was nicht, was dies unpraktisch machen könnte. In Oracle können Sie beispielsweise die Mutationstabelle nicht ändern. Wenn Sie separate Tabellen haben, mutiert möglicherweise nur eine davon, sodass Sie die andere Tabelle weiterhin über Ihren Trigger ändern können.

  • Separate Tabellen ermöglichen möglicherweise eine detailliertere Sicherheit.

Diese Überlegungen sind in den meisten Fällen irrelevant. In den meisten Fällen sollten Sie in Betracht ziehen, die Tabellen "1 zu 1" zu einer einzigen Tabelle zusammenzuführen.


20

Wenn sich Daten in einer Tabelle auf die von der anderen beschriebene Entität beziehen, aber nicht zu dieser gehören, ist dies ein Kandidat, um sie getrennt zu halten.

Dies könnte in Zukunft Vorteile bringen, wenn die separaten Daten auch mit einer anderen Entität verknüpft werden müssen.


19

Wenn Sie zwei Eins-zu-Eins-Tabellen in einer platzieren, liegt wahrscheinlich ein Semantikproblem vor. Wenn beispielsweise jedes Gerät über eine Fernbedienung verfügt, klingt es nicht gut, das Gerät und die Fernbedienung mit ihren Merkmalen in einer Tabelle zu platzieren. Möglicherweise müssen Sie sogar Zeit damit verbringen, herauszufinden, ob ein bestimmtes Attribut zum Gerät oder zur Fernbedienung gehört.

Es kann Fälle geben, in denen die Hälfte Ihrer Spalten für eine lange Zeit leer bleibt oder nie ausgefüllt wird. Beispielsweise könnte ein Auto einen Anhänger mit einer Reihe von Merkmalen haben oder keinen. Sie haben also viele unbenutzte Attribute.

Wenn Ihre Tabelle 20 Attribute hat und nur 4 davon gelegentlich verwendet werden, ist es sinnvoll, die Tabelle aus Leistungsgründen in zwei Tabellen zu unterteilen.

In solchen Fällen ist es nicht gut, alles in einer Tabelle zu haben. Außerdem ist es nicht einfach, mit einer Tabelle mit 45 Spalten umzugehen!


17

Meine 2 Cent.

Ich arbeite an einem Ort, an dem wir uns alle in einer großen Anwendung entwickeln und alles ein Modul ist. Zum Beispiel haben wir eine usersTabelle und ein Modul, das Facebook-Details für einen Benutzer hinzufügt, ein weiteres Modul, das einem Benutzer Twitter-Details hinzufügt. Wir könnten uns entscheiden, eines dieser Module abzuziehen und alle Funktionen aus unserer Anwendung zu entfernen. In diesem Fall fügt jedes Modul der globalen usersTabelle eine eigene Tabelle mit 1: 1-Beziehungen hinzu :

create table users ( id int primary key, ...);
create table users_fbdata ( id int primary key, ..., constraint users foreighn key ...)
create table users_twdata ( id int primary key, ..., constraint users foreighn key ...)

13

Der sinnvollste Zeitpunkt, dies zu nutzen, wäre, wenn es zwei getrennte Konzepte gäbe, die sich immer nur auf diese Weise beziehen würden. Zum Beispiel kann ein Auto nur einen aktuellen Fahrer haben, und der Fahrer kann jeweils nur ein Auto fahren - die Beziehung zwischen den Konzepten von Auto und Fahrer wäre also 1 zu 1. Ich akzeptiere, dass dies ein erfundenes Beispiel ist, um das zu demonstrieren Punkt.

Ein weiterer Grund ist, dass Sie ein Konzept auf unterschiedliche Weise spezialisieren möchten. Wenn Sie eine Personentabelle haben und das Konzept verschiedener Personentypen hinzufügen möchten, z. B. Mitarbeiter, Kunde, Aktionär, benötigt jede dieser Personen unterschiedliche Datensätze. Die Daten, die zwischen ihnen ähnlich sind, befinden sich in der Personentabelle, die Fachinformationen befinden sich in den spezifischen Tabellen für Kunde, Aktionär, Mitarbeiter.

Einige Datenbank-Engines haben Schwierigkeiten, einer sehr großen Tabelle (viele Zeilen) effizient eine neue Spalte hinzuzufügen, und ich habe Erweiterungstabellen gesehen, die die neue Spalte enthalten, anstatt die neue Spalte zur ursprünglichen Tabelle hinzuzufügen. Dies ist eine der verdächtigeren Verwendungen zusätzlicher Tabellen.

Sie können auch entscheiden, die Daten für ein einzelnes Konzept aus Leistungs- oder Lesbarkeitsproblemen auf zwei verschiedene Tabellen aufzuteilen. Dies ist jedoch ein ziemlich spezieller Fall, wenn Sie bei Null anfangen. Diese Probleme werden sich später zeigen.


5

nicht sehr häufig.

Sie können einige Vorteile finden, wenn Sie eine gewisse Sicherheit implementieren müssen - so können einige Benutzer einige der Spalten (Tabelle1) sehen, andere jedoch nicht (Tabelle2).

Natürlich können Sie in einigen Datenbanken (Oracle) diese Art von Sicherheit in derselben Tabelle ausführen, in anderen jedoch möglicherweise nicht.


5

Sie beziehen sich auf die Datenbanknormalisierung. Ein Beispiel, an das ich in einer von mir verwalteten Anwendung denken kann, sind Elemente. Mit der Anwendung kann der Benutzer viele verschiedene Arten von Artikeln verkaufen (z. B. InventoryItems, NonInventoryItems, ServiceItems usw.). Während ich alle für jedes Element erforderlichen Felder in einer Elementtabelle speichern konnte, ist es viel einfacher, eine Basiselementtabelle zu verwalten, die Felder enthält, die allen Elementen gemeinsam sind, und dann separate Tabellen für jeden Elementtyp (z. B. Inventar, Nichtinventar,). etc ..), die Felder enthalten, die nur für diesen Elementtyp spezifisch sind. Dann hätte die Artikeltabelle einen Fremdschlüssel für den spezifischen Artikeltyp, den sie darstellt. Die Beziehung zwischen den spezifischen Elementtabellen und der Basiselementtabelle wäre eins zu eins.

Unten finden Sie einen Artikel zur Normalisierung.

http://support.microsoft.com/kb/283878


3

Wie bei allen Designfragen lautet die Antwort "es kommt darauf an".

Es gibt nur wenige Überlegungen:

  • Wie groß wird die Tabelle (sowohl in Bezug auf Felder als auch in Bezug auf Zeilen)? Es kann unpraktisch sein, den Namen und das Kennwort Ihres Benutzers sowohl aus Wartungs- als auch aus Programmiersicht mit anderen weniger häufig verwendeten Daten zu versehen

  • Felder in der kombinierten Tabelle mit Einschränkungen können im Laufe der Zeit umständlich zu verwalten sein. Wenn beispielsweise ein Trigger für ein bestimmtes Feld ausgelöst werden muss, geschieht dies bei jeder Aktualisierung der Tabelle, unabhängig davon, ob dieses Feld betroffen war.

  • Wie sicher sind Sie, dass die Beziehung 1: 1 sein wird? Wie diese Frage zeigt, können die Dinge schnell kompliziert werden.


3

Ein anderer Anwendungsfall kann folgender sein: Sie können Daten aus einer Quelle importieren und täglich aktualisieren, z. B. Informationen zu Büchern. Anschließend fügen Sie selbst Daten zu einigen Büchern hinzu. Dann ist es sinnvoll, die importierten Daten in einer anderen Tabelle als Ihren eigenen Daten abzulegen.


2

Normalerweise begegne ich in der Praxis zwei allgemeinen Arten von 1: 1-Beziehungen:

  1. IS-A-Beziehungen, auch als Supertyp / Subtyp-Beziehungen bezeichnet. Dies ist der Fall, wenn eine Art von Entität tatsächlich eine Art einer anderen Entität ist (EntityA IS A EntityB). Beispiele:

    • Personenentität mit separaten Entitäten für Buchhalter, Ingenieur, Verkäufer innerhalb desselben Unternehmens.
    • Elemententität mit separaten Entitäten für Widget, RawMaterial, FinishedGood usw.
    • Autoeinheit mit separaten Einheiten für LKW, Limousine usw.

    In all diesen Situationen hätte die Supertyp-Entität (z. B. Person, Gegenstand oder Auto) die Attribute, die allen Subtypen gemeinsam sind, und die Subtyp-Entitäten hätten Attribute, die für jeden Subtyp eindeutig sind. Der Primärschlüssel des Subtyps wäre der gleiche wie der des Supertyps.

  2. "Boss" -Beziehungen. Dies ist der Fall, wenn eine Person der eindeutige Chef oder Manager oder Vorgesetzte einer Organisationseinheit (Abteilung, Unternehmen usw.) ist. Wenn für eine Organisationseinheit nur ein Chef zulässig ist, besteht eine 1: 1-Beziehung zwischen der Personeneinheit, die den Chef repräsentiert, und der Organisationseinheit.


1
Ich mag das zweite Beispiel. Sie können die Entität "Abteilung" und die Entität "Mitarbeiter" haben. In einer Abteilung haben Sie viele Mitarbeiter, und ein Mitarbeiter kann nur in einer Abteilung arbeiten. Dies ist 1: n. Ein Mitarbeiter kann ein Vorgesetzter einer Abteilung sein - nur einer Abteilung, und die Abteilung hat nur einen Vorgesetzten. Sie erhalten also zwei Tabellen, die mit zwei Beziehungen verbunden sind - 1: n und 1: 1.
Cezar

2

Erstens denke ich, dass es darum geht, zu modellieren und zu definieren, was aus einer separaten Einheit besteht. Angenommen, Sie haben customersnur eine einzige address. Natürlich könnten Sie alles in einer einzigen Tabelle implementieren customer, aber wenn Sie ihm in Zukunft erlauben, zwei oder mehr Adressen zu haben, müssen Sie dies umgestalten (kein Problem, aber eine bewusste Entscheidung treffen).

Ich kann mir auch einen interessanten Fall vorstellen, der in anderen Antworten nicht erwähnt wurde und bei dem das Aufteilen der Tabelle nützlich sein könnte:

Stellen Sie sich wieder vor, Sie haben jeweils customerseine einzelne address, aber diesmal ist es optional, eine Adresse zu haben. Natürlich können Sie das als eine Reihe von NULL-able-Spalten implementieren, wie z ZIP,state,street. Angenommen, Sie haben eine Adresse, der Status ist nicht optional, die Postleitzahl jedoch. Wie modelliere ich das in einer einzigen Tabelle? Sie könnten eine Einschränkung für die customerTabelle verwenden, aber es ist viel einfacher, sie in eine andere Tabelle zu unterteilen und den Foreign_key NULLable zu machen. Auf diese Weise sagt Ihr Modell viel deutlicher, dass die Entität address optional ist und dass das ZIPein optionales Attribut dieser Entität ist.


0

In meiner Programmierzeit bin ich nur in einer Situation darauf gestoßen. In diesem Fall besteht eine 1-zu-Viele- und eine 1-zu-1-Beziehung zwischen denselben 2 Entitäten ("Entität A" und "Entität B").

Wenn "Entität A" mehrere "Entität B" und "Entität B" nur 1 hat, hat "Entität A" und "Entität A" nur 1 aktuelle "Entität B" und "Entität B" hat nur 1 "Entität A".

Zum Beispiel kann ein Auto nur einen aktuellen Fahrer haben, und der Fahrer kann jeweils nur ein Auto fahren - die Beziehung zwischen den Konzepten von Auto und Fahrer wäre also 1 zu 1. - Ich habe dieses Beispiel aus der Antwort von @Steve Fenton entlehnt

Wo ein Fahrer mehrere Autos fahren kann, nur nicht gleichzeitig. Die Entitäten Auto und Fahrer sind also 1 zu viele oder viele zu viele. Wenn wir jedoch wissen müssen, wer der aktuelle Fahrer ist, brauchen wir auch die 1: 1-Beziehung.


0

Ein anderer Anwendungsfall kann sein, wenn die maximale Anzahl von Spalten in der Datenbanktabelle überschritten wird. Dann können Sie mit OneToOne einer anderen Tabelle beitreten

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.