CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

Redis/NoSQL

Fire_Storm
Fire_Storm
Niveau 10
05 juin 2013 à 13:16:52

Bonjour tout le monde.

J'ai postulé il y a quelques jours pour un poste de dev dans une bonne agence de ma région. Mon profil les intéresse mais pour décrocher mon entretien j'ai un test à passer, en particulier car la plupart de mes compétences peuvent convenir sauf un point: ils utilisent non pas une base de données MySQL classique mais une base de données NON relationnelle, du NoSQL il me semble. Et ça je ne connais absolument pas.

Bref le cas est assez classique (concours de photos, les utilisateurs peuvent s'inscrire et voter pour une photo, la commenter etc)

Ma question est plus sur le problème principale qu'on me pose à savoir cette base de données NON relationnelle (donc pas de MySQL, de tables etc hein c'est vraiment LA condition)

La première fois que j'ai lu j'ai pensé à une base de données du genre XML où par exemple on aurait plus de tables photos et votes mais plutôt un truc du genre:

<photos>
<photo>
<votes>
<vote></vote>
</votes>
</photo>
</photos>

Un noeud peut contenir un autre noeud, on évite donc le problème de relation.

D'après ce que j'ai compris Redis est une base de données fonctionnant sur l'ensemble clé/valeur. Là où ça coince c'est que je ne trouve pas comment on peut faire différentes entités (si on peut): bah oui un utilisateur est différent d'une photo, la photo a un profil (date, titre etc) mais l'utilisateur a aussi un profil (nom, email etc) -> c'est pas la même chose (mais on retrouve alors le principe des "tables" non ?). Donc là j'avoue un peu bloquer. Mais en faisant ça est ce que je ne rejoins pas l'idée d'une base de données relationnelle ?

Bref je continue à pencher sur la question, comme tout faut comprendre la logique (je demande pas à ce qu'on fasse le boulot à ma place, surtout pas, mais si je ne comprends pas la logique d'une BDD non relationnelle je ne saurai pas faire ce test et je risque fort de perdre mon entretien aussi et ça c'est hors de question).

Merci d'avance

vava740
vava740
Niveau 10
05 juin 2013 à 14:00:31

L'idée du XML me paraît très bien, ça ressemble à ce qu'on a sur MongoDB par exemple (la différence étant que MongoDB utilise du JSON).

Voilà un exemple qui montre une structure qu'on pourrait avoir sur MongoDB pour un blog, tu vois qu'on peut quand même avoir des relations, ici pour l'user id : http://stackoverflow.com/questions/5224811/mongodb-schema-design-for-blogs

Après je sais pas si c'est exactement ça qu'ils attendent de toi, et je suis pas un expert en NoSQL non plus, mais si j'avais eu un test du genre à passer je penses que je serais parti sur une base MongoDB.

Fire_Storm
Fire_Storm
Niveau 10
05 juin 2013 à 14:09:52

Mais là on m'impose Redis. ^^ (enfin je sais pas si Redis peut être comparé à MongoDB ou si c'est carrément autre chose, bref si tu veux là je suis un peu dans l'inconnu et je n'ai que peu de temps pour assimiler une nouvelle matière xD)

En je ne dois pas faire ça en XML hein mais d'après ce que j'ai compris on peut imbriquer les choses, ce qui me permettrait d'imbriquer les votes dans les photos (on vote pour une photo), par contre imbriquer le profil de l'utilisateur a pour moi peu de sens. Seulement voilà je ne sais pas si il y a moyen de faire une relation entre un id et un utilisateur

vava740
vava740
Niveau 10
05 juin 2013 à 15:12:39

Ah oui j'avais pas compris que tu devais impérativement utiliser Redis, je pensais que tu étais juste limité à du NoSQL... Je connais pas du tout Redis par contre, désolé :-(

Fire_Storm
Fire_Storm
Niveau 10
05 juin 2013 à 15:45:47

Arf maintenant je viens de voir un autre exemple qui m'embrouille... xD

Le type utilise ce genre de truc

SET photos:1:title "Ma premiere photo"
SET photos:1:date "2013-06-05"
(on peut aussi utiliser MSET pour mettre tout ça sur une ligne)

Par la suite on fait un INCR photos par exemple pour incrémenter l'id lors de la prochaine insertion

Moi au début je partais dans l'idée de faire comme MySQL c'est à dire créer des champs, or là d'après ce que j'en comprends le champ est en réalité le nom (comprenant l'id): y a pas de champs id, title etc bien distincts. En bref y a une clé qui se nomme "photos:1:title" (et non pas comme je le pensais avant une table photos, un champ id, un champ title -> le nom fait en fait tout) et c'est en faisant varier l'id qu'on donne l'illusion de créer une base de données mais ça n'est pas découper réellement en colonnes (y a juste en bref les colonnes clé (qui est composée de la "table" de l'id et du champ en question) et valeur)

L'imbrication n'est pas vraiment réelle mais on la simule c'est bien ça ou je me goure complètement ? xD

vava740
vava740
Niveau 10
05 juin 2013 à 16:02:02

Ah ouais c'est du clé valeur pur et dur, jveux pas dire de conneries mais ça doit être mignon pour faire des sélections conditionnelles à autre chose que l'id et des order by. :hap:

Du coup j'imagine que pour ton sujet ça doit ressembler à ça :

users:1:name "Foo"
users:1:pass "hash"
photos:1:title "Ma premiere photo"
photos:1:date "2013-06-05"
photos:1:user 1

Et pour récupérer le nom de l'utilisateur qui a hébergé la photo 1 faudrait déduire la clé comme ça :

"users:" + photos:1:user + ":name"

Fire_Storm
Fire_Storm
Niveau 10
05 juin 2013 à 16:07:31

Aucune idée c'est un exemple que j'ai vu comme ça. C'est ça en fait le soucis je n'arrive pas trouver la notation officielle xD

Ça pourrait fonctionner mais je me retrouve face à un soucis en utilisant ce genre de chose: si je veux compter par exemple le nombre de photos ben il va me prendre chaque ligne comme une même photo alors que non il peut (et il y aura) y avoir plusieurs lignes pour une même photo ("photos:1:id et photos:1:title c'est la même photo mais ça forcément il ne le comprend pas) donc le résultat est faux.

Je dois passer à coté d'un truc mais je vois pas quoi...

vava740
vava740
Niveau 10
05 juin 2013 à 16:27:50

Pour ça le premier truc qui me vient à l'idée est d'avoir une clé users:count que tu incrémentes à chaque insertion (avec INCR).

http://try.redis.io/

Ce site a l'air assez sympa justement pour apprendre à utiliser Redis (avec la commande TUTORIAL).

Au final pour insérer un utilisateur :

id = `INCR photos:count`
`SET photos:` + id + `title "Ma premiere photo"`
`SET photos:` + id + `date "2013-06-05"`

Fire_Storm
Fire_Storm
Niveau 10
05 juin 2013 à 22:08:55

Si quelqu'un a une idée vraiment dites le, je commence franchement à péter un cable, je dois passer à coté d'un truc mais je vois pas quoi. Les tutos que je trouve sur le net n'aborde pas ce problème ou ne sont absolument pas du tout clair ("on ne fait pas de jointure"... Et comment je suis censé lier ces choses ensembles si je peux pas les lier ? Là j'y pige vraiment plus rien...)

vava740
vava740
Niveau 10
05 juin 2013 à 22:30:46

Un autre tuto intéressant... http://redis.io/topics/twitter-clone

Très clairement avec Redis tu ne peux qu'utiliser les clés pour lier les choses, quitte à créer plusieurs clés pour indexer selon différents "champs", dans l'exemple tu as une clé `uid:1000:username` qui vaut "antirez" pour récupérer pseudo par l'id, et la clé `username:antirez:uid` qui vaut "1000" pour récupérer l'id d'un utilisateur par son pseudo (et se servir de l'id pour accéder aux autres "champs"). Ça ressemble à des index en SQL sauf que là tu dois gérer l'architecture de stockage à la main.

Pour compter les éléments d'une entité particulière (users, photos), tu dois bien incrémenter un compte (j'étais pas à l'ouest tout à l'heure, ils emploient exactement la même technique dans l'exemple du Twitter like).

=> INCR photos:count dans mon post précédent
=> INCR global:nextUserId dans l'exemple Redis

Pour lier les choses tu passe par les id que tu retrouves dans d'autres clés, dans l'exemple au-dessus, tu peux avoir `uid:1000:followers` (qui est une sorte de tableau à la sauce Redis) qui contient "123, 945, 628, 983", ça représente les id des différents followers, et pour avoir les infos d'un follower (945 par exemple), il te suffira de récupérer la clé `uid:945:*` (* pouvant être username, followers, ou autres "champs" que tu aurais pour chaque utilisateur). Dans ce cas la liaison se fait sur la même "table" (j'emploie du vocabulaire SQL pour faire le rapprochement), mais rien ne t'empêche de mettre les id d'une autre entité (id des photos par exemple) pour faire le lien exactement de la même façon.

Si tu veux des conseils de développeurs qui connaissent vraiment Redis tu devrais essayer de demander sur la communauté Google+ de Redis, enfin si quelqu'un sur JVC s'y connaît bien à ce sujet je te souhaites qu'il passe par ici :-)

deepblue
deepblue
Niveau 16
06 juin 2013 à 11:51:42

Désolé je n'ai pas lu les réponses.

L'un des objectifs d'une base de données relationnelle est d'éviter la réplication de data. Typiquement, si tu as des catégories de produits, alors le label d'une catégorie ne devrait ête persistée qu'à un seul endroit (tablespace.table). Dans le cas d'une base de données non relationnelle, tout est à plat. Ça veut dire une : l'objectif cité plus haut n'en est pas un dans ce contexte.

Dans ce que tu décris (en terme de problématique), je pense que la première chose à faire est de remettre clairement en cause la base de données non relationnelle. Je ne pense pas non plus intéressant d'utiliser un redis/memcached ou n'importe quel système clé/valeur dans cet exemple précis. Cependant, si tu pouvais utiliser un mongodb (par exemple) alors tu avanceras dans une voix plus correct à mon sens.

À la limite, tu peux utiliser un proxy entre tes données et ton application pour gérer le cache dans un redis/memcached : http://soapatterns.org/candidate_patterns/service_data_forward_cache

Fire_Storm
Fire_Storm
Niveau 10
06 juin 2013 à 12:33:19

C'est un exercice imposé donc j'ai pas trop le choix du SGBD. ^^

Sinon j'ai trouvé solutions possibles; une où au lieu de chercher comment intégrer un hash dans un hash (ou plutôt un hash qui contient une liste qui elle contient d'autres hash), je stocke les données sous forme de XML/JSON. Dans ce cas ça peut être donc une string mais considerée comme une seule valeur. Après ça demande de récuperer cette string et de la traiter pour enfin pouvoir manipuler les données. Ça devrait marcher mais perso je trouve que c'est rajouter une couche de trop.

L'autre solution est d'émuler une base de données relationnelle; en fait par exemple pour les commentaires j'ai un "champ" commentsID qui est une liste et qui contient tous les ID des commentaires. Ensuite c'est PHP qui va transformer ça en tableau et va donc pouvoir par la suite aller chercher le bon commentaire en fonction de l'ID récupéré; Je peux faire de même avec les utilisateurs. Et au final je me retrouve avec un tableau reprenant le tout, y a plus qu'a afficher.

Je ne sais pas si il y a d'autres solutions, la meilleure pour moi était la liste contenant des hashs (en gros je voulais reprendre le principe du XML ou d'un tableau multidimensionnel en PHP. C'est ce que j'ai au final mais en séparant les choses dans Redis) mais vu qu'une telle imbrication n'est apparemment pas vraiment possible j'avais pas trop le choix.

Sous forums
  • Aide à l'achat Mac
  • Internet
  • Macintosh
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Steam Deck
  • Hardware
La vidéo du moment