Comment créer correctement des clés primaires composites - MYSQL

182

Voici une simplification excessive d'une configuration intense avec laquelle je travaille. table_1et les table_2deux ont des clés primaires de substitution à incrémentation automatique comme ID. infoest une table qui contient des informations sur table_1et sur table_2.

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

J'essaie de décider si je devrais créer la clé primaire d' infoun composite des ID de table_1et table_2. Si je devais faire cela, lequel de ces éléments a le plus de sens?
(dans cet exemple, je combine l'ID 11209 avec l'ID 437)

INT(9)11209437 (je peux imaginer pourquoi c'est mauvais)
VARCHAR (10) 11209-437
DECIMAL (10,4)11209.437

Ou autre chose?

Serait-ce bien de l'utiliser comme clé primaire sur une base de données MYSQL MYISAM?

filip
la source
Copie

Réponses:

343

J'utiliserais une clé composite (multi-colonnes).

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

De cette façon, vous pouvez également avoir t1ID et t2ID comme clés étrangères pointant vers leurs tables respectives.

AlexCuse
la source
2
Oh wow, c'est ainsi que vous créez une clé composite! on dirait que j'ai totalement mal compris le concept. Je vous remercie!! Donc, quelque chose comme ça est entièrement à des fins d'indexation, alors correct? Comme dans je ne pourrais pas référencer un enregistrement en utilisant ce composite, je devrais quand même faire un UPDATE info ... WHERE t1ID=11209 AND t2ID=437?
filip
2
correct. Bien que puisque les deux colonnes doivent être uniques, où t1ID = 11209 serait probablement suffisant.
AlexCuse
39
@AlexCuse la combinaison des deux colonnes est unique, mais pour t1ID = 11209, il peut y avoir n'importe quel nombre de t2ID.
e18r
21

Je ne ferais pas de la clé primaire de la table "info" un composite des deux valeurs d'autres tables.

D'autres peuvent mieux articuler les raisons, mais il est faux d'avoir une colonne qui est vraiment composée de deux informations. Que faire si vous souhaitez trier l'ID de la deuxième table pour une raison quelconque? Que faire si vous souhaitez compter le nombre de fois qu'une valeur de l'une ou l'autre table est présente?

Je garderais toujours ces deux colonnes distinctes. Vous pouvez utiliser une clé primaire à deux colonnes dans mysql ... PRIMARY KEY (id_a, id_b) ... mais je préfère utiliser un index unique à deux colonnes et avoir un champ de clé primaire à incrémentation automatique.

wmorse
la source
1
Vous avez tout à fait raison de garder des colonnes distinctes. Je ne savais pas que vous pouviez avoir un index unique à deux colonnes et je pense que cela peut en fait être une bonne option pour moi. Puis-je vous demander pourquoi vous préféreriez toujours conserver la clé primaire en incrémentation automatique?
filip
3
Je n'ai pas de raisons vraiment convaincantes, et je reconnais que c'est un point de discorde entre moi et certains de mes collègues, car il est plus économique d'avoir moins de colonnes. Je trouve plus facile d'écrire des jointures sur une seule clé étrangère. Parfois, la signification de ces tables "Mappages entre deux tables" devient aussi importante que les tables d'origine, et sa clé primaire devient une colonne de clé étrangère dans d'autres tables encore.
wmorse
Merci. Je pense que ce que vous dites a beaucoup de sens et je vais l'essayer comme un index unique à deux colonnes + clé primaire à incrémentation automatique
filip
1
Je suppose qu'une raison venant du haut de ma tête est que vous voulez créer une table de relations. vous avez trois tables, disons marché, devise et fournisseur, un fournisseur ne peut exister qu'une seule fois sur une place de marché, donc votre table de relations ne peut fournir qu'une seule devise, donc vous composeriez (id_market, id_provider) ce qui signifie que vous ne pouvez faire cette connexion une fois, essayer d'ajouter à nouveau le même marché et le même fournisseur échouera, ce qui signifie qu'ils sont uniques, alors vous auriez une deuxième colonne, disons id_currency, ce qui signifie que la devise est singulière dans tout le tableau, est-ce que cela a du sens?
Christopher Thomas
1
Pour toute personne qui verra ce fil plus tard, veuillez noter que la raison pour laquelle il s'agit d'une mauvaise pratique est qu'elle viole un principe très basique de conception de base de données. La première forme normale exige que chaque élément d'information ait sa propre colonne. Il n'y a pratiquement aucune raison de violer cela et de multiples avantages à normaliser la structure de votre base de données.
smcjones
15

la syntaxe est CONSTRAINT constraint_name PRIMARY KEY(col1,col2,col3)par exemple:

CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)

l'exemple ci-dessus fonctionnera si vous l'écrivez pendant que vous créez la table par exemple:

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

pour ajouter cette contrainte à une table existante, vous devez suivre la syntaxe suivante

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

Supposons que vous ayez déjà créé une table, vous pouvez maintenant utiliser cette requête pour créer une clé primaire composite

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

Outre les préférences de conception personnelles, il existe des cas où l'on souhaite utiliser des clés primaires composites. Les tables peuvent avoir deux champs ou plus qui fournissent une combinaison unique, et pas nécessairement au moyen de clés étrangères.

À titre d'exemple, chaque État américain a un ensemble de districts du Congrès uniques. Alors que de nombreux états peuvent posséder individuellement un CD-5, il n'y en aura jamais plus d'un CD-5 dans l'un des 50 états, et vice versa. Par conséquent, la création d'un champ de numérotation automatique pour le Massachusetts CD-5 serait redondante.

Si la base de données gère une page Web dynamique, écrire du code à interroger sur une combinaison de deux champs peut être beaucoup plus simple que d'extraire / de resoumettre une clé numérotée automatiquement.

Donc, même si je ne réponds pas à la question initiale, j'apprécie certainement la réponse directe d'Adam.

KiloVoltaire
la source
4

Les clés primaires composites sont ce que vous voulez lorsque vous souhaitez créer une relation plusieurs à plusieurs avec une table de faits. Par exemple, vous pouvez avoir un forfait de location de vacances qui comprend un certain nombre de propriétés. D'autre part, la propriété pourrait également être disponible dans le cadre d'un certain nombre de forfaits de location, seule ou avec d'autres propriétés. Dans ce scénario, vous établissez la relation entre la propriété et le package de location avec une table de faits propriété / package. L'association entre une propriété et un package sera unique, vous ne joindrez jamais en utilisant property_id avec la table de propriétés et / ou package_id avec la table de package. Chaque relation est unique et une clé auto_increment est redondante car elle ne figurera dans aucune autre table. La réponse est donc la définition de la clé composite.

Adam Penny
la source
1
CREATE  TABLE `mom`.`sec_subsection` (

  `idsec_sub` INT(11) NOT NULL ,

  `idSubSections` INT(11) NOT NULL ,

  PRIMARY KEY (`idsec_sub`, `idSubSections`) 

);
Esprit maître
la source
1

@AlexCuse Je voulais ajouter ceci comme commentaire à votre réponse mais j'ai abandonné après plusieurs tentatives infructueuses pour ajouter des nouvelles lignes dans les commentaires.

Cela dit, t1ID est unique dans la table_1 mais cela ne le rend pas non plus unique dans la table INFO.

Par exemple:

Table_1 a:
Champ Id
1 A
2 B

Table_2 a:
Champ Id
1 X
2 Y

INFO peut alors avoir:
t1ID t2ID champ
1 1 certains
1 2 données
2 1 dans chaque ligne
2 2

Ainsi, dans la table INFO pour identifier de manière unique une ligne, vous avez besoin à la fois de t1ID et de t2ID

sactiw
la source
sa clé composite appelée
Pavel P
1
@PavelP ma réponse est le commentaire d'Alex "Bien que puisque les deux colonnes doivent être uniques, où t1ID = 11209 serait probablement suffisant." ... Je suis d'accord que l'utilisation de la clé composite est correcte, mais pour identifier la correspondance exacte, vous aurez besoin à la fois de t1ID et de t2ID ... J'espère que c'est clair maintenant.
sactiw