Utiliser des INT ou des VARCHAR pour les relations entre les tables MySQL ?

  • Auteur de la discussion Auteur de la discussion pascalpa
  • Date de début Date de début
Nouveau WRInaute
Bonjour,

Je vais poser une question sans doute bête et naïve, mais je n’ai pas trouvé de réponse claire (et je débute, merci d’être indulgent !).

Admettons que j’aie 2 tables :
Termes (id_terme, terme)
Synonymes (id_syn, synonyme)

Les champs id_terme et id_syn sont des INT.
Les champs terme et synonyme sont des VARCHAR.

Etant donné qu’il y a une relation n,n entre les 2 tables, je vais créer une table associative faisant correspondre les ID des 2 tables : Assoc(id_terme, id_syn)

Jusque là OK. Et là, tout à coup, je me dis : mais après tout, qu’est-ce qui m’empêche de créer une table associative contenant les termes et les synonymes ? Ce sera peut-être moins performant (un peu moins ou beaucoup moins… telle est la question !), mais en cas de problème, j’y verrais plus clair. Ca donnerait ça : Assoc(terme, synonyme)

Est-ce que c’est vraiment une solution à proscrire absolument (en termes de performances) ou pas forcément ?

Merci pour vos réponses.
Pascal
 
WRInaute passionné
Tu brises la logique d'une base de données relationnelle : quand tu dois corriger un mot, il faut aller le corriger dans 2 tables au lieu d'une seule. Avec les années et les tables qui s'ajoutent, ça devient un gros bordel quand il faudra faire des modifs, des transferts, des exportations, etc...

Sinon ça marche, c'est juste un peu plus lent, un index avec des nombres, c'est 1 test par ligne, un index avec des mots, c'est éventuellement 2, 3 ou plus de tests par ligne quand les mots commencent pareil.
L'important est de ne pas oublier les clés primaires, et la clé primaire/index sur les 2 champs de l'association ce que plein de gens oublient.
 
WRInaute occasionnel
Si je peux me permettre,

En terme de bonnes pratiques, je ferai mon model relationnel comme suit :

termes : id (INT), terme (VARCHAR 255)
synonymes : id (INT), terme_id (INT), synonyme_id (INT)

dans la table "synonymes", le champs "synonyme_id" est une relation polymorphe avec "terme". Parce qu'un synonyme d'un terme, c'est un terme (oui, le synonyme de "bestiole", c'est "animal", mais "animal" est synonyme de "bestiole")

Selon ta structure tu risques d'avoir autant de terme que de synonyme, ça risque donc de gonfler ta BDD inutilement.

Ainsi dans ce modèle relationnelle, un terme à plusieurs synonymes qui sont eux-mêmes des termes !

Après... Les relations c'est mieux avec les ID ;) !

Bisous Bécôts <3 <3
 
WRInaute accro
pascalpa a dit:
Admettons que j’aie 2 tables :
Termes (id_terme, terme)
Synonymes (id_syn, synonyme)
non en fait tu as bien deux tables mais pas comme ça.

une première avec des mots et leur id, et une seconde avec des couple d'id "termes" et "synonymes" c'est la même chose tu n'as pas besoins de deux tables faut juste appairer des termes pour avoir des synonymes.

Termes (id_terme, terme)
Couples (id_terme, id_terme_syn)

Ce qui de facto répond a ta question car il serait "stupide" de stocker des couple de termes dans la mesure ou cela rendrait la table de terme totalement inutile.

La ou tu dois te poser une question c'est dans ta table de couples, faut il faire deux enregistrement du style (A,B) et (B,A) (puisque c'est la même chose) Là c'est ta logique applicative qui répondra si c'est plus pratique dans un cas ou l'autre.
 
WRInaute accro
p0k3 a dit:
C'est ce que j'ai dit :p
Oui j'étais en train d'écrire quand tu as posté, j'allais pas non plus effacer pour autant.
Le truc c'est que je faisait une recherche annexe pour voir si il n'était pas possible de mettre une collection d'id dans un champ ce qui aurait évité la table de correspondance, mais rien trouvé de pratique a ce niveau.
 
Nouveau WRInaute
Bonsoir à tous.

Merci beaucoup pour toutes vos réponses, qui me sont très utiles et me permettent d'y voir plus clair !

@p0k3 et zeb : vous anticipez sur une question que j'allais poser, à savoir : comment faire pour modéliser des relations qui existent en quelque sorte "à l'intérieur" d'une seule table ? En l'occurrence, vous avez répondu à la question, dans le cas de figure où l'ensemble des synonymes est inclus dans l'ensemble des termes. Dans ce cas de figure, tous les synonymes sont des termes, tous les termes peuvent être potentiellement synonymes les uns des autres, un terme pouvant avoir (0,n) synonymes et un synonyme pouvant être lié à (1,n) termes.

Mais que se passe-t-il dans le cas où l'ensemble des termes n'est pas inclus dans l'ensemble des synonymes, mais en intersection avec lui, càd dans le cas où tout synonyme n'est pas forcément un terme ?

Cette idée que tout synonyme n'est pas un terme peut sembler absurde, mais disons que, sémantiquement, dans le cadre de mon appli, elle a un sens, notamment parce qu'il y a des notions de termes principaux et secondaires (les "termes" étant des termes principaux et les "synonymes" étant des termes secondaires). En tout cas, c'est comme ça qu'à été conçu le fichier Excel que j'ai récupéré, et que je dois transformer en base de données... ce qui n'est pas une mince affaire ! :-)

Merci pour vos lumières !

Bonne soirée.
Pascal

PS : Je ne sais pas si mes explications sont bien claires... Si ce n'est pas le cas, je reviendrai de toute façon demain matin, j'aurai sûrement l'esprit moins embrouillé. ;-)
 
WRInaute accro
pascalpa a dit:
Mais que se passe-t-il dans le cas où l'ensemble des termes n'est pas inclus dans l'ensemble des synonymes, mais en intersection avec lui, càd dans le cas où tout synonyme n'est pas forcément un terme ?
comme tu préconise au début est une solution mais ce que laisse supposer ta question c'est "quid de la suite". Il faudrait en savoir plus sur la finalité pour mettre en parallèle le fait d'ajouter purement et simplement les éléments exclus a la table des termes quitte a ajouter un champ d'identification portant sur le type si tu as besoin de manipuler les deux listes séparément.

un exemple : "équivoque" est un terme qui a deux synonyme direct dans la table des termes "interlope" et "problématique" (c'est disons un "mot unique") mais il en a aussi deux dans celle des locutions adjectivales : "à double sens", "sous entendu". donc soit je range toutes les expressions dans une même table et j'y ajoute une information de type (locution adjectivale, adverbiales, latines, ... périphrase) soit je crée une table pour chaque type possible de mots ou groupe de mots. Mais dans les deux cas je dois lier avec des couple d'id sachant que si tout est groupé j'aurais la nature du couple via le champ de type de la table de termes et que si tout n'est pas lié (tables distinctes) j'aurais la nature du couple par la table que je consulte.

C'est l'application qui dicte le choix pour des raisons de perfs. A titre d'exemple si je me borne au niveau de la langue française a chercher des synonymes sur des termes simples (42 000 mots) dans un corpus courant j'ai environ 160 000 couples, si j'étends cela au expression (en introduisant les locutions par exemple soit 48 000 expressions) je passe a 450 000 couples. Même si ça reste des ordres de grandeur pas trop violents il peut être utile de prendre en compte la finalité pour décider comment répartir les données

On peut tenir le même propos avec les antonymes au passage ...
 
Nouveau WRInaute
Merci pour ta réponse détaillée.

Cela nous emmène loin de la question initiale, mais tant mieux, c'est très intéressant ! :) Et cela correspond également à une question que je me suis déjà posée, à savoir : faut-il répartir les données dans plusieurs tables en fonction de leur type, ou bien les mettre dans une seule table en les typant via un champ spécialement dédié à cela.

Là où je ne comprends pas très bien ta réponse, c'est lorsque tu écris : "C'est l'application qui dicte le choix pour des raisons de perfs. (...) il peut être utile de prendre en compte la finalité pour décider comment répartir les données".

Peux-tu STP m'en dire un peu plus (si tu as le temps...) ? Quels sont les critères qui, selon toi, peuvent permettre d'opter pour l'une ou l'autre solution (table unique avec données typées vs. plusieurs tables) ?

Pour info, ma base est relativement petite (un peu plus de 4000 termes + leurs synonymes dans 10 langues + des définitions dans 2 langues).

Merci !
Pascal
 
WRInaute accro
pascalpa a dit:
"C'est l'application qui dicte le choix pour des raisons de perfs. (...) il peut être utile de prendre en compte la finalité pour décider comment répartir les données".
Il faut te faire une idée précise (presque dès le départ) des requêtes que ton logiciel ou site (ce qui reviens au même) va faire sur ta base de données.
En effet en fonction des cas tu peut être amené a avoir une modèle de données en base très optimisé et pertinent mais qui oblige a des requêtes lourdes en terme de performance. Auquel cas il est parfois intéressant de transgresser par exemple la notion de redondance des données évoqué a juste titre par Rick38 plus haut.
De même si le contenu d'un champ fait que tu dois utiliser des fonctions "compliquées" (genre regex par exemple) sur une requête il est parfois rentable de modifier la structure pour gagner en performance...

Les données c'est une chose il faut aussi penser a leur manipulation pour décider si une façon de procéder est plus rentable qu'une autre quand on considère le résultat final. A ce stade la maintenance doit aussi être prise en compte ... Va elle être plus lourde mais rare ? ou alors inexistante de toute façon ... Voir ingérable si ...

La décision du modèle n'est pas qu'une question de contrainte SQL il faut tout prendre en compte.

A titre d'exemple assez différent mais qui illustre cette contradiction entre fonctionnalité et principes de gestion des données, j'ai un site qui demande pour des raisons de taille plusieurs bases de données. En fonction des pages je dois manipuler des groupes de données différents qui sont rarement sur la même base .... J'ai donc choisi de dupliquer des tables pour faciliter la récupération de données via une requête au lieu de deux connections avec passage de paramètre de façon applicative.
J'y perd sur la maintenance (quand je dois modifier une data c'est sur plusieurs bases) mais j'y gagne énormément en temps de traitement et ça c'est 99% de l'usage.
 
Nouveau WRInaute
Ok, merci beaucoup pour tes explications.

Je suis justement en train d'essayer de "normaliser" au minimum ma base pour éviter notamment les redondances (ce qui prend énormément de temps, car je suis parti d'un tableau Excel... et je ne peux pas tout faire avec des macros, loin de là !) mais tout ce que tu dis m'inquiète un peu : j'espère ne pas être en train de bosser pour rien, pour finalement me rendre compte que mes requêtes sont ingérables et que j'aurais mieux fait de laisser les redondances ! :roll:

Mais bon, ne paniquons pas ! :D Je vais avancer calmement et essayer de tenir compte des 2 contraintes (cohérence SQL + requêtes). Avec tout ça, je sens que ne vais pas tarder à revenir avec d'autres questions. :wink:

En tout cas, tes réponses et celles des autres m'ont été très utiles.
Merci et bon week-end à tous.
Pascal
 
Discussions similaires
Haut