[archi mysql] splitter ou non des tables pour gagner en perf ?

splitter ou non des tables pour gagner en perf ? [archi mysql] - SQL/NoSQL - Programmation

Marsh Posté le 18-01-2011 à 12:42:16    

Bonjour, je réfléchi à l'archi bdd (mysql) d'un projet et j'aurais besoin de conseils :
 
Le projet, pour simplifier :
- Il faut stocker des "billets" (textes), auxquels sont affectés des "tags" (mots).
- Les billets et les tags sont dans des "catégories" cloisonnées, un billet ne peut pas faire partie de plusieurs catégories ni plusieurs langues.
- Les billets et les tags sont en plusieurs langues.
- Un billet et un tag appartiendront toujours à une même langue et même catégorie.
 
Requêtes  
- Les billets et les tags seront l'objet de requêtes incessantes, car des algorithmes analysent les billets, et ajoutent des tags.  Chaque fois qu'un nouveau billet est ajouté dans la bdd, il faut refaire nécessairement une analyse de tous les billets de sa même langue et sa même catégorie (ranking).  
- Il y aura plus de 1 000 000 de billets, 10 000 tags, 5 à 10 catégories, et 2 langues (4 par la suite).
 
Question : lequel des deux modèles choisir, pour des raisons d'optimisation, scalabilité, d'intégrité des données (facilité à recupérer en cas d'erreur)
 
Modèle 1 :
[billets] : id / texte  / catégorie / langue
[billet_tags_liens] : id / id_billet / id_tag
[tags] : id / nom / catégorie / langue
 
Modèle 2 :
[langue1_category1_billets] : id / texte  
[langue1_category1_billet_tags_liens] : id / id_billet / id_tag
[langue1_category1_tags] : id / nom  
[langue2_category1_billets] : id / texte  
[langue2_category1_billet_tags_liens] : id / id_billet / id_tag
[langue2_category1_tags] : id / nom  
[langue1_category2_billets] : id / texte  
[langue1_category2_billet_tags_liens] : id / id_billet / id_tag
[langue1_category2_tags] : id / nom  
[langue2_category2_billets] : id / texte  
[langue2_category2_billet_tags_liens] : id / id_billet / id_tag
[langue2_category2_tags] : id / nom  
etc...
(En gros splitter chaque table par langue et par catégorie)
 
 
Le modèle 1 est simple ... mais va t-il tenir la charge ... mysql va t-il pouvoir gérer des tables avec des millions d'entrées ?  
Le modèle 2 est complexe (il faudra créer des dizaines voir centaines de tables), mais il permet d'économiser des requetes Select sur les langues et les catégories.
 
Vos avis sont les bienvenus  :jap:


Message édité par strim le 18-01-2011 à 12:44:02
Reply

Marsh Posté le 18-01-2011 à 12:42:16   

Reply

Marsh Posté le 18-01-2011 à 13:05:58    

Si les indexes des billets et tags du modele 1 sont sur categorie et langue, tu devrais avoir les meme perfs en lecture dans les 2 modeles.
 
En ecriture tu devrais etre un peu moins rapide en Modele 1 qu'en modele 2 (vu qu'il faudra trouver ou mettre les nouveaux enregistrements dans les indexes) mais tes fonctions d'inserts sont beaucoup plus simple en Modele 1 (pas besoin de changer le nom de la table en fonction du language et de la categorie).
 
Niveau espace, le modele 2 devrai prendre le moins d'espace, vu qu'il n'a pas besoin d'indexes en plus.
 
En ce qui me concerne je choisirais le modele 1 avec de bon indexes, 1.000.000 d'enregistrements c'est pas grand chose pour une machine recente. Les perfs dependront plus de la partie applicative que de la DB (sachant qu'une mauvaise query peu mettre le plus gros server du monde a genoux).

Reply

Marsh Posté le 18-01-2011 à 14:10:59    

Merci Oliiii pour ta réponse.
 
Donc si je comprend bien, vu que l'on connait à l'avance les noms des catégories et des langues, il vaut mieux utiliser le modèle 1, avec l'utilisation d'index.
 
Par contre niveau intégrité et gestion des données, le modèle 2 serait meilleur non ? Surtout pour la détection d'erreurs (un billet ayant des tags d'une mauvaise catégorie) et les statistiques.
 
 

Reply

Marsh Posté le 19-01-2011 à 07:40:42    

Tu peux avoir le meme genre d'integrité sur le modele 1 que le modele 2 si tu ajoute des check constraints.
 
Si le nombre d'enregistrement devait devenir enorme (plusieurs milliards) le modele 2 serai plus approrié mais en general il vaut mieux privilegier la simplicité du design, c'est plus facil a maintenir, a mettre a jour et a debuger.
 
Si c'est disponible dans ton SGBD tu peux aussi regarder du coté du partitioning (aucune idée si c'est dispo ou pas dans MySQL).
 
Si tu as des doutes sur les perfs du modele 1 tu peux toujours faire un test grandeur nature avec des données generée au hazard, essaye avec plusieurs milliers de billets, puis plusieurs million et continue jusque quand les perf ne sont plus suffisante.


Message édité par Oliiii le 19-01-2011 à 07:42:45
Reply

Marsh Posté le 22-01-2011 à 12:16:18    

merci pour tes réponses, on va partir sur le modèle 1  :jap:

Reply

Marsh Posté le 22-01-2011 à 12:52:19    

+1 pour le bench grandeur nature ...
Il y a quelques mois j'avais aussi un soucis de ce genre (c'était pas la même structure de BDD, mais plusieurs patterns à choix) => J'ai écrit un script qui m'a peuplé ma BDD avec des données random cohérentes, j'ai ensuite comparé les temps d'exécution et j'ai eu ma réponse ..


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 25-01-2011 à 16:36:20    

Salut,
 
Le partitionnement est dispos depuis MySql 5.1 et ça roxx mais attention il ne faut pas changer de moteur de stockage ensuite (genre MyIsam -> InnoDb) ça peut corrompre la table en tout cas j'en ai fait les frais une fois. C'est, j’espère, plus d'actualité.
 
 
 

Reply

Marsh Posté le 26-01-2011 à 00:17:07    

_neko_ a écrit :

Salut,
 
Le partitionnement est dispos depuis MySql 5.1 et ça roxx mais attention il ne faut pas changer de moteur de stockage ensuite (genre MyIsam -> InnoDb) ça peut corrompre la table en tout cas j'en ai fait les frais une fois. C'est, j’espère, plus d'actualité.


Hello,
Perso je l'ai fait sur plusieurs bases il y a quelques semaines sur la 5.5 de InnoDB vers MyIsam, pas de problèmes constatés :)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed