So erstellen Sie zusammengesetzte Primärschlüssel - MYSQL

181

Hier ist eine grobe Vereinfachung eines intensiven Setups, mit dem ich arbeite. table_1und table_2beide haben automatisch inkrementierte Ersatzprimärschlüssel als ID. infoist eine Tabelle, die Informationen zu table_1und enthält table_2.

table_1 (id, field)  
table_2 (id, field, field)
info ( ???, field)

Ich versuche zu entscheiden, ob ich den Primärschlüssel infoeiner Zusammenstellung der IDs aus table_1und erstellen soll table_2. Wenn ich das tun würde, welche davon ist am sinnvollsten?
(In diesem Beispiel kombiniere ich ID 11209 mit ID 437)

INT(9)11209437 (ich kann mir vorstellen, warum das schlecht ist)
VARCHAR (10) 11209-437
DECIMAL (10,4)11209.437

Oder etwas anderes?

Wäre es in Ordnung, dies als Primärschlüssel in einer MYSQL MYISAM-Datenbank zu verwenden?

Filip
quelle
Mögliches Duplikat des
mehrspaltigen

Antworten:

341

Ich würde einen zusammengesetzten (mehrspaltigen) Schlüssel verwenden.

CREATE TABLE INFO (
    t1ID INT,
    t2ID INT,
    PRIMARY KEY (t1ID, t2ID)
) 

Auf diese Weise können Sie t1ID und t2ID als Fremdschlüssel verwenden, die auch auf die jeweiligen Tabellen verweisen.

AlexCuse
quelle
2
Oh wow, so machst du einen zusammengesetzten Schlüssel! Es sieht so aus, als hätte ich das Konzept völlig missverstanden. Danke dir!! Also ist so etwas nur zu Indizierungszwecken dann richtig? Da ich mit diesem Composite nicht in der Lage wäre, auf einen Datensatz zu verweisen, müsste ich trotzdem einen UPDATE info ... WHERE t1ID=11209 AND t2ID=437?
Filip
2
richtig. Obwohl, da beide Spalten eindeutig sein sollten, wäre t1ID = 11209 wahrscheinlich ausreichend.
AlexCuse
39
@AlexCuse Die Kombination beider Spalten ist eindeutig, aber für t1ID = 11209 kann es eine beliebige Anzahl von t2IDs geben.
e18r
21

Ich würde den Primärschlüssel der "info" -Tabelle nicht aus den beiden Werten anderer Tabellen zusammensetzen.

Andere können die Gründe besser artikulieren, aber es fühlt sich falsch an, eine Spalte zu haben, die wirklich aus zwei Informationen besteht. Was ist, wenn Sie aus irgendeinem Grund die ID aus der zweiten Tabelle sortieren möchten? Was ist, wenn Sie zählen möchten, wie oft ein Wert aus einer der Tabellen vorhanden ist?

Ich würde diese immer als zwei verschiedene Spalten behalten. Sie könnten einen zweispaltigen Primay-Schlüssel in mysql verwenden ... PRIMARY KEY (id_a, id_b) ... aber ich bevorzuge die Verwendung eines zweispaltigen eindeutigen Index und ein automatisch inkrementiertes Primärschlüsselfeld.

wmorse
quelle
1
Sie haben absolut Recht, wenn Sie unterschiedliche Spalten beibehalten. Mir war nicht bewusst, dass Sie einen zweispaltigen eindeutigen Index haben könnten, und ich denke, dass dies tatsächlich eine gute Option für mich sein könnte. Könnte ich fragen, warum Sie es immer noch vorziehen, den Primärschlüssel als automatische Inkrementierung beizubehalten?
Filip
3
Ich habe keine wirklich zwingenden Gründe, und ich gebe zu, dass dies ein Streitpunkt zwischen mir und einigen meiner Kollegen ist, weil es wirtschaftlicher ist, weniger Spalten zu haben. Ich finde es einfacher, Joins auf einen einzelnen Fremdschlüssel zu schreiben. Manchmal wird die Bedeutung dieser Tabellen "Zuordnungen zwischen zwei Tabellen" genauso wichtig wie die ursprünglichen Tabellen, und ihr Primärschlüssel wird zu einer Fremdschlüsselspalte in noch anderen Tabellen.
wmorse
Danke. Ich denke, was Ihr Sprichwort viel Sinn macht und ich werde es als zweispaltigen eindeutigen Index + Auto-Inkrement-Primärschlüssel versuchen
Filip
1
Ich denke, ein Grund von oben ist, dass Sie eine Beziehungstabelle erstellen möchten. Sie haben drei Tabellen, z. B. Marktplatz, Währung und Anbieter. Ein Anbieter kann NUR EINMAL auf einem Marktplatz existieren, sodass Ihre Beziehungstabelle nur eine einzige Währung bereitstellen kann. Sie würden also zusammensetzen (id_market, id_provider), was bedeutet, dass Sie nur machen können Wenn diese Verbindung einmal versucht wird, denselben Markt und denselben Anbieter erneut zusammenzufügen, schlägt dies fehl, was bedeutet, dass sie eindeutig sind. Dann haben Sie eine zweite Spalte, z. B. id_currency, dh die Währung ist in der gesamten Tabelle singulär. Ist das sinnvoll?
Christopher Thomas
1
Wenn Sie diesen Thread später sehen, beachten Sie bitte, dass dies eine schlechte Praxis ist, weil er gegen ein sehr grundlegendes Prinzip des Datenbankdesigns verstößt. Die 1. Normalform erfordert, dass jede Information eine eigene Spalte hat. Es gibt praktisch keinen Grund, dies und mehrere Vorteile bei der Normalisierung Ihrer Datenbankstruktur zu verletzen.
Smcjones
15

Die Syntax lautet CONSTRAINT constraint_name PRIMARY KEY(col1,col2,col3)zum Beispiel ::

CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)

Das obige Beispiel funktioniert, wenn Sie es schreiben, während Sie die Tabelle erstellen, zum Beispiel ::

CREATE TABLE person (
   P_Id int ,
   ............,
   ............,
   CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
);

Um diese Einschränkung zu einer vorhandenen Tabelle hinzuzufügen, müssen Sie die folgende Syntax befolgen

ALTER TABLE table_name ADD CONSTRAINT constraint_name PRIMARY KEY (P_Id,LastName)
Ritabrata Gautam
quelle
8

Angenommen, Sie haben bereits eine Tabelle erstellt. Mit dieser Abfrage können Sie einen zusammengesetzten Primärschlüssel erstellen

alter table employee add primary key(emp_id,emp_name);
Usman Yaqoob
quelle
5

Abgesehen von persönlichen Designpräferenzen gibt es Fälle, in denen zusammengesetzte Primärschlüssel verwendet werden sollen. Tabellen können zwei oder mehr Felder enthalten, die eine eindeutige Kombination bieten, und zwar nicht unbedingt über Fremdschlüssel.

Beispielsweise hat jeder US-Bundesstaat eine Reihe einzigartiger Kongressbezirke. Während viele Staaten einzeln eine CD-5 haben können, wird es in keinem der 50 Staaten mehr als eine CD-5 geben und umgekehrt. Daher wäre das Erstellen eines Felds für die automatische Nummerierung für Massachusetts CD-5 überflüssig.

Wenn die Datenbank eine dynamische Webseite steuert, kann das Schreiben von Code zum Abfragen in einer Kombination aus zwei Feldern viel einfacher sein als das Extrahieren / erneutes Senden eines automatisch nummerierten Schlüssels.

Obwohl ich die ursprüngliche Frage nicht beantworte, schätze ich Adams direkte Antwort auf jeden Fall.

KiloVoltaire
quelle
4

Zusammengesetzte Primärschlüssel sind das, was Sie möchten, wenn Sie eine Viele-zu-Viele-Beziehung zu einer Faktentabelle erstellen möchten. Beispielsweise könnten Sie ein Ferienpaket haben, das eine Reihe von Immobilien enthält. Andererseits könnte die Immobilie auch als Teil einer Reihe von Mietpaketen entweder allein oder mit anderen Immobilien verfügbar sein. In diesem Szenario stellen Sie die Beziehung zwischen der Immobilie und dem Mietpaket mit einer Faktentabelle für Immobilien / Pakete her. Die Zuordnung zwischen einer Eigenschaft und einem Paket ist eindeutig. Sie werden immer nur mit property_id mit der Eigenschaftentabelle und / oder package_id mit der Pakettabelle verbunden. Jede Beziehung ist eindeutig und ein auto_increment-Schlüssel ist redundant, da er in keiner anderen Tabelle enthalten ist. Daher ist die Definition des zusammengesetzten Schlüssels die Antwort.

Adam Penny
quelle
1
CREATE  TABLE `mom`.`sec_subsection` (

  `idsec_sub` INT(11) NOT NULL ,

  `idSubSections` INT(11) NOT NULL ,

  PRIMARY KEY (`idsec_sub`, `idSubSections`) 

);
Master Mind
quelle
1

@AlexCuse Ich wollte dies als Kommentar zu Ihrer Antwort hinzufügen, gab aber nach mehreren fehlgeschlagenen Versuchen auf, Zeilenumbrüche in Kommentare einzufügen.

Das heißt, t1ID ist in Tabelle_1 eindeutig, aber das macht es auch nicht in der INFO-Tabelle eindeutig.

Beispielsweise:

Tabelle_1 hat: ID-
Feld
1 A
2 B.

Tabelle_2 hat: ID-
Feld
1 X
2 Y.

INFO kann dann haben:
t1ID t2ID Feld
1 1 einige
1 2 Daten
2 1 in jeder
2 2 Zeile

In der INFO-Tabelle benötigen Sie also sowohl t1ID als auch t2ID, um eine Zeile eindeutig zu identifizieren

sactiw
quelle
Es heißt zusammengesetzter Schlüssel
Pavel P
1
@PavelP Meine Antwort ist auf Alex 'Kommentar "Obwohl beide Spalten eindeutig sein sollten, wäre t1ID = 11209 wahrscheinlich ausreichend." ... Ich stimme zu, dass die Verwendung des zusammengesetzten Schlüssels korrekt ist, aber um die genaue Übereinstimmung zu ermitteln, benötigen Sie sowohl t1ID als auch t2ID ... Ich hoffe, es ist jetzt klar.
Sactiw