Einfaches Beispiel: Es gibt eine Kundentabelle.
create table Customers (
id integer,
constraint CustomersPK primary key (id)
)
Alle anderen Daten in der Datenbank sollten mit a verknüpft sein Customer
, Orders
sieht also z. B. so aus:
create table Orders (
id integer,
customer integer,
constraint OrdersPK primary key (customer, id),
constraint OrdersFKCustomers foreign key (customer) references Customers (id)
)
Angenommen, es gibt jetzt eine Tabelle, die auf Folgendes verweist Orders
:
create table Items (
id integer,
customer integer,
order integer,
constraint ItemsPK primary key (customer, id),
constraint ItemsFKOrders foreign key (customer, order) references Orders (customer, id)
)
Soll ich einen separaten Fremdschlüssel von Items
bis hinzufügen Customers
?
...
constraint ItemsFKCustomers foreign key (customer) references Customers (id)
Stattdessen ein Bild: Soll ich die gestrichelte Linie / FK hinzufügen?
Bearbeiten: Ich habe den Tabellen Primärschlüsseldefinitionen hinzugefügt. Ich möchte noch einmal auf den Punkt eingehen, den ich oben angesprochen habe: Die Datenbank wird im Grunde genommen von Kunden als Korrektheits- / Sicherheitsmaßnahme isoliert. Daher enthalten alle Primärschlüssel die customer
ID.
database-design
foreign-key
vektor
quelle
quelle
Antworten:
Ich denke, das ist die ursprüngliche Idee.
Als Erstes müssen Sie feststellen, dass die PK in der LineItem-Tabelle drei Attribute hat
{CustomerID, CustomerOrderNo, OdrerItemNo}
, im Gegensatz zu nur zwei in Ihrem Beispiel.Als zweites ist die Verwirrung zu beachten, die sich aus der Verwendung des generischen
id
Namens für ein Attribut ergibt .Das
CustomerOrderNo
sollte idealerweise (1,2,3 ..) für jeden Kunden undOrderItemNo
(1,2,3 ...) für jede Bestellung sein.Nun, das ist nett, wenn möglich, erfordert aber eine Abfrage, die nach dem vorherigen Maximalwert sucht, wie z
Dies wird in Umgebungen mit hohem Transaktionsvolumen häufig nicht bevorzugt. Daher werden diese häufig durch ein automatisches Inkrement ersetzt, das im Wesentlichen demselben Zweck dient. Es ist wahr, dass dieses Auto-Inkremet jetzt einzigartig ist, daher kann es als SCHLÜSSEL verwendet werden - aber Sie können es als notwendigen Kompromiss für das betrachten
OrderItemNo
.Mit etwas Umbenennung
CustomerOrderNo -> OrderNo
undOrderItemNo
-> könnenItemNo
Sie zu diesem Modell gelangenWenn Sie sich nun
Order
Folgendes ansehen, sind die folgenden einzigartigBeachten Sie, dass dies
{CustomerID, OrderNo}
an die weitergegeben wirdLineItem
, um als FK zu dienen.Wenn Sie ein wenig blinzeln, ist dies in der Nähe Ihres Beispiels, jedoch
PKs {ItemNo} and {OrderNo}
nur mit - im Gegensatz zu zwei Spalten-PKs aus Ihrem Beispiel.Die Frage ist nun, warum nicht zu so etwas vereinfachen?
Welches ist in Ordnung, aber einleitet Wegabhängigkeit - Sie nicht teilnehmen können
LineItem
mitCustomer
direkt müssen, verwenden SieOrder
in der Verknüpfung.Ich bevorzuge den ersten Fall, wenn möglich - Sie wählen Ihren Favoriten. In diesen drei Fällen ist natürlich keine direkte FK von
LineItem
bis erforderlichCustomer
.quelle
Der "Artikel" sollte nicht direkt auf den "Kunden" verweisen, da dies durch die "Bestellung" des Artikels impliziert wird. Sie benötigen also überhaupt nicht die Spalten "Kunde" in der Tabelle "Artikel".
Die Beziehung des Artikels zum Kunden wird mit dem vorhandenen Fremdschlüssel sichergestellt.
Wenn orders.id eine Identitätsspalte ist, sollten Sie items.customer insgesamt entfernen.
quelle
customer
vermute, dass es ein ungewöhnlicher Ansatz ist , alle Tabellen zu haben (und damit die DB zu silieren). Ich muss gestehen, dass es nur etwas ist, was ich in meiner vorherigen Arbeit gesehen habe. Macht es für dich Sinn? Haben Sie so ein Design schon einmal gesehen?