8797 sujets

Développement web côté serveur, CMS

Bonjour à tous,

J'hésite très souvent entre deux architectures Mysql sans réellement me décider entre l'une ou l'autre.

Le problème consiste à créer des liens entre deux tables : imaginons que j'ai un table pages et une table documents.

La première solution, la plus simple consiste a ajouter un index id_page à ma table document pour pouvoir récupérer les document qui correspondent à une page.

Imaginons maintenant que j'ai également des tables users, activities, events et products sur ma base, et que je veux également associer des documents à chacune de ses tables. Il va falloir rajouter à ma table document des champs id_users, id_activity etc...

Compliquons encore un peux et imaginons que je veuillent aussi pouvoir associer un document à plusieurs pages ou utilisateurs, le champ id_page pourra ressembler à 6|12|18, ce qui complique un peu les requêtes et les insertions.

L'autre solution consiste à utiliser des jointures ou des unions, c'est à dire que je n'ai pas d'id_page a ma table document, mais une table page_document qui fais le lien entre les deux tables, j'utilise ensuite les requêtes imbriquées pour récupérer les données.

Les deux solutions ont leur avantages et leurs inconvénients, mais je n'arrive à définir des critères clairs pour me décider entre l'une et l'autre, je décide un peu au feeling et des fois je m'aperçois au centième enregistrement que j'aurais peut-être du faire autrement... Auriez vous des articles sur le sujets ou bien des exemples de cas précis dans lequel il faut absolument utiliser une jointure et d'autre dans lequel c'est complètement inutile?
Modifié par matmat (03 Jun 2008 - 17:55)
Hello matmat Smiley smile ,

Ben pour la doc il y a tout ce qui concerne Merise (dont celui-ci) mais je n' ai rien de bien précis Smiley rolleyes ...

Sinon personnellement la règle est simple :

- si j'ai une cardinalité (0,n) ou (1,n) je rajoute simplement l'id_xxx qui va bien dans la table qui va bien

- sinon (cardinalité (n,n)) je crée une table de liens genre page_document (ou en français : une page peut contenir 0 ou n documents et un document peut se retrouver sur 0 à n pages).

A+
Modifié par Heyoan (02 Jun 2008 - 18:30)
Heyoan a écrit :


Sinon personnellement la règle est simple :

- si j'ai une cardinalité (0,n) ou (1,n) je rajoute simplement l'id_xxx qui va bien dans la table qui va bien

- sinon (cardinalité (n,n)) je crée une table de liens genre page_document (ou en français : une page peut contenir 0 ou n documents et un document peut se retrouver sur 0 à n pages).



J'adhére!

Donc dans le cas simple d'un document associer à une page c'est résolu.
Dans le cas d'un document qui peut-être associé a plusieurs page aussi.

Par contre est ce que cette régle est toujours valide dans le cas suivant :

Je ne peux pas associer un même document à plusieurs table mais j'ai plusieurs tables auquel peut-être associer un document? Est ce que ça ne va pas faire beaucoup de champ id_product, id_event, id_user à rajouter à ma table document?

Je précise :

Dans un cas j'ai une table documents qui ressemble a ça :

id_document | id_page | id_product | id_activity | id_user | id_event |src | text |date |status

dans l'autre j'ai un table documents comme ça :

id_document | src | text |date |status

et des tables relationnelles comme ça :

id_document | id_page
id_document | id_product
id_document | id_activity
id_document | id_user
id_document | id_event
Modifié par matmat (02 Jun 2008 - 19:24)
matmat a écrit :
Je ne peux pas associer un même document à plusieurs table mais j'ai plusieurs tables auquel peut-être associer un document?
Euh... c'est moi qui suis fatigué ou ta phrase se mord la queue Smiley lol ?

Sinon, je ne suis pas bien sûr de comprendre ton exemple. En fait je fonctionne beaucoup en termes de cardinalités car je trouve que ça simplifie vraiment la question de "comment agencer mes tables" Smiley murf ! Pour dire ça autrement :

Dans cet exemple :
a écrit :
id_document | id_page | id_product | id_activity | id_user | id_event |src | text |date |status
Pour moi ça veut dire qu'1 document :
- ne peut être associé qu'à 1 et 1 seule page (ou aucune).
- ne peut être associé qu'à 1 et 1 seul produit (ou aucun).
- ne peut être associé qu'à 1 et 1 seule activité (ou aucune).
- ne peut être associé qu'à 1 et 1 seule user (ou aucun).
- ne peut être associé qu'à 1 et 1 seule évènement (ou aucun).

Et donc si ces 5 définitions sont vraies c'est à priori comme ça qu'il faut faire.


Alors que dans cet exemple :
a écrit :
id_document | id_page
id_document | id_product
id_document | id_activity
id_document | id_user
id_document | id_event
Pour moi ça veut dire qu'1 document :
- peut être associé à 0 ou plusieurs pages (et/ou qu'1 page peut être associée à 0 ou plusieurs documents).
- peut être associé à 0 ou plusieurs produits (et/ou...).
- peut être associé à 0 ou plusieurs activités (et/ou...).
- peut être associé à 0 ou plusieurs users (et/ou...).
- peut être associé à 0 ou plusieurs évènements (et/ou...).

Et donc si ces 5 définitions sont vraies c'est à priori comme ça qu'il faut faire.


Bon et bien sûr il y a des cas particuliers Smiley langue :
- par exemple on peut anticiper et se dire qu'un jour ou l'autre un document pourrait bien se retrouver sur plusieurs pages et plus sur 1 seule et du coup autant partir tout de suite sur la seconde version...
- un autre exemple est de se dire : "Bon ! Il est bien gentil M'sieur Merise mais ça complique mon code inutilement !"
Et du coup faire quelque chose du genre :
table lien_documents :
- id_lien
- id_document
- id_type_lien
- id_correspondant
- ...

table types_liens :
- id_type_lien (ex : 1=page, 2=produit, etc...)
- libellé
- ...
Modifié par Heyoan (03 Jun 2008 - 11:21)
Heyoan a écrit :
Euh... c'est moi qui suis fatigué ou ta phrase se mord la queue Smiley lol ?


En fait c'est comme l'énigme du gruillère, plus il y a de gruillère plus il y a de trous et plus il y a de trous moins il y a de gruillère. Plus il ya de table plus il ya de champs et plus il y a de champs moins il ya de table. Smiley biggol

Heyoan a écrit :

Dans cet exemple :id_document | id_page | id_product | id_activity | id_user | id_event |src | text |date |status
Pour moi ça veut dire qu'1 document :
- ne peut être associé qu'à 1 et 1 seule page (ou aucune).
- ne peut être associé qu'à 1 et 1 seul produit (ou aucun).
- ne peut être associé qu'à 1 et 1 seule activité (ou aucune).
- ne peut être associé qu'à 1 et 1 seule user (ou aucun).
- ne peut être associé qu'à 1 et 1 seule évènement (ou aucun).

Et donc si ces 5 définitions sont vraies c'est à priori comme ça qu'il faut faire.


Donc je vais faire comme ça!

En fait pas tout à fais, dans le cas ou je n'ai qu'une table en plus de ma table page, je ferais comme ça, dans le cas ou j'ai une table produit, je crois que je vais faire une table documents_page et une autre documents_product, ça compliquera pas le code parce que ce sera la même méthode pour aller en récupérer le contenu mais cela me permettras un meilleur séparations des types de contenus et de meilleures performances car la table document sera en quelque sorte partitionnée.

Merci Smiley biggrin !
matmat a écrit :
...et de meilleures performances car la table document sera en quelque sorte partitionnée.
Ah bon Smiley rolleyes ! Tu veux dire que ce serait plus performant qu'en créant les bons index sur la table de ton premier exemple ? (je viens de faire une recherche mais je n'ai rien trouvé.)

a écrit :
Merci Smiley biggrin !
De rien Smiley cligne !
Modifié par Heyoan (03 Jun 2008 - 18:38)
Heyoan a écrit :
Ah bon Smiley rolleyes ! Tu veux dire que ce serait plus performant qu'en créant les bons index sur la table de ton premier exemple ? (je viens de faire une recherche mais je n'ai rien trouvé.)


Encore un confusion, décidément il faut que je sois plus clair...

En fait ce que je voulais dire c'est que dans les deux cas ce serait comme dans le premier exemple, sauf que je pourrais créer deux tables de documents, une comme ça :

id_document | id_page | src | text |date |status

et l'autre comme ça :

id_document | id_product | src | text |date |status

C'est encore à réfléchir mais ce peut être une bonne option si il y a beaucoup de documents dans les deux tables.
matmat a écrit :
C'est encore à réfléchir mais ce peut être une bonne option si il y a beaucoup de documents dans les deux tables.
Et bien pour le coup je te déconseille vivement cette solution Smiley murf ! Autant parfois on peut "tricher" un peu avec Merise parce que ça nous simplifie la vie, autant dans ce cas je ne vois que des désavantages Smiley rolleyes ! Un exemple simple : lorsque tu vas vouloir modifier le champ text de ton document il va falloir faire ton UPDATE dans toutes les tables où il sera présent...

J'avais compris que tes tables liens (du genre documents_pages) ne contenaient que des identifiants d'où ma question sur les performances Smiley cligne !

A+
Dans ce cas ce serait 2 tables complètement différentes, je n'aurais pas à faire l'update sur les deux, c'est tout simple, quand je veux ajouter un document a une page je le met sur la table documents_page, si je veux actualiser la photo d'un produit je le met sur la table documents_product.
Modifié par matmat (04 Jun 2008 - 15:55)
Arf ! C'est la structure qui m'a embrouillé Smiley langue ! J'étais encore avec l'idée qu'un document peut être associé soit à une page, soit à un produit !

Du coup, est-ce que ce ne serait pas mieux de préciser le type de document (genre articles, photos, etc...) ?
Heyoan a écrit :
Arf ! C'est la structure qui m'a embrouillé Smiley langue ! J'étais encore avec l'idée qu'un document peut être associé soit à une page, soit à un produit !

C'est un peu normal vue que j'ai rajouté l'idée en cours de route...
Heyoan a écrit :

Du coup, est-ce que ce ne serait pas mieux de préciser le type de document (genre articles, photos, etc...) ?


Pourquoi pas, jusque là ce que je fais c'est que je met tout sur un table document, avec un champ config qui détermine si c'est une image, un document, ou un logo. L'idée c'est de faire qu'une requête pour tout récupérer puis de faire différents tableaux selon le type

De les séparer ce ferais plus de requêtes par page, mais des données mieux organisées et des tables plus petites et moins chargée.

Argg, c'est dur de faire une table mysql!