Conseil pour l"utilisation d'un champs SQL avec plusieurs entiers

Avatar du membre
Mammouth du PHP | 1564 Messages

04 déc. 2020, 23:17

Salut, je souhaiterais avoir votre avis svp, je vous explique:

J'ai une table qui contient un champ qui doit contenir un entier (non unique), simplement pour aller cherche la ligne à un moment donné

Voilà maintenant que je dois rajouter un autre champ, au cas où il correspondrait aussi à ma première recherche (désolé c'est un peu flou)

J'ai pas envie de créer plusieurs champs "ID1", "ID2",etc... mais plutôt savoir si il est possible d'utiliser un champs pour tous, comme l'exemple: ID peut contenir: "1", "2", "68", "458",... ou même: "1,45," (ici pour avoir deux entier) ou même "4,96,785,..." (autant qu'on le souhaite pour m'éviter de créer plusieurs champs ID1, ID2,...

J'ai regardé les possibilités, il y a le JSON dans le PHPMyAdmin (que je pourrais peut être utiliser comme ceci: {"1","2",...}) et je souhaiterais avoir votre avis ou des conseils.

Besoin de plus d'infos ?? n'hésitez pas, je comprendrais... :lol:

[edit]:

en prenant cet exemple: php-debutant/topic281264.html
on souhaite mettre dans la colonne matier, les matières qu'il souhaite étudier, du coup l'idée serait de donner des ID à chaque matière (1 pour math, 2 pour histoire,etc..) et ensuite de le mettre dans "matier", comme ceci: "1,2" ici dans cet exemple l'élève souhaite étudier les maths et l'histoire

Avatar du membre
Mammouth du PHP | 1564 Messages

06 déc. 2020, 17:47

ça m'est déjà arrivé de rentrer des données du genre: "1,2,4,58,452," dans un champ puis de faire une recherche du type: si dans mon champs il y a "[nombre]," tu peux l'afficher, il y a peut être mieux que ce genre de méthode ;)

Avatar du membre
Mammouth du PHP | 1564 Messages

08 déc. 2020, 21:34

Je tiens à préciser que je connais la solution de la jointure SQL et ne souhaite pas l'utiliser dans mon cas.

Merci

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

09 déc. 2020, 14:17

Si le contenu de ton champ où tu veux stocker un tableau n'est pas utilisé pour être requêté, mais uniquement pour être affiché, alors tu peux le stocker dans le format que tu veux, JSON, serialize, etc...
Par contre si tu veux pouvoir faire une recherche dessus (par exemple tous les utilisateurs qui ont telle ou telle matières), alors ça se complique... :!:

:arrow: La méthode recommandée pour MySQL et la plus performante c'est sans hésiter la création d'une nouvelle table qui ferait le lien entre id_utilisateur et id_matiere où tu as autant de ligne que de couple utilisateur-matiere.

:arrow: Si tu as la possibilité d'avoir une base de données Postgre, alors c'est le mieux car il y existe la possibilité de stocker un tableau et de faire une requête simple pour rechercher les éléments qui contiennent
https://www.postgresql.org/docs/12/functions-array.html


:arrow: Si tu ne veux pas faire l'un ou l'autre, la seule solution serait d'avoir un serveur MySQL dont la version est supérieure à 8.0.17 car c'est à partir de cette versio qu'il est possible de requêté un tableau JSON dans un champ MySQL
https://dev.mysql.com/doc/refman/8.0/en ... tions.html
Quand tout le reste a échoué, lisez le mode d'emploi...

Avatar du membre
Mammouth du PHP | 1564 Messages

09 déc. 2020, 14:45

Merci!

Si, justement c'est pour être requêté.

Actuellement j'ai 2 champs (on va partir sur l'exemple des matières) id_mat1 et id_mat2, est il judicieux, à partir de deux champs de faire une nouvelle table pour de la jointure ou faire une requête avec "OR" passe encore ? (j'ai environ 500 enregistrements seulement...)

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

09 déc. 2020, 15:22

C'est pas le plus propre mais c'est encore gérable à 2.

Mais je déconseille fortement au delà car si tu cherches les utilisateurs qui ont la matière 3 ou la matière 5, ça te fait déjà 4 clauses pour ton WHERE :
SELECT * FROM table WHERE (id_mat1=3 OR id_mat1=5 OR id_mat2=3 OR id_mat2=5)
Et ça peut devenir vite illisible si tu veux chercher sur + de matières ou avec + de champs.
Quand tout le reste a échoué, lisez le mode d'emploi...

Avatar du membre
Mammouth du PHP | 1564 Messages

09 déc. 2020, 16:39

OK merci

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

16 déc. 2020, 19:17

Hello !

Pour ma part j'ai découvert il y a peu la fonction FIND_IN_SET de MySQL (existe pourtant depuis la version 4). Elle permet de faire une recherche dans un champ texte constitué d'une liste de valeurs séparées par des virgules.

Tu peux avoir un champ contenant la valeur "3,6,42" et l'interroger pour savoir s'il contient la valeur "6" ainsi : WHERE FIND_IN_SET(6, champ) > 0.

C'est probablement pas la panacée pour les performances, mais si le volume de la base n'est pas significatif, ça fait le job. Et par rapport à un LIKE, cela permet quand tu recherches la valeur "4" de ne pas considérer celui qui se trouve dans la valeur "42" ;)

Après la jointure avec une autre table qui aurait les 3 enregistrements 3, 6 et 42 associé à ta donnée principale, reste une option intéressante pour des questions de performance et d'intégrité... A toi de voir ce qui convient le mieux selon ton contexte :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Avatar du membre
Mammouth du PHP | 1564 Messages

16 déc. 2020, 22:38

Trop cool! j'utiliserais ce FIND_IN_SET très prochainement c'est sûr! Merci pour le partage ;)

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

17 déc. 2020, 15:46

Ah oui tiens je ne connaissais pas non plus, merci pour l'info Ryle ! :-D
Quand tout le reste a échoué, lisez le mode d'emploi...