2 Stimmen

Datenbankdesign mit Fremdschlüsseln Frage

Ich versuche, Fremdschlüssel richtig zu verwenden, um die Datenintegrität zu wahren. Ich bin nicht wirklich ein Datenbanktyp, also frage ich mich, ob es ein allgemeines Designprinzip gibt, das ich nicht kenne. Hier ist ein Beispiel für das, was ich zu tun versuche:

Angenommen, Sie möchten eine Fahrzeugdatenbank mit Typ (Pkw, Lkw usw.), Marke und Modell erstellen. Ein Benutzer muss zumindest den Typ eingeben, aber die Marke und das Modell sind optional (wenn das Modell angegeben wird, ist die Marke erforderlich). Meine erste Idee ist, die Datenbank als solche einzurichten:

Type:
-id (PK)
-description

Make:
-id (PK)
-type_id (FK references Type:id)
-description

Model:
-id (PK)
-make_id (FK references Make:id)
-description

Vechicle:
-id (PK)
-type_id (FK references Type:id)
-make_id (FK references Make:id)
-model_id (FK references Model:id)

Wie würden Sie die FKs für Fahrzeuge einrichten, um sicherzustellen, dass Typ, Marke und Modell übereinstimmen? Wie würden Sie zum Beispiel verhindern, dass ein Fahrzeug (Typ:Motorrad, Marke:Ford, Modell:Civic) hat? Jede dieser FKs wäre gültig, aber sie halten nicht die Beziehungen aufrecht, die durch die FKs der anderen Tabellen gezeigt werden.

Auch, weil Modell nicht erforderlich ist, kann ich nicht nur speichern die model_id FK und arbeiten rückwärts von ihm.

Ich bin überhaupt nicht an das Datenbankdesign gebunden, also bin ich offen für die Möglichkeit, die Art und Weise, wie die Tabellen eingerichtet sind, zu ändern. Irgendwelche Ideen?

P.S. - Ich benutze mysql, wenn jemand interessiert ist, aber dies ist eher eine allgemeine Frage über Datenbanken.

Bearbeiten (Klarstellungen):

-type_id und make_id werden in der Fahrzeugtabelle benötigt, es sei denn, es gibt eine Möglichkeit, diese für den Fall herauszufinden, dass model_id null ist;

-Die Beziehungen zwischen type_id, make_id und model_id müssen beibehalten werden.

2voto

cletus Punkte 596503

Zum Beispiel so:

Art:

  • id (PK)
  • Beschreibung

Marke:

  • id (PK)
  • type_id (FK-Referenzen Type:id, nicht null)
  • Beschreibung

Modell:

  • id (PK)
  • make_id (FK-Referenzen Make:id, nicht null)
  • Beschreibung

Fahrzeug:

  • id (PK)
  • model_id (FK-Referenzen Model:id)

Grundsätzlich sollten Sie auch Marke und Typ des Fahrzeugs nicht doppelt angeben. Sie werden sonst Probleme bekommen, wenn Sie das tun. Sie können die Marke und den Typ aus dem Modell des Fahrzeugs abrufen (falls definiert). Modell muss Marke haben. Marke muss Typ haben.

Denken Sie einmal darüber nach: Wenn ein Fahrzeug ein bestimmtes Modell hat, Fahrzeug und Modell aber beide eine Marke haben, können diese Werte unterschiedlich sein. Diese Art von Inkonsistenz kann aufgrund von Informationsredundanz entstehen. Das wollen Sie generell vermeiden.

Wenn Sie die Marke und den Typ eines Fahrzeugs herausfinden müssen, sieht die SQL folgendermaßen aus:

SELECT v.id, v.model_id, m.make_id, k.type_id
FROM vehicle v
LEFT JOIN model m ON v.model_id = m.id
JOIN make k ON m.make_id = k.id
JOIN type t ON k.type_id = t.id

Und so weiter.

2voto

Jim Mitchener Punkte 8595

Was Sie suchen, ist eine CHECK-Beschränkung. Leider unterstützt MySQL dies derzeit nicht. Sie könnten eine solche Funktionalität mit Triggern emulieren, aber Sie müssten sowohl einen INSERT- als auch einen UPDATE-Trigger erstellen, damit es funktioniert.

Wie jedoch bereits in anderen Antworten erwähnt, sollten Sie eigentlich nur das Fahrzeugmodell speichern. In Ihrer Anwendung sollten Sie bis zum Typ aufschlüsseln, wenn dieser verfügbar ist.

1voto

Damir Sudarevic Punkte 21527

Hier ist ein Ansatz:

- Eine machen. (Ford, GM, Honda) können viele Modelle ein Modell gehört nur zu einer Marke.
- Modell ist von einer bestimmten Typ (Auto, Lkw, Fahrrad).
- Fahrzeug ist von einer gewissen Modell . Eine Fahrzeug kann nur einer der folgenden sein Modell Es kann viele Fahrzeuge eines Modells geben.

Die Tabelle "Modell" enthält Spalten, die allen Modellen gemeinsam sind, während "Pkw", "Lkw" und "Motorrad" jeweils eigene Spalten haben.

Wenn Sie eine DB modellieren, sollten Sie Daten, Entitäten und Beziehungen in Betracht ziehen; fangen Sie nicht mit der Benutzeroberfläche an - es gibt eine Geschäftsschicht dazwischen, die die Dinge regelt. Es ist in Ordnung, MySQL zu verwenden, Sie können Prüf- und Fremdschlüssel-Beschränkungen in Ihrer Anwendungsschicht erzwingen.

vehicle_model_01

0voto

Patrick Burleson Punkte 388

Ihr Entwurf ist gut für die Datenintegrität, es wird die Aufgabe Ihrer Anwendung sein, zu gewährleisten, dass ein Fahrzeug aus Marken eines bestimmten Typs und Modellen einer bestimmten Marke besteht.

Wenn Sie die Integrität von Fahrzeugtyp/Fabrikat/Modell in der Datenbank aufrechterhalten wollen, können Sie eine Prüfbeschränkung zu Ihrer Fahrzeugtabelle hinzufügen, die sicherstellt, dass die Typkennung des Fahrzeugs der Marke mit der angegebenen Typkennung übereinstimmt. Und wenn die Modell-ID nicht null ist, stellen Sie sicher, dass die Marken-ID mit der angegebenen Marken-ID übereinstimmt.

-1voto

C. A. McCann Punkte 76279

Wie ich sehe, haben Sie bereits eine Antwort akzeptiert, aber ein alternativer Ansatz, der Ihre aktuell strukturelles Problem und verwendet keine Trigger oder Check Constraints wäre, Dummy-Einträge in den Tabellen Make und Model mit einer Beschreibung von "n/a" oder so zu erstellen, einen für jeden Eintrag in Type bzw. Make, und dann die redundanten Spalten in Vehicle loszuwerden.

Wenn Sie also nur den Typ eines Fahrzeugs kennen, finden Sie den Dummy-Eintrag in Marke, der auf den entsprechenden Typ verweist, dann den Dummy-Eintrag in Modell, der auf diese Marke verweist, und dann den Verweis auf dieses Modell in der neuen Zeile in Fahrzeug.

Der größte Nachteil wäre natürlich die zusätzliche Arbeit zur Erstellung der Dummy-Zeilen, entweder im Voraus, wenn ein Typ oder eine Marke hinzugefügt wird, oder bei Bedarf, wenn ein Fahrzeug mit fehlenden Daten hinzugefügt 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