Forum |  HardWare.fr | News | Articles | PC | Prix | S'identifier | S'inscrire | Aide | Shop Recherche
1832 connectés 

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Gestion des relations => schéma de la BDD

 



 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Gestion des relations => schéma de la BDD

n°2349188
mechkurt
Posté le 23-03-2020 à 18:09:52  profilanswer
 

Je dois ajouter dans ma base de donnée une notion de relation entre les utilisateurs (pour le moment on va faire simple ami ou pas).
 
Je ne sais pas trop comment faire mon schéma de base car dans les 2 cas je vais avoir pas mal de jointure à faire, et je ne suis pas sur de ce qui est le plus performant...
 
Hypothèse 1 :  une table représentant la relation avec sa réciprocité

Code :
  1. user_friends : id_user_a statut_user_a date_user_a id_user_b statut_user_b date_user_b
  2. id_user_{a,b}  = ma clé dans la table user
  3. date_user_{a,b}  = date de la dernière modification de statut effectué par l'utilisateur
  4. statut_user_{a,b} = waiting / accepted / refused
  5. avec une règle dans mon code pour lors d'insertion maintenir que id_user_a < id_user_b


Dans ce cas, quand on demande quelqu’un ({id1}) en ami mais que celui-ci  ({id2}) n'as pas encore accepté, on se retrouves avec une ligne comme celle là :

Code :
  1. | {id1} | accepted  | 2020-03-23 | {id2} | waiting | NULL |


Ce qui me donnerait des requêtes pour trouver l'email des amis de l'utilisateur {ID} du genre :

Code :
  1. SELECT uf.*, a.email AS email1, b.email AS email2
  2. FROM user_friends uf
  3. INNER JOIN user a ON a.id_user = uf.id_user_a
  4. INNER JOIN user b ON b.id_user = uf.id_user_b
  5. WHERE uf.id_user_a = {ID} OR uf.id_user_b = {ID}


Du coups des résultats assez brut avec forcément pas mal de process en php derrière pour trier si ce qui nous intéresse vient de a ou de b, si le statut est bien validé ou non, etc...
Sachant que derrière, suivant les affichages je serais ptet amener a faire d'autre requêtes jointe par rapport au user (avatar, badges, etc.)
 
Hypothèse 2 :  une table représentant la relation que du point de vue de la personne

Code :
  1. user_friends : id_user statut date friend_id


Cette fois, quand on demande quelqu’un en ami mais que celui-ci n'as pas encore accepté on se retrouves avec deux lignes :

Code :
  1. | {id1} | accepted  | 2020-03-23 | {id2} |
  2. | {id2} | waiting | 2020-03-23 | {id1} |


Ce qui cette fois me donnerait des requêtes de ce genre :

Code :
  1. SELECT uf.*, f.email, fs.statut AS friend_statut, fs.date AS friend_date
  2. FROM user_friends uf
  3. INNER JOIN user f ON f.id_user = uf.friend_id
  4. INNER JOIN user_friends fs ON fs.id_user = friend_id
  5. WHERE uf.id_user_a = {ID}


Ce que j'aime dans cette version c'est que le résultat SQL est tout de suite bien plus clair et exploitable que la version 1, mais en terme de ressource j'ai l'impression que c'est plus gourmand non ?
Et je n'aimes pas trop l'idée d'avoir 2 lignes dans une même table ?
 
Je serais curieux d'avoir d'autres avis...


Message édité par mechkurt le 23-03-2020 à 18:56:36

---------------
D3
mood
Publicité
Posté le 23-03-2020 à 18:09:52  profilanswer
 

n°2349294
gelatine_v​elue
Posté le 24-03-2020 à 11:18:28  profilanswer
 

J'aime pas réfléchir en termes techniques. D'un point de vue fonctionnel, on veut la liste des demande d'ami émises par une personne. Une demande concerne deux personnes, et a un statut: l'acceptation ou non par la personne cible.
 
Je ferais donc une table avec quelque chose comme ta solution 1 mais sans l'état "accepted " pour id1, car on se doute que si il demande quelqu'un en ami, il est d'accord.


---------------
Vends des trucs sur Bdx
n°2349299
mechkurt
Posté le 24-03-2020 à 12:00:50  profilanswer
 

Ben oui mais en faite dans 1 ans N°1 vas ptet changer d'avis sur son amitié et donc changer son état...
 
...mais il faudra que la relation existe encore chez N°2 (en mode N°1 vous a rejeté, c'est cruel hein ^^).
 
La question se posera peut-être de supprimer la relation quand les 2 seront en refused pour alléger la table, mais ça peut quand même être pratique de voir "ses anciens amis"


---------------
D3
n°2349306
gelatine_v​elue
Posté le 24-03-2020 à 12:13:20  profilanswer
 

L'état passera de ACCEPTED a REJETE_DEMANDEUR non?


---------------
Vends des trucs sur Bdx
n°2349321
mechkurt
Posté le 24-03-2020 à 13:34:03  profilanswer
 

Hum, oui je supposes que ça pourrait, mais en fait distinguer les états de chaque user me semble pertinent pacqu'au cour du temps, une "amitié" peu évoluer des 2 cotés : oui,oui / oui,non / non,oui / non,non...
 
Enfin c'est comme ça que je vois les choses mais je suis ptet a cote de la plaque...
 
...d’où mon post ?


---------------
D3
n°2349431
rufo
Pas me confondre avec Lycos!
Posté le 25-03-2020 à 11:15:43  profilanswer
 

La première solution me paraît plus adaptée pour gérer des relations symétriques. Dans ce cas, il y a effectivement le statut du user 1 qui est de trop. Cette solution permet aussi de savoir plus facilement qui a initié la relation si on fait sauter la règle id1 < id2 qui n'a pas de sens et n'apporte rien à mon avis (dans ta requête d'extraction, tu es obligé de faire un OR sur les 2 ID).
 
Mais tu as indiqué que le demandeur pouvait finalement refuser la relation. Et c'est vrai, les relations humaines ne sont pas symétriques. Du coup, la solution 2 me paraît plus adaptée pour gérer l'évolution des relations dans le temps. Et si tu ajoute un ID de relation incrémental, Tu pourras aussi savoir qui a initié la relation puisque cet ID sera < l'ID de la 2ème relation.
 
Edit : pour la date, je te recommande de mettre date/heure. Ca te permettra de mesurer plus finement le temps écoulé entre la demande et la réponse. S'il est court, on peut penser que le 2ème user en avait très envie de cette relation. S'il est long, soit la personne n'était pas très pressée, soit elle n'était pas dispo pour répondre. Ca permet de faire du big data. ;)


Message édité par rufo le 25-03-2020 à 11:22:13

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Cantine Calandreta : http://sourceforge.net/projects/canteen-calandreta
n°2349494
mechkurt
Posté le 25-03-2020 à 15:38:26  profilanswer
 

Pour le moment; je suis partis sur le modèle 1 avec lequel je suis "intuitivement" plus à l'aise...
Au lieu d'avoir un statut a et un statut b on pourrait effectivement avoir un meta statut a et b résumant toutes les combinaisons mais le jour ou on voudra trouver les gens en attente de réponse de {id1] la requête sera plus compliqué (en hypothèse 1, en 2 on est bon).
Pour le champs date, je suis partis sur  yyyy-mm-dd pacque pour le moment perf >> stats, mais on est pas encore en prod donc j'interrogerais le client sur la pertinence de l'information (et comme il n'a aucune idée de l’optimisation des données on prendra surement un DATETIME complet ! ^^).


---------------
D3
n°2349498
skeye
Posté le 25-03-2020 à 16:16:39  profilanswer
 

Je préfère la v2 d'assez loin, perso, surtout si tu veux éventuellement pouvoir conserver un historique complet des demandes/acceptations/refus/changements d'avis (auquel cas il faut ajouter un id spécifique à cette table et autoriser les (id1, id2) non uniques).


---------------
Can't buy what I want because it's free -
n°2349509
mechkurt
Posté le 25-03-2020 à 17:10:10  profilanswer
 

C'est une option auquel j'ai pensé, mais j'ai peur de me retrouver avec user * user * 1.5 lignes (stats au doigt mouillé) et donc une table qui a elle seul me fait ramer le serveur entier...
 
...bon quand on en sera la on aura surement une forme de cache mais quand même, pas convaincus par le rapport utilité / cout machine.
 
Je notes néanmoins ton intérêt pour la 2 !


---------------
D3
n°2349510
skeye
Posté le 25-03-2020 à 17:12:53  profilanswer
 

mechkurt a écrit :

C'est une option auquel j'ai pensé, mais j'ai peur de me retrouver avec user * user * 1.5 lignes (stats au doigt mouillé) et donc une table qui a elle seul me fait ramer le serveur entier...
 
...bon quand on en sera la on aura surement une forme de cache mais quand même, pas convaincus par le rapport utilité / cout machine.
 
Je notes néanmoins ton intérêt pour la 2 !


 
C'est quoi le volume en users envisagé?


---------------
Can't buy what I want because it's free -
mood
Publicité
Posté le 25-03-2020 à 17:12:53  profilanswer
 

n°2349513
mechkurt
Posté le 25-03-2020 à 17:20:15  profilanswer
 

Si on en croit mon client, Facebook...
 
..moi j'en sais rien mais j'aimerais bien pouvoir me dire que la V1 va tenir avec 100 000 comptes actif et une centaine simultané...
 
Sachant que rapidement faudra mettre en cache toutes les requêtes possible (contenu, menu, user ayant une session active, etc.), et que c'est typiquement le chose qui n'aura pas besoin d'être "live" sauf éventuellement sur la page dédié à la gestion.


---------------
D3
n°2349514
skeye
Posté le 25-03-2020 à 17:28:27  profilanswer
 

mechkurt a écrit :

Si on en croit mon client, Facebook...

 

..moi j'en sais rien mais j'aimerais bien pouvoir me dire que la V1 va tenir avec 100 000 comptes actif et une centaine simultané...

 

Sachant que rapidement faudra mettre en cache toutes les requêtes possible (contenu, menu, user ayant une session active, etc.), et que c'est typiquement le chose qui n'aura pas besoin d'être "live" sauf éventuellement sur la page dédié à la gestion.


facebook, mais avec tous les utilisateurs amis avec tout le monde si j'en crois ton calcul? :D

 

Dans tous les cas, en phase de conception ne te focalise pas sur des problèmes de perfs supposées, commence par la version la plus "propre" possible. Il sera bien temps de s'occuper des perfs quand le truc sera suffisamment proche de la prod pour regarder ce qu'il se passe en chargeant un max de données fictives...:D


Message édité par skeye le 25-03-2020 à 17:28:44

---------------
Can't buy what I want because it's free -
n°2349516
mechkurt
Posté le 25-03-2020 à 18:00:19  profilanswer
 

Oui le user * user est un tantinet discutable avec le recul ! ^^
 
Et je suis sans doute dans l'optimisation prématuré, mais y'a tellement de truc à faire sur ce projet, si je pouvais éviter de les faire 2 fois...
 
Et pour mon problème, j'aurais dut faire un sondage en faite, pacque la je suis toujours aussi perdu, enfin y'a un début de biais pour la 2ème (Skeye Flo850 et 1/2 Rufo).


---------------
D3
n°2349527
rufo
Pas me confondre avec Lycos!
Posté le 25-03-2020 à 19:01:04  profilanswer
 

Moi, je suis pour la solution 2 du fait que les relations humaines ne sont pas symétriques. C'est mon avis définitif. Je disais simplement que la solution 1 se défendait si on était dans un cas de relation symétrique.
 
La taille de l'appli : Facebook ? :heink: Ton client, il se la raconterait pas un peu ? Quand on voit comment rament les solutions alternatives de réseaux sociaux  (genre, Diaspora qui n'est pas centralisée), ça me paraît peu crédible.
 
Au passage, t'as pris quel SGBD ? Sur du MySQL, pour ta table des relations, je t'aurais recommandé le partitionnement mais si ton client voit les choses en grand comme ça, j'aurais tendance à dire que t'es parti sur une BD NoSQL pour faciliter la montée en puissance, non ?


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Cantine Calandreta : http://sourceforge.net/projects/canteen-calandreta
n°2349576
mechkurt
Posté le 26-03-2020 à 10:20:11  profilanswer
 

rufo a écrit :

Moi, je suis pour la solution 2 du fait que les relations humaines ne sont pas symétriques. C'est mon avis définitif. Je disais simplement que la solution 1 se défendait si on était dans un cas de relation symétrique.


Ben le cas 1 gère tout aussi bien l'asymetrie, sinon je ne l'aurais même pas envisagé, j'ai un état pour chaque user dans ma ligne !
J'aurais put avoir un seul état "commun" avec toutes les combinaisons possible mais ça me semblait bien plus compliqué pour un gain perf sans doute relativement modeste...
 

rufo a écrit :

La taille de l'appli : Facebook ? :heink: Ton client, il se la raconterait pas un peu ? Quand on voit comment rament les solutions alternatives de réseaux sociaux  (genre, Diaspora qui n'est pas centralisée), ça me paraît peu crédible.


A moi aussi j'ai un peu de mal à croire au succès du projet (en tout cas à cette échelle), après on n'est pas non plus exactement en concurrence avec Facebook, plutôt une espèce de complémentarité mais je ne peux pas trop en dire...
Pour le moment on part que sur 2 langues (fr + en) donc les millions d'utilisateurs, ce ne sera pas pour tout de suite ! ^^
 

rufo a écrit :

Au passage, t'as pris quel SGBD ? Sur du MySQL, pour ta table des relations, je t'aurais recommandé le partitionnement mais si ton client voit les choses en grand comme ça, j'aurais tendance à dire que t'es parti sur une BD NoSQL pour faciliter la montée en puissance, non ?


Ah ben moi je ne sais faire que du Mysql, on fera la première montée en charge avec un serveur dédié un peu musclé, puis 2 (avec 1 dédié à la BDD), et après je penses qu'a ce niveau, ils auront les moyens d'embaucher "les gens qui savent" ! ^^


---------------
D3
n°2349642
rufo
Pas me confondre avec Lycos!
Posté le 26-03-2020 à 13:38:36  profilanswer
 

Si tu es sur MySQL, je te recommande de tuner le fichier de conf pour augmenter la taille de certaines variables de conf :o
Les gains peuvent être importants.
 
Autre argument pour a solution 2 : le OR dans une requête SQL, ça peut te flinguer les perfs. Mieux vaut privilégier les requêtes à base de AND que de OR ou IN (qui est en fait un OR). Par ailleurs, si la solution 2 permet de faire moins de traitement côté PHP, y'a pas à hésiter pour faciliter la montée en puissance. De plus, dans le cas où vous passeriez sur une BD NoSQL distribuée, les algos de big data (mapreduce par ex) seront plus adapté à la solution 2.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Cantine Calandreta : http://sourceforge.net/projects/canteen-calandreta
n°2349645
mechkurt
Posté le 26-03-2020 à 13:52:36  profilanswer
 

rufo a écrit :

Si tu es sur MySQL, je te recommande de tuner le fichier de conf pour augmenter la taille de certaines variables de conf :o
Les gains peuvent être importants.
 
Autre argument pour a solution 2 : le OR dans une requête SQL, ça peut te flinguer les perfs. Mieux vaut privilégier les requêtes à base de AND que de OR ou IN (qui est en fait un OR). Par ailleurs, si la solution 2 permet de faire moins de traitement côté PHP, y'a pas à hésiter pour faciliter la montée en puissance. De plus, dans le cas où vous passeriez sur une BD NoSQL distribuée, les algos de big data (mapreduce par ex) seront plus adapté à la solution 2.


Pour le moment et en phase de test on est sur du mutualisé, mais dès qu'on aura passer un certain nombre d'inscrits, on prendra un dédié et je ferais un peu de mysqltuner.pl ^^
 
En tout cas, tes arguments sur les JOIN moins couteux que les OR m'ont convaincu, je vais réorienter mon développement sur l’hypothèse 2...


Message édité par mechkurt le 26-03-2020 à 14:11:13

---------------
D3

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Gestion des relations => schéma de la BDD

 

Sujets relatifs
PHP Impossible de Connecter à 2 BDD PSQL[POSTGRESQL] Visualisation BDD TABLES etc
CMS spécialisé dans la gestion des utilisateurs[Ada] Ecrire un programme de gestion de valeur en ligne de commande
Recherche solution pour gestion de ma patientèle et de leurs examensStockage de mots de passe dans une BDD (en clair ?)
Appli web de gestion des stocksGestion de messages asynchrone couplé un système synchrone
BDD Navigationnelle ou en réseauLogiciel de gestion de contrôles périodiques
Plus de sujets relatifs à : Gestion des relations => schéma de la BDD


Copyright © 1997-2018 Hardware.fr SARL (Signaler un contenu illicite) / Groupe LDLC / Shop HFR