Question

J'ai appris lentement le SQL au cours des dernières semaines. J'ai relevé toute l'algèbre relationnelle et les bases du fonctionnement des bases de données relationnelles. Ce que j'essaie de faire maintenant, c’est d’apprendre comment elle est mise en œuvre.

Les clés étrangères de MySQL sont une pierre d'achoppement dans ce domaine. Il semble que je ne trouve pas grand-chose à propos de l’autre car ils existent dans le schéma de stockage InnoDB qui MySQL a.

Qu'est-ce qu'un exemple simple de clé étrangère implémentée dans MySQL?

Voici une partie d'un schéma que j'ai écrit qui ne semble pas fonctionner si vous préférez signaler mon défaut plutôt que de me montrer un exemple concret.

CREATE TABLE `posts` (
`pID` bigint(20) NOT NULL auto_increment,
`content` text NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`uID` bigint(20) NOT NULL,
`wikiptr` bigint(20) default NULL,
`cID` bigint(20) NOT NULL,
PRIMARY KEY  (`pID`),
Foreign Key(`cID`) references categories,
Foreign Key(`uID`) references users
) ENGINE=InnoDB;
Était-ce utile?

La solution

En supposant que votre table categories et users existe déjà et contient respectivement cID et uID en tant que clés primaires, cela devrait fonctionner:

CREATE TABLE `posts` (
`pID` bigint(20) NOT NULL auto_increment,
`content` text NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`uID` bigint(20) NOT NULL,
`wikiptr` bigint(20) default NULL,
`cID` bigint(20) NOT NULL,
PRIMARY KEY  (`pID`),
Foreign Key(`cID`) references categories(`cID`),
Foreign Key(`uID`) references users(`uID`)
) ENGINE=InnoDB;

Le nom de colonne est obligatoire dans la clause references .

Autres conseils

Modifié: Robert et Vinko déclarent que vous devez déclarer le nom de la colonne référencée dans la contrainte de clé étrangère. Ceci est nécessaire dans InnoDB, bien qu'en SQL standard, vous puissiez omettre le nom de la colonne référencée s'il s'agit du même nom dans la table parente.

Une des idiosyncrasie rencontrée dans MySQL est que la déclaration de clé étrangère échouera de manière silencieuse dans plusieurs circonstances:

  • Votre installation MySQL n'inclut pas le moteur innodb
  • Votre fichier de configuration MySQL n'active pas le moteur innodb
  • Vous ne déclarez pas votre table avec le modificateur de table ENGINE = InnoDB
  • La colonne de clé étrangère n'est pas exactement du même type de données que la colonne de clé primaire dans la table référencée

Malheureusement, MySQL ne signale pas qu’il n’a pas réussi à créer la contrainte de clé étrangère. Il ignore simplement la demande et crée la table sans la clé étrangère (si vous SHOW CREATE TABLE posts, vous ne verrez peut-être pas de déclaration de clé étrangère). J'ai toujours pensé que c'était une mauvaise fonctionnalité de MySQL!

Conseil: l'argument entier des types de données de type entier (par exemple, BIGINT (20)) n'est pas nécessaire. Cela n'a rien à voir avec la taille de stockage ou la plage de la colonne. BIGINT a toujours la même taille, quel que soit l'argument que vous lui donnez. Le nombre correspond au nombre de chiffres que MySQL complétera la colonne si vous utilisez le modificateur de colonne ZEROFILL.

Cela a quelques code indiquant comment créer des clés étrangères par eux-mêmes et dans CREATE TABLE.

Voici l'un des exemples les plus simples:

CREATE TABLE parent (
    id INT NOT NULL,
    PRIMARY KEY (id)
) ENGINE=INNODB;

CREATE TABLE child (
    id INT, 
    parent_id INT,
    INDEX par_ind (parent_id),
    FOREIGN KEY (parent_id) REFERENCES parent(id)
    ON DELETE CASCADE
) ENGINE=INNODB;

Je suis d'accord avec Robert. Il vous manque le nom de la colonne dans la clause references (et vous devriez recevoir l'erreur 150). J'ajouterai que vous pouvez vérifier comment les tables ont été créées en réalité avec:

SHOW CREATE TABLE posts;

Les réponses précédentes traitent de la contrainte de clé étrangère. Alors que la contrainte de clé étrangère est certainement utile pour maintenir l’intégrité référentielle, le concept de "clé étrangère" elle-même est fondamentale pour le modèle de données relationnel, que vous utilisiez la contrainte ou non.

Chaque fois que vous faites un équijoin , vous vous assimilez une clé étrangère à quelque chose, généralement la clé à laquelle elle fait référence. Exemple:

select *
from 
   Students
inner join
   StudentCourses
on Students.StudentId = StudentCourses.StudentId

StudentCourses.StudentId est une clé étrangère référençant Students.StudentId.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top