Comment utiliser les clés étrangères avec PHP
Donc, je comprends comment créer des clés étrangères, et je sais quel est le but de la FK. Mais j'ai un problème dans la compréhension de la Façon de les utiliser. J'ai posé une question concernant les clés Étrangères ICI(Cliquez sur le lien)
Voici ce que j'ai fait:
CREATE TABLE user(
id INT(11) NOT NULL AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
password VARCHAR(20) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE items(
i_id INT(11) NOT NULL AUTO_INCREMENT,
name TINYTEXT NOT NULL,
price DECIMAL(8,2) NOT NULL,
PRIMARY KEY (i_id)
);
CREATE TABLE user_purchase(
i_id INT(11) NOT NULL,
name TINYTEXT NOT NULL,
id INT(11) NOT NULL,
FOREIGN KEY (i_id) REFERENCES items(i_id),
FOREIGN KEY (name) REFERENCES items(name),
FOREIGN KEY (id) REFERENCES user(id)
);
Maintenant, ma question est comment puis-je tirer le meilleur parti de cette aide de PHP? À partir du lien ci-dessus, les gens ont suggéré qu'il est bon d'utiliser une seule clé étrangère dans la user_purchase table, mais si je veux plusieurs colonnes? Pourquoi ne pas utiliser plusieurs clés étrangères dans les différentes colonnes de la même table?
Je suis de l'utilisation de mysql et php. Je vous serais reconnaissant si vous pouviez montrer quelques exemples de la façon dont vous utilisez PHP avec des tables qui ont des clés étrangères pour obtenir les informations en utilisant les commandes MYSQL. J'ai vraiment besoin d'une explication approfondie.
J'ai aussi besoin de comprendre les conditions de la Normalisation et de la Dénormalisation. Je vous serais reconnaissant si vous pouviez donner quelques liens qui expliquent ces termes dans le détail avec des exemples ou si vous avez des suggestion pour certains de grands livres pour les débutants dans la conception de base de données, mise en œuvre, etc, je voudrais vraiment l'apprécier.
Merci beaucoup.
Je sais que c'est indépendant du langage de programmation, mais comme vous le dites, je n'ai pas besoin de créer une clé sur les éléments(nom). Disons que je veux extraire le i_id, l'id et le nom et les afficher sur ma page à l'aide de PHP, j'ai besoin de la clé étrangère ou alors il n'a pas d'importance?
"Pourquoi ne pas utiliser plusieurs clés étrangères dans les différentes colonnes de la même table?": Pourquoi devrions-nous? Comment est-ce justifié?
OriginalL'auteur Please Delete me | 2013-11-03
Vous devez vous connecter pour publier un commentaire.
Les colonnes de clé étrangère/les contraintes de désambiguïsation
En supposant que vous faites référence à les contraintes de clé étrangère, la réponse courte serait vous suffit de ne pas les utiliser.
Et voici la longue:
Nous sommes habitués à se référer à colonnes de clés étrangères à d'autres tables. En particulier pendant le processus de normalisation, des phrases comme "
user_purchase.i_id
est une clé étrangère vers laitems
table" serait très commun. Alors que c'est un bon moyen de décrire la relation, il peut obtenir un peu floue quand on arrive à la phase de mise en œuvre.Supposons que vous avez créé vos tables sans la
FOREIGN KEY
clauses:Avis que, la relation, la clé étrangère colonnes sont encore mis en œuvre. Il y a une colonne qui fait référence à la
user
table (id
) et un autre qui fait référence à laitems
table (i_id
) -- mettons laname
colonne de côté pour un moment. Considérons les données suivantes:La relation est là. Il est mis en œuvre par le biais de la
user_purchase
table, qui contient les informations de qui a acheté quoi. Si nous étions à la requête de la base de données pour un rapport sur la question, nous voudrions faire:Et comment nous pouvons utiliser la relation et la clé étrangère colonnes impliqués.
Maintenant, si nous faisons:
Apparemment, c'est une entrée non valide. Bien qu'il y a un utilisateur avec
id=23
, il n'y a pas d'élément aveci_id=99
. Le SGBDR serait de permettre que cela se produise, parce que il ne savent pas mieux. Encore.C'est là la clé étrangère contraintes entrent en jeu. En spécifiant
FOREIGN KEY (i_id) REFERENCES items(i_id)
dans leuser_purchase
définition de la table, nous avons essentiellement donner le SGBDR une règle à suivre: entrées aveci_id
valeurs qui ne sont pas contenues dans leitems.i_id
colonne ne sont pas acceptables. En d'autres termes, alors qu'une clé étrangère colonne met en œuvre la référence, une clé étrangère contrainte applique la l'intégrité référentielle.Noter, cependant, que le ci-dessus
select
ne change pas, juste parce que vous avez défini un FK contrainte. Ainsi, vous n'utilisez pas de contraintes FK, le SGBDR n', afin de protéger vos données.Licenciements
Demandez-vous: Pourquoi voudriez-vous que? Si les deux clés étrangères sont de servir le même but, la redondance finira par obtenir en difficulté. Considérons les données suivantes:
Quel est le problème avec cette image? N'utilisateur
55
acheter deux barres de chocolat, ou une barre de chocolat et une pâte dentifrice? Ce type d'ambiguïté peuvent conduire à beaucoup d'efforts pour conserver les données de synchronisation, ce qui serait inutile si nous avons juste gardé l'une des clés étrangères. En fait, pourquoi ne pas abandonner lename
colonne au total, depuis il est sous-entendu par la relation.Bien sûr, on pourrait résoudre ce par la mise en œuvre d'un composite de clé étrangère, par la mise en
PRIMARY KEY(i_id,name)
pour laitems
table (ou de la définition d'un extraUNIQUE(i_id,name)
indice, il n'a pas vraiment d'importance) et de définir ensuite unFOREIGN KEY(i_id,name) REFERENCES items(i_id,name)
. De cette façon, seulement (i_id,nom) les couples qui existent dans leitems
tableau serait valable pouruser_purchases
. Outre le fait que vous auriez encore un clé étrangère, cette approche est totalement inutile, à condition que lei_id
colonne est déjà suffisant pour identifier un élément (ne peut pas en dire de même pour lename
colonne...).Cependant, il n'y a pas de règle contre l'utilisation de plusieurs clés étrangères de la table. En fait, il existe des circonstances de la demande d'une telle approche. Considérons un
person(id,name)
table et unparent(person,father,mother)
, avec les données suivantes:Évidemment, tous les trois colonnes de la
parent
tableau sont des clés étrangèresperson
. Pas la même relation, si, mais pour trois différents: Depuis les parents de la personne sont des personnes trop, les deux colonnes correspondantes doivent faire référence à la même tableperson
. Notez, cependant, que les trois champs non seulement peut mais aussi ont pour consulter les différentsperson
s dans la mêmeparent
ligne, puisque personne n'est son propre parent et la personne du père, c'est sa mère.OriginalL'auteur geomagas
Les clés étrangères sont utilisés dans les jointures. Par exemple, si vous voulez savoir les noms d'utilisateurs qui ont acheté un article en particulier, vous écrivez:
Ils peuvent également être utilisés par le moteur de base de données elle-même. Il peut détecter si vous créez une ligne de
user_purchase
dontid
oui_id
colonne ne correspond à rien dans la colonne référencée dans l'autre table.Vous devriez pas reproduire le
name
colonne dans lauser_purchase
table. Lename
est juste un attribut de laitem
, ce n'est pas spécifique à un achat spécifique. Si vous avez besoin pour obtenir le nom de l'élément que vous avez acheté, vous joindre à laitems
table.Eh bien, ils décrivent la relation entre les tables, et vous n'auriez pas des tables avec des relations si vous n'avez pas besoin de se joindre à eux. C'est en ce sens seulement je pouvais faire de la question de savoir comment vous "utilisez" a FK.
Vrai. Et j'ai, moi-même, peut comprendre le sens de vos paroles. Mais encore, une jointure n'est pas utilisation FKs par dire, simplement colonnes qui peuvent ou peuvent ne pas avoir les clefs étrangères appliquées. Il est naturel pour créer FKs sur les données connexes, mais malheureusement pas tout le monde qui s'en occupe. Otoh, que, la seule chose que vraiment FKs est le SGBDR, la façon dont vous décrivez plus tard. FKs sont vraiment contraintes, et je pense que c'est la façon dont ils doivent être définis, décrits et utilisés.
Si j'essaie d'entrer une valeur qui n'existe pas ce qui va être retourné? Avis? Avertissement?
ERREUR 1452 (23000): Impossible d'ajouter ou de mettre à jour une ligne enfant: une contrainte de clé étrangère échoue
OriginalL'auteur Barmar
Au lieu de lire tant de liens, juste essayer de mettre en œuvre ce projet simple. Je suis juste en expliquant comment on va utiliser les tableaux ci-dessus.
Supposons que vous 3 utilisateurs en
user
table et 5 éléments dansitems
table.user
tableitems
tablevotre
user_purchase
table ressembler à ceciCREATE TABLE user_purchase(
i_id INT(11) not NULL,
id INT(11) not NULL,
La CLÉ ÉTRANGÈRE (i_id) de référence à des éléments(i_id),
FOREIGN KEY (id) les RÉFÉRENCES de l'utilisateur(id)
);
Il n'y a pas besoin de nom d'élément nouveau dans ce tableau. J'ai donc supprimé.
Dans le tableau ci-dessus, nous allons obtenir, l'utilisateur 1 a acheté l'article 1, utilisateur 2 a acheté l'article 1,article 2, et l'utilisateur 3 a acheté la rubrique 3.
C'est comment la normalisation des œuvres. Vous pouvez utiliser MySQL JOINDRE pour obtenir le nom d'utilisateur et les détails de l'élément
Ici est la clef étrangère utiliser pour joindre
OriginalL'auteur Shafeeque
Vous treet tables avec des clés étrangères dans php de la même façon, comme si elles n'avaient pas les clés étrangères. Les clés étrangères sont définies dans la base de données et n'a (presque) rien à voir avec php. La seule chose que vous avez à faire dans le php est de réagir à d'éventuelles erreurs qui peuvent être renvoyées par les requêtes sql, frein à la contrainte de clé étrangère (généralement de SUPPRIMER des requêtes).
Et pour votre schéma de base de données, vous devez supprimer la colonne "nom" de la table "de user_purchase". Il est redundat.
OriginalL'auteur Jardo
Simplement en regardant la normalisation/dénormalisation point:
La normalisation est un processus d'essayer de supprimer les redondances dans votre base de données dans votre exemple, le
name
champ dansuser_purchase
est redondant - je peux savoir le nom de l'élément en regardant dans leitems
table à l'aide dei_id
.Donc, si nous devions chercher à normaliser
user_purchase
, nous aurions probablement supprimer laname
champ et l'utilisation d'unJOIN
les récupérer quand nous en avions besoin. Ce serait, bien sûr, signifie aussi nous n'avons pas besoin de la deuxièmeFOREIGN KEY
référence àitems
.De-la normalisation est fondamentalement va à l'opposé - l'ajout de redondance est en général faite pour des raisons de performances.
Cependant, dans votre exemple, vous pourriez aussi envisager de normalisation pour des raisons d'affaires. Par exemple, vous pourriez décider qu'il est important de stocker le nom du produit tel qu'il était lors de l'achat (plutôt que de ce qu'on l'appelle maintenant) - juste au cas où vous avez besoin pour être en mesure de ré-imprimer une facture par exemple. Cependant, même dans ce cas, vous ne voulez pas le
FOREIGN KEY
retour àitems
(comme il le ferait "pause" si le produit a été re-nommé).price
champ de fournir un exemple pour cela.Vous avez raison, bien sûr. Je ne pense plus tard que mon exemple était un peu forcé!
OriginalL'auteur Clart Tent