web-dev-qa-db-fra.com

Tables de fractionnement dans MySQL. Bonnes pratiques?

J'ai commencé à travailler sur un projet existant et le développeur précédent avait divisé une table en 10 tables distinctes avec des schémas identiques, mais des données différentes.

Les tables ressemblent à ceci:

[tableName_0]
[tableName_1]
[tableName_2]
[tableName_3]
[tableName_4]
[tableName_5]
[tableName_6]
[tableName_7]
[tableName_8]
[tableName_9]

La clé principale est un entier id champ. L'application utilise un algorithme de hachage (id mod 10) pour savoir quel tableau pour accéder lors de la recherche. Par exemple id = 10 résulterait de [tableName_0].

Combiné, les tableaux ont probablement 100 000 rangées et le taux de croissance est relativement faible.

Donc, ma question est de savoir s'il s'agit ou non d'une solution viable ou même si c'est une bonne pratique dans une situation. Ma théorie est de pousser pour les avoir combinées car elle facilitera les choses aussi loin que UNIONs, etc. Go. L'inconvénient principal change tout le code de l'application et s'il en vaut même la peine à long terme.

14
PinkGrapefruit

Je pense que tout le monde est trop compliquant cela. Le point clé ici est:

Combiné, les tableaux ont probablement 100 000 rangées et le taux de croissance est relativement faible.

Ceci est un morceau de gâteau pour n'importe quel RDBM. Allez avec une table, indexez-le correctement et considérez-le un problème résolu.

Vous n'avez pas besoin d'envisager de partitionnement, que ce soit "fait maison" ou autrement, jusqu'à ce que vous commenciez à gérer des volumes de données extrêmement importants - Pensez des milliards de lignes et de plus en plus.

17
Nick Chammas

Ce que le développeur précédent a fait pour vous est construit sa propre mise en œuvre de la partition par hash. MySQL soutient littéralement cette native de MySQL 5.1:

http://dev.mysql.com/doc/refman/5.1/fr/Partitioninging-hash.html

Je ne peux pas penser à une bonne raison afin de mettre en œuvre votre propre partition par hasch plutôt que de compter sur la version natale [1]. Les changements de schéma d'exécution seront un cauchemar.

Je recommande également rarement la partition par hasch (la mise en œuvre native). Je pense que ce serait utile si vous pouviez l'utiliser pour une recherche parallèle chacune des partitions à la fois (que MySQL ne fera pas). Si vous avez besoin de rechercher plusieurs partitions, le régime que vous avez décrit sera souvent beaucoup plus lent.

[1] Cependant, pour certains des autres types de partitionnement, il peut être logique de rouler votre propre partitionnement. MySQL vous oblige à faire partie de votre clé de partition de votre clé principale et de tous les index uniques.

3
Morgan Tocker

Vous pouvez utiliser des tables de fusion, mais elles sont plus désuées des versions 4.x. Compte tenu de votre application est partitionnée manuellement, soit a), vous exécutez une version vraiment ancienne ou b) le développeur d'origine n'était pas au courant des partitions de table.

En bref si vous utilisez 5.1+, vous pouvez laisser MySQL faire cette partition pour vous. Voir http://dev.mysql.com/doc/refman/5.1/fr/Partitioning.html Si vous utilisez 5.5, vous devez vérifier ces documents spécifiques car vous trouverez des différences.

Il y a beaucoup d'avantages à la partition. Cependant, cela dépend vraiment de l'ensemble de données à la main, des modèles d'accès et de la manière dont il est indexé. N'oubliez pas non plus que mes commentaires suivants sont dans le contexte de la partition de MySQL 5+, pas plus d'anciennes tables de fusion MySQL; bien qu'ils soient parfois discutés en termes de partitions.

Quelques exemples:

  • Seabreting droit (ou hachage) basé sur une clé de recherche fréquemment accessible. Si vous cherchez toujours toujours une clé primaire ou une autre clé unique, MySQL peut réduire l'espace de recherche d'un facteur de la façon dont vous avez des partitions. Remarque Toutefois, cela peut être préjudiciable si vous partitionnez par une clé, puis recherchez fréquemment une autre clé. Si vous effectuez une recherche par une clé, les données ne sont pas partitionnées par alors, il doit faire plus de recherches sur les recherches (une pour chaque partition, B/C franchement, il ne sait pas où les données sont)
  • Considérez des situations Avez-vous eu un ensemble temporel d'enregistrements qui pousse par date et vous pruneez périodiquement le mois précédent. Si vous partitionnez à la date, vous pouvez simplement déposer une partition qui est aussi rapide que la chute d'une table, peu importe la taille. Si vous deviez prunealiser une telle table par des dates, vous devez émettre une ou plusieurs requêtes de suppression lorsque chaque ligne individuelle est supprimée. MySQL ne crée pas automatiquement de nouvelles partitions une fois que vous avez atteint la date maximale que vous avez comptabilisée dans ce scénario; Vous avez besoin de scripts de maintenance supplémentaires construits sur votre part pour ajouter des partitions comme elles sont nécessaires.
  • Si vous utilisez des chèques MyISAM et des récupérations sont beaucoup plus rapides. Considérons une table de myisam 100g. Si vous vouliez récupérer une table écrasée, vous auriez besoin d'environ 100 g d'espace disque de rechange au moins. S'il était partitionné dans 10 morceaux différents de taille égale, vous n'avez besoin que de 10 g de espace (et moins de mémoire Key_sort_buffer pour une récupération rapide); mais aurait besoin de faire une itération pour chaque partition.

Donc, en résumé, l'approche générale des tables de partitionnement peut offrir de nombreux avantages. Cependant, ce n'est pas une balle magique à appliquer aveuglément sans considération pour accéder aux modèles et Comment Exactement vous partitionnez.

Je pouvais imaginer des situations où la partition souhaitée est très spécifique et conviendrait mieux pour que la logique assise dans la couche d'application. Cependant, étant donné votre module droite 10 description, cela ne semble pas comme si un tel cas.

[~ # ~] Edit [~ # ~ #]

En écrivant ma description, j'ai oublié que vous avez déclaré que votre table est de 100 000 rangées. Avec le schéma complet de votre table et la longueur moyenne de la ligne, il est difficile de dire pour certains, mais en général, cela sonne moyenne, même pour un matériel modeste. Dans le même temps, s'il ne causse pas de problèmes de la façon dont il est maintenant ou dans un avenir prévisible, alors ne passez pas de temps et ne pas introduire de risque en le modifiant.

3
atxdba

En réponse à la question:

est s'il s'agit ou non d'une solution viable?

IMHO, cela semble être des frais généraux inutiles. Vous pouvez simplement indexer et cloisonner une table unique correctement, à moins d'autres informations non révélées dans la description.

En réponse à la question:

... Si c'est une bonne pratique dans n'importe quelle situation

IMHO, le frisson vertical peut avoir un sens en fonction du contexte. Quand je vois cela, il est typiquement sous forme de log. Prétendre que nous utilisons cela pour les journaux de serveur Web et nous voulons participer par mois. Au lieu de modifier une table existante en place tous les jours, nous pourrions créer une nouvelle table tous les jours et enregistrer des rangées à cette table.

par exemple. Prétendre une table de journaux Web peut prendre le formulaire:

datetime TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
uri VARCHAR(1024),
Host VARCHAR(255),
user_agent VARCHAR(255),
etc...

Votre solution crée des tables au besoin dans la base de données Weblog:

weblogs.20120301
weblogs.20120302
weblogs.20120303

etc.

De cette façon, les données restent à la maintenance et à la recherche. L'extraction devient un processus périodique normal. Les opérations continues ne sont pas verrouillées par des opérations sur des données plus anciennes.

Dans le scénario, vous avez présenté de toute façon vous êtes enfermé dans une structure, alors pourquoi ne pas utiliser une seule table optimisée à cet effet? Le stockage basé sur l'algorithme de lignes semble être esquissé et sujet aux erreurs.

2
randomx

Si une requête cible énormes données, la division des données par des conditions de requête aurait une amélioration notable des performances. Mais cette scission, comme vous l'avez vu, apporte quelques problèmes de programmation.

La question est donc la suivante: est-ce la scission de la performance, ou de nuire à la performance?

Si vous avez une transaction qui doit verrouiller plusieurs lignes sur plusieurs tables et qu'il y a des problèmes (par exemple, de l'impasse ou du délai de transaction), vous pouvez les combiner en une seule table et réécrire le SQL pour réparer les problèmes.

Lorsque je pense que je pense que vous envisagiez de scinder la table, je considérais le compromis entre la complexité des performances et la complexité de la programmation.

Dans votre situation, la modification du code existant peut être une solution à long terme pour faciliter la maintenance de code. Je suggérerais d'essayer de méta-programmation. Par exemple, en utilisant StringTemplate pour générer de manière dynamique SQL. J'aime générer SQL du moteur méta-programmation si la modification du code existant est trop difficile.

0
Mike Lue

Lorsque vous devez stocker des fichiers dans le tableau, cette métodologie aide à exporter, à réparer et à restaurer.

J'ai des tables avec> 30 Go partitionnées dans 10 tables. Ces tables n'ont que l'ID - Blob et moi sont facilement à garder. Et j'utilise Myisam pour sauver un tampon InnoDb.

0
Marcelo Bus