par
Cyrano » 04 sept. 2005, 18:12
Absolument, j'ai une idée en arrière-plan.
Alors petite mise au point, ceci n'est pas du PHP mais du SQL, et même un peu avant ça, c'Est de la modélisation de base de données.
Explication de base : Prenons pour exemple imaginaire une table client et une table téléphone. Dans la table client, tu enregistres le nom, le prénom et l'adresse. Mais pour le téléphone, il pourrait y avoir un téléphone de domicile, un fax ou un portable ou les trois ou aucun. COmment éviter d'avoir des champs vides ? En créant une table à part avec deux champs : le numéro et le type de téléphone (domicile, fax, mobile) . Comment est-ce qu'on va relier les deux ? Chacune des deux tables doit avoir une clé primaire. ON ajoute donc à chacune un champ de type INT en auto_increment et en clé primaire. La clé primaire sert à identifier une ligne de façon unique puisque la valeur d'un champ de clé primaire n'accès aucun doublon. Tu ne l'utiliseras en principe pas pour sa valeur en tant que telle mais comme point de repère virtuel. Même chose pour les deux tables. Donc ma table client aura un champ cli_id et ma table telephone un champ tel_id.
Pourquoi et comment ?
Je sais au départ qu'un client peut avoir de zéro à
n numéros de téléphones, mais je sais également que chaque téléphone ne correspond qu'à un et un seul client. Je peux donc ajouter dans ma table téléphone un nouveau champ qui sera une clé étrangère correspondant à la valeur de la clé primaire de ma table client. Comme ça, si mon client a 30 numéros de téléphones, j'aurai mes trente lignes dans la table téléphone mais je pourrai savoir lesquels grâce à la clé étrangère puisque c'est la même valeur que la clé primaire de ma table client : un requête pour obtenir tous les numéros et le type d'appareil pour un client précis se fera donc de la manière suivante:
Ici, j'ai mis 12 pour l'exemple, ça n,a aucune autre signification.
Je crois que jusque là, tu dne devrais pas avoir eu trop de difficultés à suivre.
Maintenant, revenons à ton problème qui est un poil plus complexe. Nous avons au départ deux tables : client et annonceur. Nous savons également qu'un client peut avoir affaire avec
0 à n annonceurs et qu'un annonceur peut traiter
0 à n clients : là, j'ai un problème d'identification: comment vais-je faire pour connaitre tous les clients d'un annonceur si je mets dans la table annonceurs la clé primaire de la table clients ? En mettant la clé dans ce sens, je pourrais facilement connaitre tous les annonceurs d'un client, mais pas l'inverse. Bon mais alors si j'inverse, je mets à la place en clé étrangère dans la table clients une clé étrangère correspondant à la clé primaire de l'annonceur. Je résouds mon permier problème et je peux connaître tous les clients d'un annonceur, mais je ne peux plus faire l'inverse.
Je te vois penser à l'idée : "alors mettons les deux, une dans chaque" : TU pourrais essayer et je te regarderai t'arracher les cheveux pour faire des requêtes après
Donc la solution simple : on crée ce qu'on appelle une relation, c'est à dire en fin de compte une table intermédiaire qui permet les deux sens: cette table intermédiaire va comporter en clé étrangères les ceux clés primaires des deux tables clients et annonceurs, c'est tout : et bien entendu selon ce schéma simple (on oublie la commande elle-même et les détails que j'ai évoqué dans une réponse précédente, la clé primaire de cette table intermédiaire est composite et faite des deux clés étrangères réunies. Il ne peut de cette façon jamais y avoir de doublons.
Mais alors me diras-tu : pourquoi une clé primaire en plus dans le schéma que j'ai envoyé tout à l'heure ? Si tu as lu attentivement ce que j'ai noté, j'ai évoqué une autre table detail_commande qui comporte les champs décrivant chaque commande : On doit la relier aussi bien à un lcient qu'à un annonceur : on passera par notre table intermédiaire commandes_2005 en ajoutant une troisième clé étrangère qui sera la clé primaire de la table details_commandes.
Mon schéma devient donc :
Code : Tout sélectionner
+-------------------------------------------+
| annonceur |
+-------------------------------------------+
|ann_id INT NOT NULL Auto_increment <PK> |
|ann_nom VARCHAR(32) |
|ann_telephone VARCHAR(16) |
|ann_fax VARCHAR(16) |
|ann_region VARCHAR(32) |
+-------------------------------------------+
|
|
+-------------------------------------------+ +-------------------------------------------+
| commandes_2005 | | details_commmande |
+-------------------------------------------+ +-------------------------------------------+
|ann_id INT NOT NULL <PK, FK> |----------|det_id <PK>|
|com_id INT NOT NULL <PK, FK> | |det_date_diff |
|det_id INT NOT NULL <PK, FK> | |det_nb_msg |
+-------------------------------------------+ +-------------------------------------------+
|
|
+-------------------------------------------+
| commercial |
+-------------------------------------------+
|com_id INT NOT NULL Auto_increment <PK> |
|com_portable VARCHAR(16) |
+-------------------------------------------+
Là, je ne vais pas plus loin pour l'instant, dis-moi ce que tu n'as pas compris éventuellement ou ce qui n'est pas clair.
Absolument, j'ai une idée en arrière-plan.
Alors petite mise au point, ceci n'est pas du PHP mais du SQL, et même un peu avant ça, c'Est de la modélisation de base de données.
Explication de base : Prenons pour exemple imaginaire une table client et une table téléphone. Dans la table client, tu enregistres le nom, le prénom et l'adresse. Mais pour le téléphone, il pourrait y avoir un téléphone de domicile, un fax ou un portable ou les trois ou aucun. COmment éviter d'avoir des champs vides ? En créant une table à part avec deux champs : le numéro et le type de téléphone (domicile, fax, mobile) . Comment est-ce qu'on va relier les deux ? Chacune des deux tables doit avoir une clé primaire. ON ajoute donc à chacune un champ de type INT en auto_increment et en clé primaire. La clé primaire sert à identifier une ligne de façon unique puisque la valeur d'un champ de clé primaire n'accès aucun doublon. Tu ne l'utiliseras en principe pas pour sa valeur en tant que telle mais comme point de repère virtuel. Même chose pour les deux tables. Donc ma table client aura un champ cli_id et ma table telephone un champ tel_id.
[b]Pourquoi et comment ?[/b]
Je sais au départ qu'un client peut avoir de zéro à [i]n[/i] numéros de téléphones, mais je sais également que chaque téléphone ne correspond qu'à un et un seul client. Je peux donc ajouter dans ma table téléphone un nouveau champ qui sera une clé étrangère correspondant à la valeur de la clé primaire de ma table client. Comme ça, si mon client a 30 numéros de téléphones, j'aurai mes trente lignes dans la table téléphone mais je pourrai savoir lesquels grâce à la clé étrangère puisque c'est la même valeur que la clé primaire de ma table client : un requête pour obtenir tous les numéros et le type d'appareil pour un client précis se fera donc de la manière suivante:
[code]SELECT tel_num, tel_type
FROM telephone
WHERE cli_id = 12;[/code]
Ici, j'ai mis 12 pour l'exemple, ça n,a aucune autre signification.
Je crois que jusque là, tu dne devrais pas avoir eu trop de difficultés à suivre.
Maintenant, revenons à ton problème qui est un poil plus complexe. Nous avons au départ deux tables : client et annonceur. Nous savons également qu'un client peut avoir affaire avec [i]0 à n[/i] annonceurs et qu'un annonceur peut traiter [i]0 à n[/i] clients : là, j'ai un problème d'identification: comment vais-je faire pour connaitre tous les clients d'un annonceur si je mets dans la table annonceurs la clé primaire de la table clients ? En mettant la clé dans ce sens, je pourrais facilement connaitre tous les annonceurs d'un client, mais pas l'inverse. Bon mais alors si j'inverse, je mets à la place en clé étrangère dans la table clients une clé étrangère correspondant à la clé primaire de l'annonceur. Je résouds mon permier problème et je peux connaître tous les clients d'un annonceur, mais je ne peux plus faire l'inverse.
Je te vois penser à l'idée : "alors mettons les deux, une dans chaque" : TU pourrais essayer et je te regarderai t'arracher les cheveux pour faire des requêtes après :langue:
Donc la solution simple : on crée ce qu'on appelle une relation, c'est à dire en fin de compte une table intermédiaire qui permet les deux sens: cette table intermédiaire va comporter en clé étrangères les ceux clés primaires des deux tables clients et annonceurs, c'est tout : et bien entendu selon ce schéma simple (on oublie la commande elle-même et les détails que j'ai évoqué dans une réponse précédente, la clé primaire de cette table intermédiaire est composite et faite des deux clés étrangères réunies. Il ne peut de cette façon jamais y avoir de doublons.
Mais alors me diras-tu : pourquoi une clé primaire en plus dans le schéma que j'ai envoyé tout à l'heure ? Si tu as lu attentivement ce que j'ai noté, j'ai évoqué une autre table detail_commande qui comporte les champs décrivant chaque commande : On doit la relier aussi bien à un lcient qu'à un annonceur : on passera par notre table intermédiaire commandes_2005 en ajoutant une troisième clé étrangère qui sera la clé primaire de la table details_commandes.
Mon schéma devient donc :
[code]+-------------------------------------------+
| annonceur |
+-------------------------------------------+
|ann_id INT NOT NULL Auto_increment <PK> |
|ann_nom VARCHAR(32) |
|ann_telephone VARCHAR(16) |
|ann_fax VARCHAR(16) |
|ann_region VARCHAR(32) |
+-------------------------------------------+
|
|
+-------------------------------------------+ +-------------------------------------------+
| commandes_2005 | | details_commmande |
+-------------------------------------------+ +-------------------------------------------+
|ann_id INT NOT NULL <PK, FK> |----------|det_id <PK>|
|com_id INT NOT NULL <PK, FK> | |det_date_diff |
|det_id INT NOT NULL <PK, FK> | |det_nb_msg |
+-------------------------------------------+ +-------------------------------------------+
|
|
+-------------------------------------------+
| commercial |
+-------------------------------------------+
|com_id INT NOT NULL Auto_increment <PK> |
|com_portable VARCHAR(16) |
+-------------------------------------------+[/code]
Là, je ne vais pas plus loin pour l'instant, dis-moi ce que tu n'as pas compris éventuellement ou ce qui n'est pas clair.