In meinem aktuellen Datenbankdesign wird ein Primärschlüssel mit mehreren Spalten verwendet, um vorhandene Daten zu verwenden (die ohnehin eindeutig wären), anstatt eine zusätzliche Spalte zu erstellen, die jedem Eintrag einen beliebigen Schlüssel zuweist. Ich weiß, dass dies zulässig ist, habe mich aber gefragt, ob dies eine Übung ist, die ich vorsichtig anwenden und möglicherweise vermeiden möchte (ähnlich wie bei goto in C).
Was sind also einige der Nachteile, die ich bei diesem Ansatz sehen könnte, oder Gründe, warum ich einen einspaltigen Schlüssel haben möchte?
database-design
Covar
quelle
quelle
Antworten:
Wenn Sie eine Tabelle mit einem mehrspaltigen Primärschlüssel haben, ist dies in der Regel das Ergebnis einer Join-Tabelle (viele zu viele), die zu einer eigenen Entität heraufgestuft wurde (und daher ihren eigenen Primärschlüssel verdient). Es gibt viele, die argumentieren, dass eine Join-Tabelle standardmäßig eine Entität sein sollte, aber das ist eine Diskussion für einen anderen Tag.
Betrachten wir eine hypothetische Beziehung von vielen zu vielen:
Student * --- * Klasse
(Ein Schüler kann in mehreren Klassen sein, eine Klasse kann mehrere Schüler haben).
Zwischen diesen beiden Tabellen befindet sich eine Junction-Tabelle mit dem Namen StudentClass (oder ClassStudent, je nachdem, wie Sie sie schreiben). Manchmal möchten Sie Dinge nachverfolgen, wie wenn der Schüler in der Klasse war. So fügen Sie es der StudentClass-Tabelle hinzu. Zu diesem Zeitpunkt ist StudentClass zu einer einzigartigen Entität geworden ... und sollte einen Namen erhalten, um sie als solche zu erkennen, z. B. Einschreibung.
Schüler 1 --- * Einschreibung * --- 1 Klasse
(Ein Schüler kann viele Einschreibungen haben, jede Einschreibung ist für eine Klasse (oder umgekehrt, eine Klasse kann viele Einschreibungen haben, jede Einschreibung ist für einen Schüler).
Nun können Sie beispielsweise abfragen, wie viele Schüler im vergangenen Jahr in der Klasse Chemie 101 eingeschrieben waren. Oder in welchen Klassen war der Student John Doe während seines Studiums an der Acme University eingeschrieben? Dies war ohne den separaten Primärschlüssel möglich. Wenn Sie jedoch einen Primärschlüssel für die Anmeldung haben, können Sie diese Anmeldungen (nach ID) einfacher abfragen. Wie viele Schüler haben eine bestandene Note erhalten?
Die Entscheidung, ob eine Entität eine PK verdient, hängt davon ab, wie viel Abfragen (oder Manipulationen) Sie für diese Entität ausführen. Nehmen wir zum Beispiel an, Sie wollten die Aufgaben anhängen, die für einen Schüler in einer Klasse erledigt wurden. Der logische Ort zum Anhängen dieser Entität (Zuweisung) befindet sich in der Registrierungsentität. Wenn Sie der Registrierung einen eigenen Primärschlüssel geben, werden die Zuweisungsabfragen einfacher.
quelle
Es ist sinnvoll, eine separate ID-Spalte zu haben. Wenn Sie etwas aus Ihrer Datenbanktabelle abrufen möchten, ist dies einfacher:
als SELECT was auch immer FROM-Tabelle WHERE col1 = 'val1' AND col2 = 'val2' AND col3 = 'val3'
In einer Webanwendung bedeutet dies beispielsweise, dass die URL folgendermaßen aussieht:
oder so:
quelle
SELECT
Abfragen kommen. Und, B) , ich habe keine Ahnung, wie dies tatsächlich irgendeine Art von URL-Anforderung verursacht (es sei denn, Sie arbeiten mit einem schlechten Framework). Meine URLs enthalten keine Abfragezeichenfolgen?id=13
, geschweige denn?col1=val1&col2=val2&col3=val3
.Grundsätzlich werden Sie gefragt, ob Sie Ersatz- oder natürliche Schlüssel verwenden sollen (in Ihrem Fall klingt dies nach zusammengesetzten natürlichen Schlüsseln). Hier ist ein großartiger Artikel: http://www.agiledata.org/essays/keys.html
Ich bevorzuge Ersatzschlüssel, weil sie die Verwaltung über die gesamte Lebensdauer der Datenbank vereinfachen (Sie müssen sich keine Gedanken darüber machen, wie sich die Bedeutung von Schlüsseln ändert, was in keinem realen System, in dem Menschen involviert sind, passieren sollte). Allerdings , wenn es eine Menge von „Lookup“ Tabellen in der DB ist (dh Tabellen , die im Grunde sind die Schlüssel: Wert - Paare), dann kann Ersatzschlüssel erhält umständlich , weil man diese Tabellen in die Abfrage verbinden , um muß aussagekräftige Ergebnisse zu erhalten.
Angenommen, Sie haben zwei Entitäten: Adresse und Land.
select * from Address where CountryCode = 'US'
select Address.* from Address join Country on Address.CountryID = Country.ID where Country.Code = 'US'
Ich gebe gerne natürliche Schlüssel für Nachschlagetabellen und Ersatzschlüssel für alles andere an, wenn ich mir ziemlich sicher bin, dass sich die natürlichen Schlüssel nicht allzu oft ändern, wenn überhaupt.
quelle
Es hängt davon ab, wie Sie auf die Daten zugreifen. Wenn Sie häufig nach Teilschlüsseln suchen (wobei Sie Datensätze beispielsweise nur anhand von zwei der drei Schlüssel auswählen), sollten Sie die mehrteiligen Schlüssel beibehalten. OTOH, wenn Sie viele 1: 1-Beziehungen zu anderen Tabellen haben, ist es wahrscheinlich sinnvoller, einen Ersatzschlüssel zu haben.
quelle
Ich möchte immer einen Ersatzprimärschlüssel für jede Tabelle haben. Aber es gibt nicht viele "harte" Gründe, dies durchzusetzen, die ich gehört habe.
Das einzige Mal, dass ich jemals einen mehrspaltigen natürlichen Schlüsselbiss hatte, war mit ORM. Gelegentlich hatte ich Probleme mit einem mehrspaltigen Primärschlüssel, der Linq To Entities verwendet.
quelle
Sag niemals nie, aber es ist schmerzhaft, an 4 Säulen teilzunehmen. Je mehr Spalten mit intelligenten Daten vorhanden sind, desto größer ist die Wahrscheinlichkeit, dass sich diese Werte ändern. Datenbanken können so eingerichtet werden, dass die referenzielle Integrität bei kaskadierenden Updates erhalten bleibt.
Sie können jederzeit einen anderen Index erstellen, um die eindeutigen Werte zu verarbeiten.
Die Leistung ist in den meisten Fällen wahrscheinlich vernachlässigbar, aber Sie können Ihre Abfragen mit und ohne Ersatzschlüssel testen.
quelle
Ich finde es schwierig, einen guten Grund zu finden, einen separaten Schlüssel zu vergeben, aber wie Sie sagten, haben viele Leute ihn eingegeben.
Ich finde das nicht hilfreich (besonders beim Speichern), wenn ich mit Fakten- / Detailtabellen arbeite. Ein kanonisches Beispiel für eine Verkaufsfaktentabelle mit einem (customer_key, store_key, product_key) mit Menge ist nicht sehr sinnvoll, um einen Schlüssel auf Datensatzebene zu haben.
quelle
Wenn Sie feststellen, dass Ihr zusammengesetzter Schlüssel tatsächlich Duplikate haben kann, ist es einfacher, wenn PK ein Autoincrement Int ist.
quelle
Auf Ask Tom gibt es eine gute Diskussion, die bis ins Jahr 2002 zurückreicht . Es ist Oracle-spezifisch, aber die breitere Diskussion ist relevant, egal welche Datenbank Sie verwenden.
quelle