Le truc c'est que dans ton exemple le plus récent ce n'est pas une relation 1:n mais n:n (un job peut avoir plusieurs users et un user peut avoir plusieurs jobs).
Si je comprend bien, tu souhaites ensuite avoir en PHP
1 2 3 4
| [
"toto123" => ["coucou"]
"foo456" => ["bonjour", "bonsoir"]
] |
?
Et si je comprend toujours bien tu aimerais que ta base de données de sorte ce format directement pour économiser d'avoir des utilisateurs ou des jobs en doublon ? Techniquement c'est possible, mais ça va demander beaucoup plus de ressources à ta base de données de sortir ce format en une seule requête, ce qui est l'inverse de l'effet voulu.
Tu as plusieurs options :
- Si tu veux une liste des users et les jobs associés à chacun (possiblement aucun, si tu veux ignorer les users sans jobs remplace le 1er LEFT JOIN par un INNER JOIN),
SELECT champs FROM users u LEFT JOIN jobs_users ju ON u.id = ju.id_user INNER JOIN jobs j ON ju.id_job = j.id
- Si tu veux une liste des jobs et les users associés à chacun (possiblement aucun, idem qu'au dessus).
SELECT champs FROM jobs j LEFT JOIN jobs_users ju ON j.id = ju.id_job INNER JOIN users u ON ju.id_user = u.id
- Si tu veux la liste de toutes les prises en charges avec les users et jobs associés. A priori une entrée est créée dans la table jobs_users lors de la prise en charge d'un job par un user, il ne devrait donc pas y avoir de relations mortes. Si ce n'est pas le cas il faudra utiliser LEFT JOIN et traiter en PHP les cas où id_user/id_job est NULL.
SELECT champs FROM jobs_users ju INNER JOIN users u ON ju.id_user = u.id INNER JOIN jobs j ON ju.id_job = j.id
Ce sont des requêtes simples et quelques milliers de lignes c'est une petite table donc ça ne devrait pas poser de problème. J'utilise ce genre de requêtes sur des tables de plus de 50millions de lignes par exemple et ça passe nickel et j'ai un petit serveur. Si tu as des soucis de performances, tu as souvent 2 pistes principales :
- Evite autant que possible les appels à la base de données dans des boucles comme foreach ou while. C'est BEAUCOUP mieux de termes de performance de faire une ou deux grosses requêtes puis d'exploiter les retours en PHP par la suite.
- Il faut indexer ta base de données. Par exemple dans ce cas précis, les champs id_user et id_job de a table jobs_users doivent être indexés (je suppose que les champs id sont des clés primaires donc il y a déjà un index dessus).
En bonus, si tu utilises PDO, tu peux faire un truc du genre :
$data = $pdo->query("SELECT user_name, autres_champs FROM users u LEFT JOIN jobs_users ju ON u.id = ju.id_user INNER JOIN jobs j ON ju.id_job = j.id")->fetchAll(PDO::FETCH_GROUP);
Ce qui devrait donner qqch du genre :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| [
"toto123" => [
[
"autre_champ1" => "val1",
"autre_champ2" => "val2",
"autre_champ3" => "val3"
],
[
"autre_champ1" => "val4",
"autre_champ2" => "val5",
"autre_champ3" => "val6"
]
],
"foobar456" => [
[
"autre_champ1" => "val7",
"autre_champ2" => "val8",
"autre_champ3" => "val9"
],
[
"autre_champ1" => "val10",
"autre_champ2" => "val11",
"autre_champ3" => "val12"
]
]
] |
FETCH_GROUP créé un tableau associatif avec la 1ère valeur du SELECT comme valeur de regroupement.
Partager